mirror of
https://github.com/github/awesome-copilot.git
synced 2026-09-18 12:45:17 +00:00
Migrate website to Starlight with full-text resource search (#883)
* Add search functionality to Learning Hub index page Add a client-side search bar that filters articles by title, description, and tags. Sections with no matching results are hidden automatically. Uses the existing .search-bar CSS pattern from the cookbook page. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: remove deprecated layouts, theme script, and learning-hub config Phase 5 cleanup of Starlight migration: - Delete BaseLayout.astro (replaced by StarlightPage) - Delete ArticleLayout.astro (replaced by Starlight docs rendering) - Delete theme.ts (Starlight has built-in theme toggle) - Delete src/config/learning-hub.ts (sidebar order now in astro.config.mjs) - Replace learning-hub glob collection with Starlight docs collection in content.config.ts - Keep search.ts (still used by homepage and all resource page scripts) Build verified: 23 pages, no errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate website to Starlight with full-text resource search - Replace bespoke Astro layouts with Starlight integration - Homepage and resource pages use StarlightPage wrapper - Learning Hub articles rendered via Starlight docs collection - Starlight provides search, theme toggle, sidebar, ToC, a11y - Add custom Pagefind integration for resource search - All 614 agents/skills/instructions/hooks/workflows/plugins indexed as custom records with deep-link URLs - Type filter pills (horizontal pill toggles) above results - Search results link directly to resource modals via #file= hash - Move global.css to src/styles/ for Vite processing - Scope CSS reset to #main-content to avoid Starlight conflicts - Full-width page gradient via body:has(#main-content) - Light/dark theme support with Starlight gray scale inversion - Delete old layouts (BaseLayout, ArticleLayout), theme.ts, config Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback - Fix pagefind-resources.ts header comment (pagefind:true not false) - Remove unused base variable in cookbook/index.astro - Replace hardcoded /awesome-copilot/ paths with relative links in index.md - Delete stale public/styles/global.css (source of truth is src/styles/) - Replace fragile getBasePath() with Astro config base in pagefind integration - Document pagefind:true reasoning in astro.config.mjs - Use proper visually-hidden pattern + :focus-visible ring for filter pills - Remove dead header/nav/theme CSS from global.css (~160 lines) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,132 +0,0 @@
|
||||
---
|
||||
import BaseLayout from './BaseLayout.astro';
|
||||
import { getCollection } from 'astro:content';
|
||||
import { fundamentalsOrder, referenceOrder } from '../config/learning-hub';
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
estimatedReadingTime?: string;
|
||||
lastUpdated?: string;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
const { title, description, estimatedReadingTime, lastUpdated, tags } = Astro.props;
|
||||
const base = import.meta.env.BASE_URL;
|
||||
|
||||
const createOrderIndexMap = (order: string[]) => {
|
||||
const map = new Map<string, number>();
|
||||
for (let i = 0; i < order.length; i += 1) {
|
||||
map.set(order[i], i);
|
||||
}
|
||||
return map;
|
||||
};
|
||||
|
||||
const articles = await getCollection('learning-hub');
|
||||
|
||||
const fundamentalsOrderIndex = createOrderIndexMap(fundamentalsOrder);
|
||||
const referenceOrderIndex = createOrderIndexMap(referenceOrder);
|
||||
|
||||
const fundamentals = articles
|
||||
.filter((a) => fundamentalsOrderIndex.has(a.id))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(fundamentalsOrderIndex.get(a.id) ?? 0) - (fundamentalsOrderIndex.get(b.id) ?? 0),
|
||||
);
|
||||
|
||||
const reference = articles
|
||||
.filter((a) => referenceOrderIndex.has(a.id))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(referenceOrderIndex.get(a.id) ?? 0) - (referenceOrderIndex.get(b.id) ?? 0),
|
||||
);
|
||||
|
||||
const currentSlug = Astro.url.pathname.replace(/\/$/, '').split('/').pop();
|
||||
---
|
||||
|
||||
<BaseLayout title={title} description={description} activeNav="learning-hub">
|
||||
<main id="main-content">
|
||||
<div class="page-header">
|
||||
<div class="container">
|
||||
<nav class="breadcrumb" aria-label="Breadcrumb">
|
||||
<a href={`${base}learning-hub/`}>← Learning Hub</a>
|
||||
</nav>
|
||||
<h1>{title}</h1>
|
||||
{description && <p>{description}</p>}
|
||||
<div class="article-meta">
|
||||
{estimatedReadingTime && (
|
||||
<span class="meta-item">
|
||||
<span aria-hidden="true">📖</span> {estimatedReadingTime}
|
||||
</span>
|
||||
)}
|
||||
{lastUpdated && <span class="meta-item">Updated: {lastUpdated}</span>}
|
||||
</div>
|
||||
{tags && tags.length > 0 && (
|
||||
<div class="article-tags">
|
||||
{tags.map((tag) => (
|
||||
<span class="tag">{tag}</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="container">
|
||||
<div class="learning-hub-layout">
|
||||
<nav class="learning-hub-sidebar" aria-label="Learning Hub articles">
|
||||
<div class="sidebar-section">
|
||||
<h3>Fundamentals</h3>
|
||||
<ol class="sidebar-nav-list">
|
||||
{fundamentals.map((article) => (
|
||||
<li>
|
||||
<a
|
||||
href={`${base}learning-hub/${article.id}/`}
|
||||
class={currentSlug === article.id ? 'active' : ''}
|
||||
aria-current={currentSlug === article.id ? 'page' : undefined}
|
||||
>
|
||||
{article.data.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
<div class="sidebar-section">
|
||||
<h3>Reference</h3>
|
||||
<ul class="sidebar-nav-list">
|
||||
{reference.map((article) => (
|
||||
<li>
|
||||
<a
|
||||
href={`${base}learning-hub/${article.id}/`}
|
||||
class={currentSlug === article.id ? 'active' : ''}
|
||||
aria-current={currentSlug === article.id ? 'page' : undefined}
|
||||
>
|
||||
{article.data.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sidebar-section">
|
||||
<h3>Hands-on</h3>
|
||||
<ul class="sidebar-nav-list">
|
||||
<li>
|
||||
<a
|
||||
href={`${base}learning-hub/cookbook/`}
|
||||
class={currentSlug === 'cookbook' ? 'active' : ''}
|
||||
aria-current={currentSlug === 'cookbook' ? 'page' : undefined}
|
||||
>
|
||||
Cookbook
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<article class="article-content">
|
||||
<slot />
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</BaseLayout>
|
||||
@@ -1,199 +0,0 @@
|
||||
---
|
||||
import { execSync } from "child_process";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
activeNav?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
title,
|
||||
description = "Community-driven collection of custom agents, instructions, and skills for GitHub Copilot",
|
||||
activeNav = "",
|
||||
} = Astro.props;
|
||||
const base = import.meta.env.BASE_URL;
|
||||
const canonicalUrl = new URL(Astro.url.pathname, Astro.site);
|
||||
const socialImageUrl = new URL(`${base}images/social-image.png`, Astro.site);
|
||||
|
||||
// Get git commit SHA and build date at build time
|
||||
let commitSha = "unknown";
|
||||
let buildDate = new Date().toISOString().split("T")[0];
|
||||
try {
|
||||
// Use GITHUB_SHA env var in GitHub Actions, fallback to git command locally
|
||||
const githubSha = process.env.GITHUB_SHA;
|
||||
if (githubSha) {
|
||||
commitSha = githubSha.substring(0, 7);
|
||||
} else {
|
||||
commitSha = execSync("git rev-parse --short HEAD", { encoding: "utf-8" }).trim();
|
||||
}
|
||||
} catch {
|
||||
// Fallback if git is not available
|
||||
}
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{title} | Awesome GitHub Copilot</title>
|
||||
<meta name="description" content={description} />
|
||||
<link rel="canonical" href={canonicalUrl} />
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={canonicalUrl.toString()} />
|
||||
<meta property="og:title" content={`${title} | Awesome GitHub Copilot`} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content={socialImageUrl.toString()} />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
<meta property="og:image:width" content="2400" />
|
||||
<meta property="og:image:height" content="1260" />
|
||||
<meta property="og:site_name" content="Awesome GitHub Copilot" />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={`${title} | Awesome GitHub Copilot`} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={socialImageUrl.toString()} />
|
||||
<meta name="twitter:image:alt" content={`${title} | Awesome GitHub Copilot`} />
|
||||
|
||||
<link rel="stylesheet" href={`${base}styles/global.css`} />
|
||||
<link
|
||||
rel="icon"
|
||||
href={`${base}images/Copilot_Icon_Black.svg`}
|
||||
type="image/svg+xml"
|
||||
/>
|
||||
</head>
|
||||
<body data-base-path={base}>
|
||||
<a href="#main-content" class="skip-link">Skip to main content</a>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href={base} class="logo">
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav" aria-label="Main navigation">
|
||||
<a
|
||||
href={`${base}agents/`}
|
||||
class:list={[{ active: activeNav === "agents" }]}>Agents</a
|
||||
>
|
||||
<a
|
||||
href={`${base}instructions/`}
|
||||
class:list={[{ active: activeNav === "instructions" }]}
|
||||
>Instructions</a
|
||||
>
|
||||
<a
|
||||
href={`${base}skills/`}
|
||||
class:list={[{ active: activeNav === "skills" }]}>Skills</a
|
||||
>
|
||||
<a
|
||||
href={`${base}hooks/`}
|
||||
class:list={[{ active: activeNav === "hooks" }]}>Hooks</a
|
||||
>
|
||||
<a
|
||||
href={`${base}workflows/`}
|
||||
class:list={[{ active: activeNav === "workflows" }]}>Workflows</a
|
||||
>
|
||||
<a
|
||||
href={`${base}plugins/`}
|
||||
class:list={[{ active: activeNav === "plugins" }]}
|
||||
>Plugins</a
|
||||
>
|
||||
<a
|
||||
href={`${base}tools/`}
|
||||
class:list={[{ active: activeNav === "tools" }]}>Tools</a
|
||||
>
|
||||
<a
|
||||
href={`${base}learning-hub/`}
|
||||
class:list={[{ active: activeNav === "learning-hub" }]}>Learning Hub</a
|
||||
>
|
||||
</nav>
|
||||
<div class="header-actions">
|
||||
<button
|
||||
id="theme-toggle"
|
||||
class="theme-toggle"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<svg
|
||||
class="icon-sun"
|
||||
viewBox="0 0 16 16"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.75.75 0 0 1 .75.75v1.5a.75.75 0 0 1-1.5 0V.75A.75.75 0 0 1 8 0zm0 13a.75.75 0 0 1 .75.75v1.5a.75.75 0 0 1-1.5 0v-1.5A.75.75 0 0 1 8 13zM2.343 2.343a.75.75 0 0 1 1.061 0l1.06 1.061a.75.75 0 0 1-1.06 1.06l-1.06-1.06a.75.75 0 0 1 0-1.06zm9.193 9.193a.75.75 0 0 1 1.06 0l1.061 1.06a.75.75 0 0 1-1.06 1.061l-1.061-1.06a.75.75 0 0 1 0-1.061zM0 8a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 0 1.5H.75A.75.75 0 0 1 0 8zm13 0a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 0 1.5h-1.5A.75.75 0 0 1 13 8zM2.343 13.657a.75.75 0 0 1 0-1.061l1.06-1.06a.75.75 0 0 1 1.061 1.06l-1.06 1.06a.75.75 0 0 1-1.061 0zm9.193-9.193a.75.75 0 0 1 0-1.06l1.061-1.061a.75.75 0 0 1 1.06 1.06l-1.06 1.061a.75.75 0 0 1-1.061 0z"
|
||||
></path>
|
||||
</svg>
|
||||
<svg
|
||||
class="icon-moon"
|
||||
viewBox="0 0 16 16"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M9.598 1.591a.75.75 0 0 1 .785-.175 7 7 0 1 1-8.967 8.967.75.75 0 0 1 .961-.96 5.5 5.5 0 0 0 7.046-7.046.75.75 0 0 1 .175-.786zm1.616 1.945a7 7 0 0 1-7.678 7.678 5.5 5.5 0 1 0 7.678-7.678z"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
<a
|
||||
href="https://github.com/github/awesome-copilot"
|
||||
class="github-link"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
aria-label="View on GitHub"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 16 16"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<slot />
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">
|
||||
<p>
|
||||
<a
|
||||
href="https://github.com/github/awesome-copilot"
|
||||
target="_blank"
|
||||
rel="noopener">GitHub</a
|
||||
> ·
|
||||
<a
|
||||
href="https://github.com/github/awesome-copilot/blob/main/CONTRIBUTING.md"
|
||||
target="_blank"
|
||||
rel="noopener">Contribute</a
|
||||
> ·
|
||||
<a
|
||||
href="https://github.com/github/awesome-copilot/blob/main/LICENSE"
|
||||
target="_blank"
|
||||
rel="noopener">MIT License</a
|
||||
>
|
||||
</p>
|
||||
<p class="build-info">
|
||||
Built from <a
|
||||
href={`https://github.com/github/awesome-copilot/commit/${commitSha}`}
|
||||
target="_blank"
|
||||
rel="noopener">{commitSha}</a
|
||||
> on {buildDate}
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
import "../scripts/theme";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user