mirror of
https://github.com/github/awesome-copilot.git
synced 2026-02-20 02:15:12 +00:00
feat: Add GitHub Pages website for browsing resources
- Add static website with pages for agents, prompts, instructions, skills, and collections - Implement client-side fuzzy search across all resources - Add file viewer modal with copy-to-clipboard and install-to-editor functionality - Add Tools page for MCP server and future tools - Add Samples page placeholder for copilot-sdk cookbook migration - Add metadata JSON generation script (eng/generate-website-data.mjs) - Add GitHub Actions workflow for automated Pages deployment - Update package.json with website build scripts
This commit is contained in:
73
.github/workflows/deploy-website.yml
vendored
Normal file
73
.github/workflows/deploy-website.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
# GitHub Pages deployment workflow
|
||||
# Builds the website data and deploys to GitHub Pages
|
||||
|
||||
name: Deploy Website to GitHub Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
paths:
|
||||
- 'website/**'
|
||||
- 'agents/**'
|
||||
- 'prompts/**'
|
||||
- 'instructions/**'
|
||||
- 'skills/**'
|
||||
- 'collections/**'
|
||||
- 'eng/generate-website-data.mjs'
|
||||
- '.github/workflows/deploy-website.yml'
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Build job
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Generate website data
|
||||
run: npm run website:build-data
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: './website'
|
||||
|
||||
# Deployment job
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
392
eng/generate-website-data.mjs
Normal file
392
eng/generate-website-data.mjs
Normal file
@@ -0,0 +1,392 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Generate JSON metadata files for the GitHub Pages website.
|
||||
* This script extracts metadata from agents, prompts, instructions, skills, and collections
|
||||
* and writes them to website/data/ for client-side search and display.
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { dirname } from "path";
|
||||
import {
|
||||
AGENTS_DIR,
|
||||
INSTRUCTIONS_DIR,
|
||||
PROMPTS_DIR,
|
||||
SKILLS_DIR,
|
||||
COLLECTIONS_DIR,
|
||||
ROOT_FOLDER,
|
||||
} from "./constants.mjs";
|
||||
import {
|
||||
parseFrontmatter,
|
||||
parseCollectionYaml,
|
||||
parseSkillMetadata,
|
||||
} from "./yaml-parser.mjs";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const WEBSITE_DATA_DIR = path.join(ROOT_FOLDER, "website", "data");
|
||||
|
||||
/**
|
||||
* Ensure the output directory exists
|
||||
*/
|
||||
function ensureDataDir() {
|
||||
if (!fs.existsSync(WEBSITE_DATA_DIR)) {
|
||||
fs.mkdirSync(WEBSITE_DATA_DIR, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract title from filename or frontmatter
|
||||
*/
|
||||
function extractTitle(filePath, frontmatter) {
|
||||
if (frontmatter?.title) return frontmatter.title;
|
||||
if (frontmatter?.name) {
|
||||
return frontmatter.name
|
||||
.split("-")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(" ");
|
||||
}
|
||||
// Fallback to filename
|
||||
const basename = path.basename(filePath);
|
||||
const name = basename
|
||||
.replace(/\.(agent|prompt|instructions)\.md$/, "")
|
||||
.replace(/\.md$/, "");
|
||||
return name
|
||||
.split("-")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file content (for preview/full content)
|
||||
*/
|
||||
function getFileContent(filePath) {
|
||||
try {
|
||||
return fs.readFileSync(filePath, "utf8");
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate agents metadata
|
||||
*/
|
||||
function generateAgentsData() {
|
||||
const agents = [];
|
||||
const files = fs
|
||||
.readdirSync(AGENTS_DIR)
|
||||
.filter((f) => f.endsWith(".agent.md"));
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(AGENTS_DIR, file);
|
||||
const frontmatter = parseFrontmatter(filePath);
|
||||
const relativePath = path.relative(ROOT_FOLDER, filePath).replace(/\\/g, "/");
|
||||
|
||||
agents.push({
|
||||
id: file.replace(".agent.md", ""),
|
||||
title: extractTitle(filePath, frontmatter),
|
||||
description: frontmatter?.description || "",
|
||||
model: frontmatter?.model || null,
|
||||
tools: frontmatter?.tools || [],
|
||||
mcpServers: frontmatter?.["mcp-servers"]
|
||||
? Object.keys(frontmatter["mcp-servers"])
|
||||
: [],
|
||||
path: relativePath,
|
||||
filename: file,
|
||||
});
|
||||
}
|
||||
|
||||
return agents.sort((a, b) => a.title.localeCompare(b.title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate prompts metadata
|
||||
*/
|
||||
function generatePromptsData() {
|
||||
const prompts = [];
|
||||
const files = fs
|
||||
.readdirSync(PROMPTS_DIR)
|
||||
.filter((f) => f.endsWith(".prompt.md"));
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(PROMPTS_DIR, file);
|
||||
const frontmatter = parseFrontmatter(filePath);
|
||||
const relativePath = path.relative(ROOT_FOLDER, filePath).replace(/\\/g, "/");
|
||||
|
||||
prompts.push({
|
||||
id: file.replace(".prompt.md", ""),
|
||||
title: extractTitle(filePath, frontmatter),
|
||||
description: frontmatter?.description || "",
|
||||
agent: frontmatter?.agent || null,
|
||||
model: frontmatter?.model || null,
|
||||
tools: frontmatter?.tools || [],
|
||||
path: relativePath,
|
||||
filename: file,
|
||||
});
|
||||
}
|
||||
|
||||
return prompts.sort((a, b) => a.title.localeCompare(b.title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate instructions metadata
|
||||
*/
|
||||
function generateInstructionsData() {
|
||||
const instructions = [];
|
||||
const files = fs
|
||||
.readdirSync(INSTRUCTIONS_DIR)
|
||||
.filter((f) => f.endsWith(".instructions.md"));
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(INSTRUCTIONS_DIR, file);
|
||||
const frontmatter = parseFrontmatter(filePath);
|
||||
const relativePath = path.relative(ROOT_FOLDER, filePath).replace(/\\/g, "/");
|
||||
|
||||
instructions.push({
|
||||
id: file.replace(".instructions.md", ""),
|
||||
title: extractTitle(filePath, frontmatter),
|
||||
description: frontmatter?.description || "",
|
||||
applyTo: frontmatter?.applyTo || null,
|
||||
path: relativePath,
|
||||
filename: file,
|
||||
});
|
||||
}
|
||||
|
||||
return instructions.sort((a, b) => a.title.localeCompare(b.title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate skills metadata
|
||||
*/
|
||||
function generateSkillsData() {
|
||||
const skills = [];
|
||||
|
||||
if (!fs.existsSync(SKILLS_DIR)) {
|
||||
return skills;
|
||||
}
|
||||
|
||||
const folders = fs
|
||||
.readdirSync(SKILLS_DIR)
|
||||
.filter((f) => fs.statSync(path.join(SKILLS_DIR, f)).isDirectory());
|
||||
|
||||
for (const folder of folders) {
|
||||
const skillPath = path.join(SKILLS_DIR, folder);
|
||||
const metadata = parseSkillMetadata(skillPath);
|
||||
|
||||
if (metadata) {
|
||||
const relativePath = path.relative(ROOT_FOLDER, skillPath).replace(/\\/g, "/");
|
||||
|
||||
skills.push({
|
||||
id: folder,
|
||||
name: metadata.name,
|
||||
title: metadata.name
|
||||
.split("-")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(" "),
|
||||
description: metadata.description,
|
||||
assets: metadata.assets,
|
||||
path: relativePath,
|
||||
skillFile: `${relativePath}/SKILL.md`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return skills.sort((a, b) => a.title.localeCompare(b.title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate collections metadata
|
||||
*/
|
||||
function generateCollectionsData() {
|
||||
const collections = [];
|
||||
|
||||
if (!fs.existsSync(COLLECTIONS_DIR)) {
|
||||
return collections;
|
||||
}
|
||||
|
||||
const files = fs
|
||||
.readdirSync(COLLECTIONS_DIR)
|
||||
.filter((f) => f.endsWith(".collection.yml"));
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(COLLECTIONS_DIR, file);
|
||||
const data = parseCollectionYaml(filePath);
|
||||
const relativePath = path.relative(ROOT_FOLDER, filePath).replace(/\\/g, "/");
|
||||
|
||||
if (data) {
|
||||
collections.push({
|
||||
id: file.replace(".collection.yml", ""),
|
||||
name: data.name || file.replace(".collection.yml", ""),
|
||||
description: data.description || "",
|
||||
tags: data.tags || [],
|
||||
featured: data.featured || false,
|
||||
items: (data.items || []).map((item) => ({
|
||||
path: item.path,
|
||||
kind: item.kind,
|
||||
usage: item.usage || null,
|
||||
})),
|
||||
path: relativePath,
|
||||
filename: file,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Sort with featured first, then alphabetically
|
||||
return collections.sort((a, b) => {
|
||||
if (a.featured && !b.featured) return -1;
|
||||
if (!a.featured && b.featured) return 1;
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a combined index for search
|
||||
*/
|
||||
function generateSearchIndex(agents, prompts, instructions, skills, collections) {
|
||||
const index = [];
|
||||
|
||||
for (const agent of agents) {
|
||||
index.push({
|
||||
type: "agent",
|
||||
id: agent.id,
|
||||
title: agent.title,
|
||||
description: agent.description,
|
||||
path: agent.path,
|
||||
searchText: `${agent.title} ${agent.description} ${agent.tools.join(" ")}`.toLowerCase(),
|
||||
});
|
||||
}
|
||||
|
||||
for (const prompt of prompts) {
|
||||
index.push({
|
||||
type: "prompt",
|
||||
id: prompt.id,
|
||||
title: prompt.title,
|
||||
description: prompt.description,
|
||||
path: prompt.path,
|
||||
searchText: `${prompt.title} ${prompt.description}`.toLowerCase(),
|
||||
});
|
||||
}
|
||||
|
||||
for (const instruction of instructions) {
|
||||
index.push({
|
||||
type: "instruction",
|
||||
id: instruction.id,
|
||||
title: instruction.title,
|
||||
description: instruction.description,
|
||||
path: instruction.path,
|
||||
searchText: `${instruction.title} ${instruction.description} ${instruction.applyTo || ""}`.toLowerCase(),
|
||||
});
|
||||
}
|
||||
|
||||
for (const skill of skills) {
|
||||
index.push({
|
||||
type: "skill",
|
||||
id: skill.id,
|
||||
title: skill.title,
|
||||
description: skill.description,
|
||||
path: skill.path,
|
||||
searchText: `${skill.title} ${skill.description}`.toLowerCase(),
|
||||
});
|
||||
}
|
||||
|
||||
for (const collection of collections) {
|
||||
index.push({
|
||||
type: "collection",
|
||||
id: collection.id,
|
||||
title: collection.name,
|
||||
description: collection.description,
|
||||
path: collection.path,
|
||||
tags: collection.tags,
|
||||
searchText: `${collection.name} ${collection.description} ${collection.tags.join(" ")}`.toLowerCase(),
|
||||
});
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
async function main() {
|
||||
console.log("Generating website data...\n");
|
||||
|
||||
ensureDataDir();
|
||||
|
||||
// Generate all data
|
||||
const agents = generateAgentsData();
|
||||
console.log(`✓ Generated ${agents.length} agents`);
|
||||
|
||||
const prompts = generatePromptsData();
|
||||
console.log(`✓ Generated ${prompts.length} prompts`);
|
||||
|
||||
const instructions = generateInstructionsData();
|
||||
console.log(`✓ Generated ${instructions.length} instructions`);
|
||||
|
||||
const skills = generateSkillsData();
|
||||
console.log(`✓ Generated ${skills.length} skills`);
|
||||
|
||||
const collections = generateCollectionsData();
|
||||
console.log(`✓ Generated ${collections.length} collections`);
|
||||
|
||||
const searchIndex = generateSearchIndex(agents, prompts, instructions, skills, collections);
|
||||
console.log(`✓ Generated search index with ${searchIndex.length} items`);
|
||||
|
||||
// Write JSON files
|
||||
fs.writeFileSync(
|
||||
path.join(WEBSITE_DATA_DIR, "agents.json"),
|
||||
JSON.stringify(agents, null, 2)
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(WEBSITE_DATA_DIR, "prompts.json"),
|
||||
JSON.stringify(prompts, null, 2)
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(WEBSITE_DATA_DIR, "instructions.json"),
|
||||
JSON.stringify(instructions, null, 2)
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(WEBSITE_DATA_DIR, "skills.json"),
|
||||
JSON.stringify(skills, null, 2)
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(WEBSITE_DATA_DIR, "collections.json"),
|
||||
JSON.stringify(collections, null, 2)
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(WEBSITE_DATA_DIR, "search-index.json"),
|
||||
JSON.stringify(searchIndex, null, 2)
|
||||
);
|
||||
|
||||
// Generate a manifest with counts and timestamps
|
||||
const manifest = {
|
||||
generated: new Date().toISOString(),
|
||||
counts: {
|
||||
agents: agents.length,
|
||||
prompts: prompts.length,
|
||||
instructions: instructions.length,
|
||||
skills: skills.length,
|
||||
collections: collections.length,
|
||||
total: searchIndex.length,
|
||||
},
|
||||
};
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(WEBSITE_DATA_DIR, "manifest.json"),
|
||||
JSON.stringify(manifest, null, 2)
|
||||
);
|
||||
|
||||
console.log(`\n✓ All data written to website/data/`);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error generating website data:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -14,7 +14,10 @@
|
||||
"collection:validate": "node ./eng/validate-collections.mjs",
|
||||
"collection:create": "node ./eng/create-collection.mjs",
|
||||
"skill:validate": "node ./eng/validate-skills.mjs",
|
||||
"skill:create": "node ./eng/create-skill.mjs"
|
||||
"skill:create": "node ./eng/create-skill.mjs",
|
||||
"website:build-data": "node ./eng/generate-website-data.mjs",
|
||||
"website:build": "npm run build && npm run website:build-data",
|
||||
"website:serve": "npx serve website -l 3000"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
811
website/css/styles.css
Normal file
811
website/css/styles.css
Normal file
@@ -0,0 +1,811 @@
|
||||
/* CSS Variables and Base Styles */
|
||||
:root {
|
||||
--color-bg: #0d1117;
|
||||
--color-bg-secondary: #161b22;
|
||||
--color-bg-tertiary: #21262d;
|
||||
--color-border: #30363d;
|
||||
--color-text: #c9d1d9;
|
||||
--color-text-muted: #8b949e;
|
||||
--color-text-emphasis: #f0f6fc;
|
||||
--color-link: #58a6ff;
|
||||
--color-link-hover: #79c0ff;
|
||||
--color-accent: #238636;
|
||||
--color-accent-hover: #2ea043;
|
||||
--color-danger: #f85149;
|
||||
--color-warning: #d29922;
|
||||
--color-success: #238636;
|
||||
--color-card-bg: #161b22;
|
||||
--color-card-hover: #1c2128;
|
||||
--border-radius: 6px;
|
||||
--border-radius-lg: 12px;
|
||||
--shadow: 0 1px 3px rgba(0,0,0,0.12), 0 8px 24px rgba(0,0,0,0.12);
|
||||
--shadow-lg: 0 8px 24px rgba(0,0,0,0.4);
|
||||
--transition: 0.15s ease;
|
||||
--container-width: 1200px;
|
||||
--header-height: 64px;
|
||||
}
|
||||
|
||||
/* Light mode support */
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-secondary: #f6f8fa;
|
||||
--color-bg-tertiary: #f0f3f6;
|
||||
--color-border: #d0d7de;
|
||||
--color-text: #24292f;
|
||||
--color-text-muted: #57606a;
|
||||
--color-text-emphasis: #1f2328;
|
||||
--color-link: #0969da;
|
||||
--color-link-hover: #0550ae;
|
||||
--color-card-bg: #ffffff;
|
||||
--color-card-hover: #f6f8fa;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
||||
background-color: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: var(--container-width);
|
||||
margin: 0 auto;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--color-link-hover);
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.site-header {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
height: var(--header-height);
|
||||
}
|
||||
|
||||
.header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: var(--header-height);
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
color: var(--color-text-emphasis);
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
color: var(--color-text-emphasis);
|
||||
}
|
||||
|
||||
.logo-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.main-nav a {
|
||||
color: var(--color-text);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding: 8px 0;
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: all var(--transition);
|
||||
}
|
||||
|
||||
.main-nav a:hover,
|
||||
.main-nav a.active {
|
||||
color: var(--color-text-emphasis);
|
||||
border-bottom-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.github-link {
|
||||
color: var(--color-text);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.github-link:hover {
|
||||
color: var(--color-text-emphasis);
|
||||
}
|
||||
|
||||
/* Hero Section */
|
||||
.hero {
|
||||
background: linear-gradient(180deg, var(--color-bg-secondary) 0%, var(--color-bg) 100%);
|
||||
padding: 80px 0 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-emphasis);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 20px;
|
||||
color: var(--color-text-muted);
|
||||
max-width: 600px;
|
||||
margin: 0 auto 32px;
|
||||
}
|
||||
|
||||
.hero-search {
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hero-search input {
|
||||
width: 100%;
|
||||
padding: 16px 20px;
|
||||
font-size: 16px;
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-lg);
|
||||
color: var(--color-text);
|
||||
transition: all var(--transition);
|
||||
}
|
||||
|
||||
.hero-search input:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-link);
|
||||
box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.3);
|
||||
}
|
||||
|
||||
.hero-search input::placeholder {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.hero-stats {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 40px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.stat {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-emphasis);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* Search Results Dropdown */
|
||||
.search-results {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
margin-top: 8px;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
box-shadow: var(--shadow-lg);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.search-results.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search-result-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
transition: background-color var(--transition);
|
||||
}
|
||||
|
||||
.search-result-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.search-result-item:hover {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
}
|
||||
|
||||
.search-result-type {
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
background-color: var(--color-bg-tertiary);
|
||||
color: var(--color-text-muted);
|
||||
font-weight: 500;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.search-result-title {
|
||||
font-weight: 500;
|
||||
color: var(--color-text-emphasis);
|
||||
}
|
||||
|
||||
.search-result-description {
|
||||
font-size: 13px;
|
||||
color: var(--color-text-muted);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
/* Cards Grid */
|
||||
.cards-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: var(--color-card-bg);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-lg);
|
||||
padding: 24px;
|
||||
transition: all var(--transition);
|
||||
display: block;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
background-color: var(--color-card-hover);
|
||||
border-color: var(--color-link);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
font-size: 32px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-emphasis);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.card p {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* Quick Links Section */
|
||||
.quick-links {
|
||||
padding: 60px 0;
|
||||
}
|
||||
|
||||
/* Featured Section */
|
||||
.featured {
|
||||
padding: 60px 0;
|
||||
background-color: var(--color-bg-secondary);
|
||||
}
|
||||
|
||||
.featured h2 {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-emphasis);
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Getting Started */
|
||||
.getting-started {
|
||||
padding: 80px 0;
|
||||
}
|
||||
|
||||
.getting-started h2 {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-emphasis);
|
||||
margin-bottom: 48px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.steps {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 40px;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.step {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-color: var(--color-accent);
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin: 0 auto 16px;
|
||||
}
|
||||
|
||||
.step h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-emphasis);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.step p {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.site-footer {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-top: 1px solid var(--color-border);
|
||||
padding: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.site-footer p {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.site-footer a {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.site-footer a:hover {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--color-accent);
|
||||
color: white;
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--color-accent-hover);
|
||||
border-color: var(--color-accent-hover);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
color: var(--color-text);
|
||||
border-color: var(--color-border);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: var(--color-border);
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
padding: 8px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.btn-icon:hover {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* Modal */
|
||||
.modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.modal.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-lg);
|
||||
width: 100%;
|
||||
max-width: 900px;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.modal-header h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-emphasis);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.modal-body pre {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
/* Page Layouts */
|
||||
.page-header {
|
||||
padding: 48px 0 32px;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-emphasis);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.page-header p {
|
||||
font-size: 16px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.page-content {
|
||||
padding: 32px 0 60px;
|
||||
}
|
||||
|
||||
/* Search and Filter Bar */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.search-bar input {
|
||||
flex: 1;
|
||||
min-width: 250px;
|
||||
padding: 12px 16px;
|
||||
font-size: 14px;
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.search-bar input:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-link);
|
||||
}
|
||||
|
||||
.results-count {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-muted);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* Resource List */
|
||||
.resource-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.resource-item {
|
||||
background-color: var(--color-card-bg);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 16px 20px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
transition: all var(--transition);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.resource-item:hover {
|
||||
background-color: var(--color-card-hover);
|
||||
border-color: var(--color-link);
|
||||
}
|
||||
|
||||
.resource-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.resource-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-emphasis);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.resource-description {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-muted);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.resource-meta {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.resource-tag {
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
background-color: var(--color-bg-tertiary);
|
||||
border-radius: 12px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.resource-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Collection Items */
|
||||
.collection-items {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.collection-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 0;
|
||||
font-size: 13px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.collection-item-kind {
|
||||
font-size: 11px;
|
||||
padding: 2px 6px;
|
||||
background-color: var(--color-bg-tertiary);
|
||||
border-radius: 4px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
/* Empty State */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.empty-state h3 {
|
||||
font-size: 18px;
|
||||
color: var(--color-text);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* Loading State */
|
||||
.loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 20px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* Toast Notifications */
|
||||
.toast {
|
||||
position: fixed;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
padding: 12px 20px;
|
||||
background-color: var(--color-success);
|
||||
color: white;
|
||||
border-radius: var(--border-radius);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
z-index: 1100;
|
||||
animation: slideIn 0.3s ease;
|
||||
}
|
||||
|
||||
.toast.error {
|
||||
background-color: var(--color-danger);
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.main-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.hero-stats {
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.steps {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.cards-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.resource-item {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.resource-actions {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
/* Placeholder sections */
|
||||
.placeholder-section {
|
||||
text-align: center;
|
||||
padding: 80px 20px;
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 2px dashed var(--color-border);
|
||||
border-radius: var(--border-radius-lg);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.placeholder-section h3 {
|
||||
font-size: 24px;
|
||||
color: var(--color-text-emphasis);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.placeholder-section p {
|
||||
color: var(--color-text-muted);
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Tools page specific */
|
||||
.tool-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.tool-card h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.tool-status {
|
||||
font-size: 12px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tool-status.available {
|
||||
background-color: rgba(35, 134, 54, 0.2);
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.tool-status.coming-soon {
|
||||
background-color: rgba(210, 153, 34, 0.2);
|
||||
color: var(--color-warning);
|
||||
}
|
||||
2802
website/data/agents.json
Normal file
2802
website/data/agents.json
Normal file
File diff suppressed because it is too large
Load Diff
1979
website/data/collections.json
Normal file
1979
website/data/collections.json
Normal file
File diff suppressed because it is too large
Load Diff
1314
website/data/instructions.json
Normal file
1314
website/data/instructions.json
Normal file
File diff suppressed because it is too large
Load Diff
11
website/data/manifest.json
Normal file
11
website/data/manifest.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"generated": "2026-01-28T02:42:05.621Z",
|
||||
"counts": {
|
||||
"agents": 140,
|
||||
"prompts": 134,
|
||||
"instructions": 163,
|
||||
"skills": 28,
|
||||
"collections": 39,
|
||||
"total": 504
|
||||
}
|
||||
}
|
||||
1942
website/data/prompts.json
Normal file
1942
website/data/prompts.json
Normal file
File diff suppressed because it is too large
Load Diff
4361
website/data/search-index.json
Normal file
4361
website/data/search-index.json
Normal file
File diff suppressed because it is too large
Load Diff
299
website/data/skills.json
Normal file
299
website/data/skills.json
Normal file
@@ -0,0 +1,299 @@
|
||||
[
|
||||
{
|
||||
"id": "agentic-eval",
|
||||
"name": "agentic-eval",
|
||||
"title": "Agentic Eval",
|
||||
"description": "Patterns and techniques for evaluating and improving AI agent outputs. Use this skill when:\n- Implementing self-critique and reflection loops\n- Building evaluator-optimizer pipelines for quality-critical generation\n- Creating test-driven code refinement workflows\n- Designing rubric-based or LLM-as-judge evaluation systems\n- Adding iterative improvement to agent outputs (code, reports, analysis)\n- Measuring and improving agent response quality",
|
||||
"assets": [],
|
||||
"path": "skills/agentic-eval",
|
||||
"skillFile": "skills/agentic-eval/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "appinsights-instrumentation",
|
||||
"name": "appinsights-instrumentation",
|
||||
"title": "Appinsights Instrumentation",
|
||||
"description": "Instrument a webapp to send useful telemetry data to Azure App Insights",
|
||||
"assets": [
|
||||
"LICENSE.txt",
|
||||
"examples/appinsights.bicep",
|
||||
"references/ASPNETCORE.md",
|
||||
"references/AUTO.md",
|
||||
"references/NODEJS.md",
|
||||
"references/PYTHON.md",
|
||||
"scripts/appinsights.ps1"
|
||||
],
|
||||
"path": "skills/appinsights-instrumentation",
|
||||
"skillFile": "skills/appinsights-instrumentation/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "azure-deployment-preflight",
|
||||
"name": "azure-deployment-preflight",
|
||||
"title": "Azure Deployment Preflight",
|
||||
"description": "Performs comprehensive preflight validation of Bicep deployments to Azure, including template syntax validation, what-if analysis, and permission checks. Use this skill before any deployment to Azure to preview changes, identify potential issues, and ensure the deployment will succeed. Activate when users mention deploying to Azure, validating Bicep files, checking deployment permissions, previewing infrastructure changes, running what-if, or preparing for azd provision.",
|
||||
"assets": [
|
||||
"references/ERROR-HANDLING.md",
|
||||
"references/REPORT-TEMPLATE.md",
|
||||
"references/VALIDATION-COMMANDS.md"
|
||||
],
|
||||
"path": "skills/azure-deployment-preflight",
|
||||
"skillFile": "skills/azure-deployment-preflight/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "azure-devops-cli",
|
||||
"name": "azure-devops-cli",
|
||||
"title": "Azure Devops Cli",
|
||||
"description": "Manage Azure DevOps resources via CLI including projects, repos, pipelines, builds, pull requests, work items, artifacts, and service endpoints. Use when working with Azure DevOps, az commands, devops automation, CI/CD, or when user mentions Azure DevOps CLI.",
|
||||
"assets": [],
|
||||
"path": "skills/azure-devops-cli",
|
||||
"skillFile": "skills/azure-devops-cli/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "azure-resource-visualizer",
|
||||
"name": "azure-resource-visualizer",
|
||||
"title": "Azure Resource Visualizer",
|
||||
"description": "Analyze Azure resource groups and generate detailed Mermaid architecture diagrams showing the relationships between individual resources. Use this skill when the user asks for a diagram of their Azure resources or help in understanding how the resources relate to each other.",
|
||||
"assets": [
|
||||
"LICENSE.txt",
|
||||
"assets/template-architecture.md"
|
||||
],
|
||||
"path": "skills/azure-resource-visualizer",
|
||||
"skillFile": "skills/azure-resource-visualizer/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "azure-role-selector",
|
||||
"name": "azure-role-selector",
|
||||
"title": "Azure Role Selector",
|
||||
"description": "When user is asking for guidance for which role to assign to an identity given desired permissions, this agent helps them understand the role that will meet the requirements with least privilege access and how to apply that role.",
|
||||
"assets": [
|
||||
"LICENSE.txt"
|
||||
],
|
||||
"path": "skills/azure-role-selector",
|
||||
"skillFile": "skills/azure-role-selector/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "azure-static-web-apps",
|
||||
"name": "azure-static-web-apps",
|
||||
"title": "Azure Static Web Apps",
|
||||
"description": "Helps create, configure, and deploy Azure Static Web Apps using the SWA CLI. Use when deploying static sites to Azure, setting up SWA local development, configuring staticwebapp.config.json, adding Azure Functions APIs to SWA, or setting up GitHub Actions CI/CD for Static Web Apps.",
|
||||
"assets": [],
|
||||
"path": "skills/azure-static-web-apps",
|
||||
"skillFile": "skills/azure-static-web-apps/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "chrome-devtools",
|
||||
"name": "chrome-devtools",
|
||||
"title": "Chrome Devtools",
|
||||
"description": "Expert-level browser automation, debugging, and performance analysis using Chrome DevTools MCP. Use for interacting with web pages, capturing screenshots, analyzing network traffic, and profiling performance.",
|
||||
"assets": [],
|
||||
"path": "skills/chrome-devtools",
|
||||
"skillFile": "skills/chrome-devtools/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "gh-cli",
|
||||
"name": "gh-cli",
|
||||
"title": "Gh Cli",
|
||||
"description": "GitHub CLI (gh) comprehensive reference for repositories, issues, pull requests, Actions, projects, releases, gists, codespaces, organizations, extensions, and all GitHub operations from the command line.",
|
||||
"assets": [],
|
||||
"path": "skills/gh-cli",
|
||||
"skillFile": "skills/gh-cli/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "git-commit",
|
||||
"name": "git-commit",
|
||||
"title": "Git Commit",
|
||||
"description": "Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions \"/commit\". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping",
|
||||
"assets": [],
|
||||
"path": "skills/git-commit",
|
||||
"skillFile": "skills/git-commit/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "github-issues",
|
||||
"name": "github-issues",
|
||||
"title": "Github Issues",
|
||||
"description": "Create, update, and manage GitHub issues using MCP tools. Use this skill when users want to create bug reports, feature requests, or task issues, update existing issues, add labels/assignees/milestones, or manage issue workflows. Triggers on requests like \"create an issue\", \"file a bug\", \"request a feature\", \"update issue X\", or any GitHub issue management task.",
|
||||
"assets": [
|
||||
"references/templates.md"
|
||||
],
|
||||
"path": "skills/github-issues",
|
||||
"skillFile": "skills/github-issues/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "image-manipulation-image-magick",
|
||||
"name": "image-manipulation-image-magick",
|
||||
"title": "Image Manipulation Image Magick",
|
||||
"description": "Process and manipulate images using ImageMagick. Supports resizing, format conversion, batch processing, and retrieving image metadata. Use when working with images, creating thumbnails, resizing wallpapers, or performing batch image operations.",
|
||||
"assets": [],
|
||||
"path": "skills/image-manipulation-image-magick",
|
||||
"skillFile": "skills/image-manipulation-image-magick/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "legacy-circuit-mockups",
|
||||
"name": "legacy-circuit-mockups",
|
||||
"title": "Legacy Circuit Mockups",
|
||||
"description": "Generate breadboard circuit mockups and visual diagrams using HTML5 Canvas drawing techniques. Use when asked to create circuit layouts, visualize electronic component placements, draw breadboard diagrams, mockup 6502 builds, generate retro computer schematics, or design vintage electronics projects. Supports 555 timers, W65C02S microprocessors, 28C256 EEPROMs, W65C22 VIA chips, 7400-series logic gates, LEDs, resistors, capacitors, switches, buttons, crystals, and wires.",
|
||||
"assets": [
|
||||
"references/28256-eeprom.md",
|
||||
"references/555.md",
|
||||
"references/6502.md",
|
||||
"references/6522.md",
|
||||
"references/6C62256.md",
|
||||
"references/7400-series.md",
|
||||
"references/assembly-compiler.md",
|
||||
"references/assembly-language.md",
|
||||
"references/basic-electronic-components.md",
|
||||
"references/breadboard.md",
|
||||
"references/common-breadboard-components.md",
|
||||
"references/connecting-electronic-components.md",
|
||||
"references/emulator-28256-eeprom.md",
|
||||
"references/emulator-6502.md",
|
||||
"references/emulator-6522.md",
|
||||
"references/emulator-6C62256.md",
|
||||
"references/emulator-lcd.md",
|
||||
"references/lcd.md",
|
||||
"references/minipro.md",
|
||||
"references/t48eeprom-programmer.md"
|
||||
],
|
||||
"path": "skills/legacy-circuit-mockups",
|
||||
"skillFile": "skills/legacy-circuit-mockups/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "make-skill-template",
|
||||
"name": "make-skill-template",
|
||||
"title": "Make Skill Template",
|
||||
"description": "Create new Agent Skills for GitHub Copilot from prompts or by duplicating this template. Use when asked to \"create a skill\", \"make a new skill\", \"scaffold a skill\", or when building specialized AI capabilities with bundled resources. Generates SKILL.md files with proper frontmatter, directory structure, and optional scripts/references/assets folders.",
|
||||
"assets": [],
|
||||
"path": "skills/make-skill-template",
|
||||
"skillFile": "skills/make-skill-template/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "mcp-cli",
|
||||
"name": "mcp-cli",
|
||||
"title": "Mcp Cli",
|
||||
"description": "Interface for MCP (Model Context Protocol) servers via CLI. Use when you need to interact with external tools, APIs, or data sources through MCP servers, list available MCP servers/tools, or call MCP tools from command line.",
|
||||
"assets": [],
|
||||
"path": "skills/mcp-cli",
|
||||
"skillFile": "skills/mcp-cli/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "microsoft-code-reference",
|
||||
"name": "microsoft-code-reference",
|
||||
"title": "Microsoft Code Reference",
|
||||
"description": "Look up Microsoft API references, find working code samples, and verify SDK code is correct. Use when working with Azure SDKs, .NET libraries, or Microsoft APIs—to find the right method, check parameters, get working examples, or troubleshoot errors. Catches hallucinated methods, wrong signatures, and deprecated patterns by querying official docs.",
|
||||
"assets": [],
|
||||
"path": "skills/microsoft-code-reference",
|
||||
"skillFile": "skills/microsoft-code-reference/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "microsoft-docs",
|
||||
"name": "microsoft-docs",
|
||||
"title": "Microsoft Docs",
|
||||
"description": "Query official Microsoft documentation to understand concepts, find tutorials, and learn how services work. Use for Azure, .NET, Microsoft 365, Windows, Power Platform, and all Microsoft technologies. Get accurate, current information from learn.microsoft.com and other official Microsoft websites—architecture overviews, quickstarts, configuration guides, limits, and best practices.",
|
||||
"assets": [],
|
||||
"path": "skills/microsoft-docs",
|
||||
"skillFile": "skills/microsoft-docs/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "nuget-manager",
|
||||
"name": "nuget-manager",
|
||||
"title": "Nuget Manager",
|
||||
"description": "Manage NuGet packages in .NET projects/solutions. Use this skill when adding, removing, or updating NuGet package versions. It enforces using `dotnet` CLI for package management and provides strict procedures for direct file edits only when updating versions.",
|
||||
"assets": [],
|
||||
"path": "skills/nuget-manager",
|
||||
"skillFile": "skills/nuget-manager/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "plantuml-ascii",
|
||||
"name": "plantuml-ascii",
|
||||
"title": "Plantuml Ascii",
|
||||
"description": "Generate ASCII art diagrams using PlantUML text mode. Use when user asks to create ASCII diagrams, text-based diagrams, terminal-friendly diagrams, or mentions plantuml ascii, text diagram, ascii art diagram. Supports: Converting PlantUML diagrams to ASCII art, Creating sequence diagrams, class diagrams, flowcharts in ASCII format, Generating Unicode-enhanced ASCII art with -utxt flag",
|
||||
"assets": [],
|
||||
"path": "skills/plantuml-ascii",
|
||||
"skillFile": "skills/plantuml-ascii/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "prd",
|
||||
"name": "prd",
|
||||
"title": "Prd",
|
||||
"description": "Generate high-quality Product Requirements Documents (PRDs) for software systems and AI-powered features. Includes executive summaries, user stories, technical specifications, and risk analysis.",
|
||||
"assets": [],
|
||||
"path": "skills/prd",
|
||||
"skillFile": "skills/prd/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "refactor",
|
||||
"name": "refactor",
|
||||
"title": "Refactor",
|
||||
"description": "Surgical code refactoring to improve maintainability without changing behavior. Covers extracting functions, renaming variables, breaking down god functions, improving type safety, eliminating code smells, and applying design patterns. Less drastic than repo-rebuilder; use for gradual improvements.",
|
||||
"assets": [],
|
||||
"path": "skills/refactor",
|
||||
"skillFile": "skills/refactor/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "scoutqa-test",
|
||||
"name": "scoutqa-test",
|
||||
"title": "Scoutqa Test",
|
||||
"description": "This skill should be used when the user asks to \"test this website\", \"run exploratory testing\", \"check for accessibility issues\", \"verify the login flow works\", \"find bugs on this page\", or requests automated QA testing. Triggers on web application testing scenarios including smoke tests, accessibility audits, e-commerce flows, and user flow validation using ScoutQA CLI. IMPORTANT: Use this skill proactively after implementing web application features to verify they work correctly - don't wait for the user to ask for testing.",
|
||||
"assets": [],
|
||||
"path": "skills/scoutqa-test",
|
||||
"skillFile": "skills/scoutqa-test/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "snowflake-semanticview",
|
||||
"name": "snowflake-semanticview",
|
||||
"title": "Snowflake Semanticview",
|
||||
"description": "Create, alter, and validate Snowflake semantic views using Snowflake CLI (snow). Use when asked to build or troubleshoot semantic views/semantic layer definitions with CREATE/ALTER SEMANTIC VIEW, to validate semantic-view DDL against Snowflake via CLI, or to guide Snowflake CLI installation and connection setup.",
|
||||
"assets": [],
|
||||
"path": "skills/snowflake-semanticview",
|
||||
"skillFile": "skills/snowflake-semanticview/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "vscode-ext-commands",
|
||||
"name": "vscode-ext-commands",
|
||||
"title": "Vscode Ext Commands",
|
||||
"description": "Guidelines for contributing commands in VS Code extensions. Indicates naming convention, visibility, localization and other relevant attributes, following VS Code extension development guidelines, libraries and good practices",
|
||||
"assets": [],
|
||||
"path": "skills/vscode-ext-commands",
|
||||
"skillFile": "skills/vscode-ext-commands/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "vscode-ext-localization",
|
||||
"name": "vscode-ext-localization",
|
||||
"title": "Vscode Ext Localization",
|
||||
"description": "Guidelines for proper localization of VS Code extensions, following VS Code extension development guidelines, libraries and good practices",
|
||||
"assets": [],
|
||||
"path": "skills/vscode-ext-localization",
|
||||
"skillFile": "skills/vscode-ext-localization/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "web-design-reviewer",
|
||||
"name": "web-design-reviewer",
|
||||
"title": "Web Design Reviewer",
|
||||
"description": "This skill enables visual inspection of websites running locally or remotely to identify and fix design issues. Triggers on requests like \"review website design\", \"check the UI\", \"fix the layout\", \"find design problems\". Detects issues with responsive design, accessibility, visual consistency, and layout breakage, then performs fixes at the source code level.",
|
||||
"assets": [
|
||||
"references/framework-fixes.md",
|
||||
"references/visual-checklist.md"
|
||||
],
|
||||
"path": "skills/web-design-reviewer",
|
||||
"skillFile": "skills/web-design-reviewer/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "webapp-testing",
|
||||
"name": "webapp-testing",
|
||||
"title": "Webapp Testing",
|
||||
"description": "Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.",
|
||||
"assets": [
|
||||
"test-helper.js"
|
||||
],
|
||||
"path": "skills/webapp-testing",
|
||||
"skillFile": "skills/webapp-testing/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "workiq-copilot",
|
||||
"name": "workiq-copilot",
|
||||
"title": "Workiq Copilot",
|
||||
"description": "Guides the Copilot CLI on how to use the WorkIQ CLI/MCP server to query Microsoft 365 Copilot data (emails, meetings, docs, Teams, people) for live context, summaries, and recommendations.",
|
||||
"assets": [],
|
||||
"path": "skills/workiq-copilot",
|
||||
"skillFile": "skills/workiq-copilot/SKILL.md"
|
||||
}
|
||||
]
|
||||
173
website/index.html
Normal file
173
website/index.html
Normal file
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Awesome GitHub Copilot</title>
|
||||
<meta name="description" content="Community-contributed instructions, prompts, agents, and skills for GitHub Copilot">
|
||||
<link rel="stylesheet" href="css/styles.css">
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🤖</text></svg>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href="index.html" class="logo">
|
||||
<span class="logo-icon">🤖</span>
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="pages/agents.html">Agents</a>
|
||||
<a href="pages/prompts.html">Prompts</a>
|
||||
<a href="pages/instructions.html">Instructions</a>
|
||||
<a href="pages/skills.html">Skills</a>
|
||||
<a href="pages/collections.html">Collections</a>
|
||||
<a href="pages/tools.html">Tools</a>
|
||||
<a href="pages/samples.html">Samples</a>
|
||||
</nav>
|
||||
<a href="https://github.com/github/awesome-copilot" class="github-link" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24" fill="currentColor">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!-- Hero Section -->
|
||||
<section class="hero">
|
||||
<div class="container">
|
||||
<h1>Awesome GitHub Copilot</h1>
|
||||
<p class="hero-subtitle">Community-contributed instructions, prompts, agents, and skills to enhance your GitHub Copilot experience</p>
|
||||
<div class="hero-search">
|
||||
<input type="text" id="global-search" placeholder="Search all resources..." autocomplete="off">
|
||||
<div id="search-results" class="search-results hidden"></div>
|
||||
</div>
|
||||
<div class="hero-stats" id="stats">
|
||||
<!-- Populated by JS -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Quick Links -->
|
||||
<section class="quick-links">
|
||||
<div class="container">
|
||||
<div class="cards-grid">
|
||||
<a href="pages/agents.html" class="card">
|
||||
<div class="card-icon">🤖</div>
|
||||
<h3>Agents</h3>
|
||||
<p>Custom agents for specialized Copilot experiences</p>
|
||||
</a>
|
||||
<a href="pages/prompts.html" class="card">
|
||||
<div class="card-icon">🎯</div>
|
||||
<h3>Prompts</h3>
|
||||
<p>Ready-to-use prompt templates for development tasks</p>
|
||||
</a>
|
||||
<a href="pages/instructions.html" class="card">
|
||||
<div class="card-icon">📋</div>
|
||||
<h3>Instructions</h3>
|
||||
<p>Coding standards and best practices for Copilot</p>
|
||||
</a>
|
||||
<a href="pages/skills.html" class="card">
|
||||
<div class="card-icon">⚡</div>
|
||||
<h3>Skills</h3>
|
||||
<p>Self-contained folders with instructions and resources</p>
|
||||
</a>
|
||||
<a href="pages/collections.html" class="card">
|
||||
<div class="card-icon">📦</div>
|
||||
<h3>Collections</h3>
|
||||
<p>Curated collections organized by themes</p>
|
||||
</a>
|
||||
<a href="pages/tools.html" class="card">
|
||||
<div class="card-icon">🔧</div>
|
||||
<h3>Tools</h3>
|
||||
<p>MCP servers and developer tools</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Featured Collections -->
|
||||
<section class="featured">
|
||||
<div class="container">
|
||||
<h2>Featured Collections</h2>
|
||||
<div id="featured-collections" class="cards-grid">
|
||||
<!-- Populated by JS -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Getting Started -->
|
||||
<section class="getting-started">
|
||||
<div class="container">
|
||||
<h2>Getting Started</h2>
|
||||
<div class="steps">
|
||||
<div class="step">
|
||||
<div class="step-number">1</div>
|
||||
<h3>Browse</h3>
|
||||
<p>Explore agents, prompts, instructions, and skills</p>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-number">2</div>
|
||||
<h3>Preview</h3>
|
||||
<p>Click any item to view its full content</p>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-number">3</div>
|
||||
<h3>Install</h3>
|
||||
<p>One-click install to VS Code or copy to clipboard</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- File Viewer Modal -->
|
||||
<div id="file-modal" class="modal hidden">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="modal-title">File</h3>
|
||||
<div class="modal-actions">
|
||||
<button id="copy-btn" class="btn btn-secondary" title="Copy to clipboard">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path>
|
||||
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
|
||||
</svg>
|
||||
Copy
|
||||
</button>
|
||||
<a id="install-vscode-btn" href="#" class="btn btn-primary" title="Install to VS Code">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M7.5 1.75a.75.75 0 00-1.5 0v5.69L4.78 6.22a.75.75 0 00-1.06 1.06l2.5 2.5a.75.75 0 001.06 0l2.5-2.5a.75.75 0 00-1.06-1.06L7.5 7.44V1.75z"></path>
|
||||
<path d="M1.75 13a.75.75 0 000 1.5h12.5a.75.75 0 000-1.5H1.75z"></path>
|
||||
</svg>
|
||||
Install
|
||||
</a>
|
||||
<button id="close-modal" class="btn btn-icon" title="Close">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre id="modal-content"><code></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="js/utils.js"></script>
|
||||
<script src="js/search.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
250
website/js/app.js
Normal file
250
website/js/app.js
Normal file
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* Main application logic for the Awesome Copilot website
|
||||
*/
|
||||
|
||||
// Modal state
|
||||
let currentFilePath = null;
|
||||
let currentFileContent = null;
|
||||
let currentFileType = null;
|
||||
|
||||
/**
|
||||
* Initialize the application
|
||||
*/
|
||||
async function init() {
|
||||
// Initialize global search
|
||||
await initGlobalSearch();
|
||||
|
||||
// Load stats for homepage
|
||||
await loadStats();
|
||||
|
||||
// Load featured collections for homepage
|
||||
await loadFeaturedCollections();
|
||||
|
||||
// Setup global search
|
||||
setupGlobalSearch();
|
||||
|
||||
// Setup modal
|
||||
setupModal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and display stats on homepage
|
||||
*/
|
||||
async function loadStats() {
|
||||
const statsEl = document.getElementById('stats');
|
||||
if (!statsEl) return;
|
||||
|
||||
const manifest = await fetchData('manifest.json');
|
||||
if (!manifest) return;
|
||||
|
||||
const { counts } = manifest;
|
||||
statsEl.innerHTML = `
|
||||
<div class="stat">
|
||||
<div class="stat-value">${counts.agents}</div>
|
||||
<div class="stat-label">Agents</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value">${counts.prompts}</div>
|
||||
<div class="stat-label">Prompts</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value">${counts.instructions}</div>
|
||||
<div class="stat-label">Instructions</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value">${counts.skills}</div>
|
||||
<div class="stat-label">Skills</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value">${counts.collections}</div>
|
||||
<div class="stat-label">Collections</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load featured collections for homepage
|
||||
*/
|
||||
async function loadFeaturedCollections() {
|
||||
const container = document.getElementById('featured-collections');
|
||||
if (!container) return;
|
||||
|
||||
const collections = await fetchData('collections.json');
|
||||
if (!collections) return;
|
||||
|
||||
const featured = collections.filter(c => c.featured).slice(0, 6);
|
||||
|
||||
if (featured.length === 0) {
|
||||
// Show first 6 collections if none are featured
|
||||
featured.push(...collections.slice(0, 6));
|
||||
}
|
||||
|
||||
container.innerHTML = featured.map(collection => `
|
||||
<div class="card" onclick="openCollectionModal('${collection.id}')">
|
||||
<div class="card-icon">📦</div>
|
||||
<h3>${escapeHtml(collection.name)}</h3>
|
||||
<p>${escapeHtml(truncate(collection.description, 100))}</p>
|
||||
${collection.tags?.length ? `
|
||||
<div class="resource-meta">
|
||||
${collection.tags.slice(0, 3).map(tag => `
|
||||
<span class="resource-tag">${escapeHtml(tag)}</span>
|
||||
`).join('')}
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup global search functionality
|
||||
*/
|
||||
function setupGlobalSearch() {
|
||||
const searchInput = document.getElementById('global-search');
|
||||
const searchResults = document.getElementById('search-results');
|
||||
|
||||
if (!searchInput || !searchResults) return;
|
||||
|
||||
const performSearch = debounce((query) => {
|
||||
if (!query || query.length < 2) {
|
||||
searchResults.classList.add('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
const results = globalSearch.search(query, { limit: 10 });
|
||||
|
||||
if (results.length === 0) {
|
||||
searchResults.innerHTML = `
|
||||
<div class="search-result-item">
|
||||
<span class="search-result-title">No results found</span>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
searchResults.innerHTML = results.map(item => `
|
||||
<div class="search-result-item" onclick="openFileModal('${item.path}', '${item.type}')">
|
||||
<span class="search-result-type">${item.type}</span>
|
||||
<span class="search-result-title">${globalSearch.highlight(item.title, query)}</span>
|
||||
<span class="search-result-description">${escapeHtml(truncate(item.description, 60))}</span>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
searchResults.classList.remove('hidden');
|
||||
}, 200);
|
||||
|
||||
searchInput.addEventListener('input', (e) => {
|
||||
performSearch(e.target.value);
|
||||
});
|
||||
|
||||
// Close results when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!searchInput.contains(e.target) && !searchResults.contains(e.target)) {
|
||||
searchResults.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
// Handle keyboard navigation
|
||||
searchInput.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
searchResults.classList.add('hidden');
|
||||
searchInput.blur();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup modal functionality
|
||||
*/
|
||||
function setupModal() {
|
||||
const modal = document.getElementById('file-modal');
|
||||
const closeBtn = document.getElementById('close-modal');
|
||||
const copyBtn = document.getElementById('copy-btn');
|
||||
const installBtn = document.getElementById('install-vscode-btn');
|
||||
|
||||
if (!modal) return;
|
||||
|
||||
closeBtn?.addEventListener('click', closeModal);
|
||||
|
||||
modal.addEventListener('click', (e) => {
|
||||
if (e.target === modal) closeModal();
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && !modal.classList.contains('hidden')) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
|
||||
copyBtn?.addEventListener('click', async () => {
|
||||
if (currentFileContent) {
|
||||
const success = await copyToClipboard(currentFileContent);
|
||||
showToast(success ? 'Copied to clipboard!' : 'Failed to copy', success ? 'success' : 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Open file viewer modal
|
||||
*/
|
||||
async function openFileModal(filePath, type) {
|
||||
const modal = document.getElementById('file-modal');
|
||||
const title = document.getElementById('modal-title');
|
||||
const content = document.getElementById('modal-content').querySelector('code');
|
||||
const installBtn = document.getElementById('install-vscode-btn');
|
||||
|
||||
if (!modal) return;
|
||||
|
||||
currentFilePath = filePath;
|
||||
currentFileType = type;
|
||||
|
||||
// Show modal with loading state
|
||||
title.textContent = filePath.split('/').pop();
|
||||
content.textContent = 'Loading...';
|
||||
modal.classList.remove('hidden');
|
||||
|
||||
// Setup install button
|
||||
const installUrl = getVSCodeInstallUrl(type, filePath);
|
||||
if (installUrl && installBtn) {
|
||||
installBtn.href = installUrl;
|
||||
installBtn.style.display = 'inline-flex';
|
||||
} else if (installBtn) {
|
||||
installBtn.style.display = 'none';
|
||||
}
|
||||
|
||||
// Fetch and display content
|
||||
const fileContent = await fetchFileContent(filePath);
|
||||
currentFileContent = fileContent;
|
||||
|
||||
if (fileContent) {
|
||||
content.textContent = fileContent;
|
||||
} else {
|
||||
content.textContent = 'Failed to load file content. Click the button below to view on GitHub.';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open collection modal (for homepage)
|
||||
*/
|
||||
async function openCollectionModal(collectionId) {
|
||||
const collections = await fetchData('collections.json');
|
||||
const collection = collections?.find(c => c.id === collectionId);
|
||||
|
||||
if (collection) {
|
||||
openFileModal(collection.path, 'collection');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close modal
|
||||
*/
|
||||
function closeModal() {
|
||||
const modal = document.getElementById('file-modal');
|
||||
if (modal) {
|
||||
modal.classList.add('hidden');
|
||||
}
|
||||
currentFilePath = null;
|
||||
currentFileContent = null;
|
||||
currentFileType = null;
|
||||
}
|
||||
|
||||
// Initialize when DOM is ready
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
139
website/js/search.js
Normal file
139
website/js/search.js
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Fuzzy search implementation for the Awesome Copilot website
|
||||
* Simple substring matching on title and description with scoring
|
||||
*/
|
||||
|
||||
class FuzzySearch {
|
||||
constructor(items = []) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the items to search
|
||||
*/
|
||||
setItems(items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search items with fuzzy matching
|
||||
* @param {string} query - The search query
|
||||
* @param {object} options - Search options
|
||||
* @returns {array} Matching items sorted by relevance
|
||||
*/
|
||||
search(query, options = {}) {
|
||||
const {
|
||||
fields = ['title', 'description', 'searchText'],
|
||||
limit = 50,
|
||||
minScore = 0,
|
||||
} = options;
|
||||
|
||||
if (!query || query.trim().length === 0) {
|
||||
return this.items.slice(0, limit);
|
||||
}
|
||||
|
||||
const normalizedQuery = query.toLowerCase().trim();
|
||||
const queryWords = normalizedQuery.split(/\s+/);
|
||||
const results = [];
|
||||
|
||||
for (const item of this.items) {
|
||||
const score = this.calculateScore(item, queryWords, fields);
|
||||
if (score > minScore) {
|
||||
results.push({ item, score });
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by score descending
|
||||
results.sort((a, b) => b.score - a.score);
|
||||
|
||||
return results.slice(0, limit).map(r => r.item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate match score for an item
|
||||
*/
|
||||
calculateScore(item, queryWords, fields) {
|
||||
let totalScore = 0;
|
||||
|
||||
for (const word of queryWords) {
|
||||
let wordScore = 0;
|
||||
|
||||
for (const field of fields) {
|
||||
const value = item[field];
|
||||
if (!value) continue;
|
||||
|
||||
const normalizedValue = String(value).toLowerCase();
|
||||
|
||||
// Exact match in title gets highest score
|
||||
if (field === 'title' && normalizedValue === word) {
|
||||
wordScore = Math.max(wordScore, 100);
|
||||
}
|
||||
// Title starts with word
|
||||
else if (field === 'title' && normalizedValue.startsWith(word)) {
|
||||
wordScore = Math.max(wordScore, 80);
|
||||
}
|
||||
// Title contains word
|
||||
else if (field === 'title' && normalizedValue.includes(word)) {
|
||||
wordScore = Math.max(wordScore, 60);
|
||||
}
|
||||
// Description contains word
|
||||
else if (field === 'description' && normalizedValue.includes(word)) {
|
||||
wordScore = Math.max(wordScore, 30);
|
||||
}
|
||||
// searchText (includes tags, tools, etc) contains word
|
||||
else if (field === 'searchText' && normalizedValue.includes(word)) {
|
||||
wordScore = Math.max(wordScore, 20);
|
||||
}
|
||||
}
|
||||
|
||||
totalScore += wordScore;
|
||||
}
|
||||
|
||||
// Bonus for matching all words
|
||||
const matchesAllWords = queryWords.every(word =>
|
||||
fields.some(field => {
|
||||
const value = item[field];
|
||||
return value && String(value).toLowerCase().includes(word);
|
||||
})
|
||||
);
|
||||
|
||||
if (matchesAllWords && queryWords.length > 1) {
|
||||
totalScore *= 1.5;
|
||||
}
|
||||
|
||||
return totalScore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight matching text in a string
|
||||
*/
|
||||
highlight(text, query) {
|
||||
if (!query || !text) return escapeHtml(text || '');
|
||||
|
||||
const normalizedQuery = query.toLowerCase().trim();
|
||||
const words = normalizedQuery.split(/\s+/);
|
||||
let result = escapeHtml(text);
|
||||
|
||||
for (const word of words) {
|
||||
if (word.length < 2) continue;
|
||||
const regex = new RegExp(`(${word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
|
||||
result = result.replace(regex, '<mark>$1</mark>');
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Global search instance
|
||||
const globalSearch = new FuzzySearch();
|
||||
|
||||
/**
|
||||
* Initialize global search with search index
|
||||
*/
|
||||
async function initGlobalSearch() {
|
||||
const searchIndex = await fetchData('search-index.json');
|
||||
if (searchIndex) {
|
||||
globalSearch.setItems(searchIndex);
|
||||
}
|
||||
return globalSearch;
|
||||
}
|
||||
168
website/js/utils.js
Normal file
168
website/js/utils.js
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Utility functions for the Awesome Copilot website
|
||||
*/
|
||||
|
||||
const REPO_BASE_URL = 'https://raw.githubusercontent.com/github/awesome-copilot/main';
|
||||
const REPO_GITHUB_URL = 'https://github.com/github/awesome-copilot/blob/main';
|
||||
|
||||
// VS Code install URL template
|
||||
const VSCODE_INSTALL_URLS = {
|
||||
instructions: 'https://aka.ms/awesome-copilot/install/instructions',
|
||||
prompt: 'https://aka.ms/awesome-copilot/install/prompt',
|
||||
agent: 'https://aka.ms/awesome-copilot/install/agent',
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch JSON data from the data directory
|
||||
*/
|
||||
async function fetchData(filename) {
|
||||
try {
|
||||
const basePath = window.location.pathname.includes('/pages/') ? '..' : '.';
|
||||
const response = await fetch(`${basePath}/data/${filename}`);
|
||||
if (!response.ok) throw new Error(`Failed to fetch ${filename}`);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error(`Error fetching ${filename}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch raw file content from GitHub
|
||||
*/
|
||||
async function fetchFileContent(filePath) {
|
||||
try {
|
||||
const response = await fetch(`${REPO_BASE_URL}/${filePath}`);
|
||||
if (!response.ok) throw new Error(`Failed to fetch ${filePath}`);
|
||||
return await response.text();
|
||||
} catch (error) {
|
||||
console.error(`Error fetching file content:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy text to clipboard
|
||||
*/
|
||||
async function copyToClipboard(text) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
return true;
|
||||
} catch (error) {
|
||||
// Fallback for older browsers
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
textarea.style.position = 'fixed';
|
||||
textarea.style.opacity = '0';
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
const success = document.execCommand('copy');
|
||||
document.body.removeChild(textarea);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate VS Code install URL
|
||||
*/
|
||||
function getVSCodeInstallUrl(type, filePath) {
|
||||
const baseUrl = VSCODE_INSTALL_URLS[type];
|
||||
if (!baseUrl) return null;
|
||||
return `${baseUrl}?url=${encodeURIComponent(`${REPO_BASE_URL}/${filePath}`)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get GitHub URL for a file
|
||||
*/
|
||||
function getGitHubUrl(filePath) {
|
||||
return `${REPO_GITHUB_URL}/${filePath}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a toast notification
|
||||
*/
|
||||
function showToast(message, type = 'success') {
|
||||
const existing = document.querySelector('.toast');
|
||||
if (existing) existing.remove();
|
||||
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `toast ${type}`;
|
||||
toast.textContent = message;
|
||||
document.body.appendChild(toast);
|
||||
|
||||
setTimeout(() => {
|
||||
toast.remove();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Debounce function for search input
|
||||
*/
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape HTML to prevent XSS
|
||||
*/
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate text with ellipsis
|
||||
*/
|
||||
function truncate(text, maxLength) {
|
||||
if (!text || text.length <= maxLength) return text;
|
||||
return text.slice(0, maxLength).trim() + '...';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource type from file path
|
||||
*/
|
||||
function getResourceType(filePath) {
|
||||
if (filePath.endsWith('.agent.md')) return 'agent';
|
||||
if (filePath.endsWith('.prompt.md')) return 'prompt';
|
||||
if (filePath.endsWith('.instructions.md')) return 'instruction';
|
||||
if (filePath.includes('/skills/') && filePath.endsWith('SKILL.md')) return 'skill';
|
||||
if (filePath.endsWith('.collection.yml')) return 'collection';
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a resource type for display
|
||||
*/
|
||||
function formatResourceType(type) {
|
||||
const labels = {
|
||||
agent: '🤖 Agent',
|
||||
prompt: '🎯 Prompt',
|
||||
instruction: '📋 Instruction',
|
||||
skill: '⚡ Skill',
|
||||
collection: '📦 Collection',
|
||||
};
|
||||
return labels[type] || type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get icon for resource type
|
||||
*/
|
||||
function getResourceIcon(type) {
|
||||
const icons = {
|
||||
agent: '🤖',
|
||||
prompt: '🎯',
|
||||
instruction: '📋',
|
||||
skill: '⚡',
|
||||
collection: '📦',
|
||||
};
|
||||
return icons[type] || '📄';
|
||||
}
|
||||
179
website/pages/agents.html
Normal file
179
website/pages/agents.html
Normal file
@@ -0,0 +1,179 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Agents - Awesome GitHub Copilot</title>
|
||||
<meta name="description" content="Custom agents for specialized GitHub Copilot experiences">
|
||||
<link rel="stylesheet" href="../css/styles.css">
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🤖</text></svg>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href="../index.html" class="logo">
|
||||
<span class="logo-icon">🤖</span>
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="agents.html" class="active">Agents</a>
|
||||
<a href="prompts.html">Prompts</a>
|
||||
<a href="instructions.html">Instructions</a>
|
||||
<a href="skills.html">Skills</a>
|
||||
<a href="collections.html">Collections</a>
|
||||
<a href="tools.html">Tools</a>
|
||||
<a href="samples.html">Samples</a>
|
||||
</nav>
|
||||
<a href="https://github.com/github/awesome-copilot" class="github-link" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24" fill="currentColor">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="page-header">
|
||||
<div class="container">
|
||||
<h1>🤖 Custom Agents</h1>
|
||||
<p>Specialized agents that enhance GitHub Copilot for specific technologies, workflows, and domains</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="container">
|
||||
<div class="search-bar">
|
||||
<input type="text" id="search-input" placeholder="Search agents..." autocomplete="off">
|
||||
</div>
|
||||
<div class="results-count" id="results-count"></div>
|
||||
<div class="resource-list" id="resource-list">
|
||||
<div class="loading">Loading agents...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- File Viewer Modal -->
|
||||
<div id="file-modal" class="modal hidden">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="modal-title">File</h3>
|
||||
<div class="modal-actions">
|
||||
<button id="copy-btn" class="btn btn-secondary" title="Copy to clipboard">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path>
|
||||
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
|
||||
</svg>
|
||||
Copy
|
||||
</button>
|
||||
<a id="install-vscode-btn" href="#" class="btn btn-primary" title="Install to VS Code">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M7.5 1.75a.75.75 0 00-1.5 0v5.69L4.78 6.22a.75.75 0 00-1.06 1.06l2.5 2.5a.75.75 0 001.06 0l2.5-2.5a.75.75 0 00-1.06-1.06L7.5 7.44V1.75z"></path>
|
||||
<path d="M1.75 13a.75.75 0 000 1.5h12.5a.75.75 0 000-1.5H1.75z"></path>
|
||||
</svg>
|
||||
Install
|
||||
</a>
|
||||
<button id="close-modal" class="btn btn-icon" title="Close">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre id="modal-content"><code></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/search.js"></script>
|
||||
<script src="../js/app.js"></script>
|
||||
<script>
|
||||
// Page-specific initialization
|
||||
const resourceType = 'agent';
|
||||
const dataFile = 'agents.json';
|
||||
let allItems = [];
|
||||
let search = new FuzzySearch();
|
||||
|
||||
async function initPage() {
|
||||
const list = document.getElementById('resource-list');
|
||||
const countEl = document.getElementById('results-count');
|
||||
const searchInput = document.getElementById('search-input');
|
||||
|
||||
// Load data
|
||||
const data = await fetchData(dataFile);
|
||||
if (!data) {
|
||||
list.innerHTML = '<div class="empty-state"><h3>Failed to load data</h3></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
allItems = data;
|
||||
search.setItems(allItems);
|
||||
|
||||
// Render all items
|
||||
renderItems(allItems);
|
||||
countEl.textContent = `${allItems.length} agents`;
|
||||
|
||||
// Setup search
|
||||
searchInput.addEventListener('input', debounce((e) => {
|
||||
const query = e.target.value;
|
||||
const results = query ? search.search(query) : allItems;
|
||||
renderItems(results, query);
|
||||
countEl.textContent = `${results.length} of ${allItems.length} agents`;
|
||||
}, 200));
|
||||
|
||||
// Setup modal
|
||||
setupModal();
|
||||
}
|
||||
|
||||
function renderItems(items, query = '') {
|
||||
const list = document.getElementById('resource-list');
|
||||
|
||||
if (items.length === 0) {
|
||||
list.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<h3>No agents found</h3>
|
||||
<p>Try a different search term</p>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
list.innerHTML = items.map(item => `
|
||||
<div class="resource-item" onclick="openFileModal('${item.path}', '${resourceType}')">
|
||||
<div class="resource-info">
|
||||
<div class="resource-title">${query ? search.highlight(item.title, query) : escapeHtml(item.title)}</div>
|
||||
<div class="resource-description">${escapeHtml(item.description || 'No description')}</div>
|
||||
${item.tools?.length || item.mcpServers?.length ? `
|
||||
<div class="resource-meta">
|
||||
${item.model ? `<span class="resource-tag">Model: ${escapeHtml(item.model)}</span>` : ''}
|
||||
${item.mcpServers?.slice(0, 3).map(s => `<span class="resource-tag">MCP: ${escapeHtml(s)}</span>`).join('') || ''}
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
<div class="resource-actions">
|
||||
<a href="${getVSCodeInstallUrl(resourceType, item.path)}" class="btn btn-primary" onclick="event.stopPropagation()">
|
||||
Install
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initPage);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
184
website/pages/collections.html
Normal file
184
website/pages/collections.html
Normal file
@@ -0,0 +1,184 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Collections - Awesome GitHub Copilot</title>
|
||||
<meta name="description" content="Curated collections of prompts, instructions, and agents for specific workflows">
|
||||
<link rel="stylesheet" href="../css/styles.css">
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📦</text></svg>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href="../index.html" class="logo">
|
||||
<span class="logo-icon">🤖</span>
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="agents.html">Agents</a>
|
||||
<a href="prompts.html">Prompts</a>
|
||||
<a href="instructions.html">Instructions</a>
|
||||
<a href="skills.html">Skills</a>
|
||||
<a href="collections.html" class="active">Collections</a>
|
||||
<a href="tools.html">Tools</a>
|
||||
<a href="samples.html">Samples</a>
|
||||
</nav>
|
||||
<a href="https://github.com/github/awesome-copilot" class="github-link" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24" fill="currentColor">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="page-header">
|
||||
<div class="container">
|
||||
<h1>📦 Collections</h1>
|
||||
<p>Curated collections of related prompts, instructions, and agents organized by themes and workflows</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="container">
|
||||
<div class="search-bar">
|
||||
<input type="text" id="search-input" placeholder="Search collections..." autocomplete="off">
|
||||
</div>
|
||||
<div class="results-count" id="results-count"></div>
|
||||
<div class="resource-list" id="resource-list">
|
||||
<div class="loading">Loading collections...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- File Viewer Modal -->
|
||||
<div id="file-modal" class="modal hidden">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="modal-title">File</h3>
|
||||
<div class="modal-actions">
|
||||
<button id="copy-btn" class="btn btn-secondary" title="Copy to clipboard">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path>
|
||||
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
|
||||
</svg>
|
||||
Copy
|
||||
</button>
|
||||
<a id="install-vscode-btn" href="#" class="btn btn-primary" style="display:none" title="Install to VS Code">
|
||||
Install
|
||||
</a>
|
||||
<button id="close-modal" class="btn btn-icon" title="Close">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre id="modal-content"><code></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/search.js"></script>
|
||||
<script src="../js/app.js"></script>
|
||||
<script>
|
||||
const resourceType = 'collection';
|
||||
const dataFile = 'collections.json';
|
||||
let allItems = [];
|
||||
let search = new FuzzySearch();
|
||||
|
||||
async function initPage() {
|
||||
const list = document.getElementById('resource-list');
|
||||
const countEl = document.getElementById('results-count');
|
||||
const searchInput = document.getElementById('search-input');
|
||||
|
||||
const data = await fetchData(dataFile);
|
||||
if (!data) {
|
||||
list.innerHTML = '<div class="empty-state"><h3>Failed to load data</h3></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
allItems = data;
|
||||
search.setItems(allItems.map(item => ({
|
||||
...item,
|
||||
title: item.name,
|
||||
searchText: `${item.name} ${item.description} ${item.tags?.join(' ') || ''}`.toLowerCase()
|
||||
})));
|
||||
renderItems(allItems);
|
||||
countEl.textContent = `${allItems.length} collections`;
|
||||
|
||||
searchInput.addEventListener('input', debounce((e) => {
|
||||
const query = e.target.value;
|
||||
const results = query ? search.search(query) : allItems;
|
||||
renderItems(results, query);
|
||||
countEl.textContent = `${results.length} of ${allItems.length} collections`;
|
||||
}, 200));
|
||||
|
||||
setupModal();
|
||||
}
|
||||
|
||||
function renderItems(items, query = '') {
|
||||
const list = document.getElementById('resource-list');
|
||||
|
||||
if (items.length === 0) {
|
||||
list.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<h3>No collections found</h3>
|
||||
<p>Try a different search term</p>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
list.innerHTML = items.map(item => `
|
||||
<div class="resource-item" onclick="openFileModal('${item.path}', '${resourceType}')">
|
||||
<div class="resource-info">
|
||||
<div class="resource-title">
|
||||
${item.featured ? '⭐ ' : ''}${query ? search.highlight(item.name, query) : escapeHtml(item.name)}
|
||||
</div>
|
||||
<div class="resource-description">${escapeHtml(item.description || 'No description')}</div>
|
||||
<div class="resource-meta">
|
||||
${item.tags?.map(tag => `<span class="resource-tag">${escapeHtml(tag)}</span>`).join('') || ''}
|
||||
<span class="resource-tag">${item.items?.length || 0} items</span>
|
||||
</div>
|
||||
${item.items?.length ? `
|
||||
<div class="collection-items">
|
||||
${item.items.slice(0, 5).map(ci => `
|
||||
<div class="collection-item">
|
||||
<span class="collection-item-kind">${ci.kind}</span>
|
||||
<span>${escapeHtml(ci.path.split('/').pop())}</span>
|
||||
</div>
|
||||
`).join('')}
|
||||
${item.items.length > 5 ? `<div class="collection-item" style="color: var(--color-text-muted)">... and ${item.items.length - 5} more</div>` : ''}
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
<div class="resource-actions">
|
||||
<a href="${getGitHubUrl(item.path)}" class="btn btn-secondary" target="_blank" onclick="event.stopPropagation()">
|
||||
View
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initPage);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
172
website/pages/instructions.html
Normal file
172
website/pages/instructions.html
Normal file
@@ -0,0 +1,172 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Instructions - Awesome GitHub Copilot</title>
|
||||
<meta name="description" content="Coding standards and best practices for GitHub Copilot">
|
||||
<link rel="stylesheet" href="../css/styles.css">
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📋</text></svg>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href="../index.html" class="logo">
|
||||
<span class="logo-icon">🤖</span>
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="agents.html">Agents</a>
|
||||
<a href="prompts.html">Prompts</a>
|
||||
<a href="instructions.html" class="active">Instructions</a>
|
||||
<a href="skills.html">Skills</a>
|
||||
<a href="collections.html">Collections</a>
|
||||
<a href="tools.html">Tools</a>
|
||||
<a href="samples.html">Samples</a>
|
||||
</nav>
|
||||
<a href="https://github.com/github/awesome-copilot" class="github-link" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24" fill="currentColor">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="page-header">
|
||||
<div class="container">
|
||||
<h1>📋 Custom Instructions</h1>
|
||||
<p>Team and project-specific instructions to enhance GitHub Copilot's behavior for specific technologies</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="container">
|
||||
<div class="search-bar">
|
||||
<input type="text" id="search-input" placeholder="Search instructions..." autocomplete="off">
|
||||
</div>
|
||||
<div class="results-count" id="results-count"></div>
|
||||
<div class="resource-list" id="resource-list">
|
||||
<div class="loading">Loading instructions...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- File Viewer Modal -->
|
||||
<div id="file-modal" class="modal hidden">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="modal-title">File</h3>
|
||||
<div class="modal-actions">
|
||||
<button id="copy-btn" class="btn btn-secondary" title="Copy to clipboard">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path>
|
||||
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
|
||||
</svg>
|
||||
Copy
|
||||
</button>
|
||||
<a id="install-vscode-btn" href="#" class="btn btn-primary" title="Install to VS Code">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M7.5 1.75a.75.75 0 00-1.5 0v5.69L4.78 6.22a.75.75 0 00-1.06 1.06l2.5 2.5a.75.75 0 001.06 0l2.5-2.5a.75.75 0 00-1.06-1.06L7.5 7.44V1.75z"></path>
|
||||
<path d="M1.75 13a.75.75 0 000 1.5h12.5a.75.75 0 000-1.5H1.75z"></path>
|
||||
</svg>
|
||||
Install
|
||||
</a>
|
||||
<button id="close-modal" class="btn btn-icon" title="Close">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre id="modal-content"><code></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/search.js"></script>
|
||||
<script src="../js/app.js"></script>
|
||||
<script>
|
||||
const resourceType = 'instruction';
|
||||
const dataFile = 'instructions.json';
|
||||
let allItems = [];
|
||||
let search = new FuzzySearch();
|
||||
|
||||
async function initPage() {
|
||||
const list = document.getElementById('resource-list');
|
||||
const countEl = document.getElementById('results-count');
|
||||
const searchInput = document.getElementById('search-input');
|
||||
|
||||
const data = await fetchData(dataFile);
|
||||
if (!data) {
|
||||
list.innerHTML = '<div class="empty-state"><h3>Failed to load data</h3></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
allItems = data;
|
||||
search.setItems(allItems);
|
||||
renderItems(allItems);
|
||||
countEl.textContent = `${allItems.length} instructions`;
|
||||
|
||||
searchInput.addEventListener('input', debounce((e) => {
|
||||
const query = e.target.value;
|
||||
const results = query ? search.search(query) : allItems;
|
||||
renderItems(results, query);
|
||||
countEl.textContent = `${results.length} of ${allItems.length} instructions`;
|
||||
}, 200));
|
||||
|
||||
setupModal();
|
||||
}
|
||||
|
||||
function renderItems(items, query = '') {
|
||||
const list = document.getElementById('resource-list');
|
||||
|
||||
if (items.length === 0) {
|
||||
list.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<h3>No instructions found</h3>
|
||||
<p>Try a different search term</p>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
list.innerHTML = items.map(item => `
|
||||
<div class="resource-item" onclick="openFileModal('${item.path}', 'instructions')">
|
||||
<div class="resource-info">
|
||||
<div class="resource-title">${query ? search.highlight(item.title, query) : escapeHtml(item.title)}</div>
|
||||
<div class="resource-description">${escapeHtml(item.description || 'No description')}</div>
|
||||
${item.applyTo ? `
|
||||
<div class="resource-meta">
|
||||
<span class="resource-tag">Applies to: ${escapeHtml(item.applyTo)}</span>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
<div class="resource-actions">
|
||||
<a href="${getVSCodeInstallUrl('instructions', item.path)}" class="btn btn-primary" onclick="event.stopPropagation()">
|
||||
Install
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initPage);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
171
website/pages/prompts.html
Normal file
171
website/pages/prompts.html
Normal file
@@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Prompts - Awesome GitHub Copilot</title>
|
||||
<meta name="description" content="Ready-to-use prompt templates for development tasks with GitHub Copilot">
|
||||
<link rel="stylesheet" href="../css/styles.css">
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🎯</text></svg>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href="../index.html" class="logo">
|
||||
<span class="logo-icon">🤖</span>
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="agents.html">Agents</a>
|
||||
<a href="prompts.html" class="active">Prompts</a>
|
||||
<a href="instructions.html">Instructions</a>
|
||||
<a href="skills.html">Skills</a>
|
||||
<a href="collections.html">Collections</a>
|
||||
<a href="tools.html">Tools</a>
|
||||
<a href="samples.html">Samples</a>
|
||||
</nav>
|
||||
<a href="https://github.com/github/awesome-copilot" class="github-link" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24" fill="currentColor">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="page-header">
|
||||
<div class="container">
|
||||
<h1>🎯 Reusable Prompts</h1>
|
||||
<p>Ready-to-use prompt templates for specific development scenarios and tasks</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="container">
|
||||
<div class="search-bar">
|
||||
<input type="text" id="search-input" placeholder="Search prompts..." autocomplete="off">
|
||||
</div>
|
||||
<div class="results-count" id="results-count"></div>
|
||||
<div class="resource-list" id="resource-list">
|
||||
<div class="loading">Loading prompts...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- File Viewer Modal -->
|
||||
<div id="file-modal" class="modal hidden">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="modal-title">File</h3>
|
||||
<div class="modal-actions">
|
||||
<button id="copy-btn" class="btn btn-secondary" title="Copy to clipboard">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path>
|
||||
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
|
||||
</svg>
|
||||
Copy
|
||||
</button>
|
||||
<a id="install-vscode-btn" href="#" class="btn btn-primary" title="Install to VS Code">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M7.5 1.75a.75.75 0 00-1.5 0v5.69L4.78 6.22a.75.75 0 00-1.06 1.06l2.5 2.5a.75.75 0 001.06 0l2.5-2.5a.75.75 0 00-1.06-1.06L7.5 7.44V1.75z"></path>
|
||||
<path d="M1.75 13a.75.75 0 000 1.5h12.5a.75.75 0 000-1.5H1.75z"></path>
|
||||
</svg>
|
||||
Install
|
||||
</a>
|
||||
<button id="close-modal" class="btn btn-icon" title="Close">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre id="modal-content"><code></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/search.js"></script>
|
||||
<script src="../js/app.js"></script>
|
||||
<script>
|
||||
const resourceType = 'prompt';
|
||||
const dataFile = 'prompts.json';
|
||||
let allItems = [];
|
||||
let search = new FuzzySearch();
|
||||
|
||||
async function initPage() {
|
||||
const list = document.getElementById('resource-list');
|
||||
const countEl = document.getElementById('results-count');
|
||||
const searchInput = document.getElementById('search-input');
|
||||
|
||||
const data = await fetchData(dataFile);
|
||||
if (!data) {
|
||||
list.innerHTML = '<div class="empty-state"><h3>Failed to load data</h3></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
allItems = data;
|
||||
search.setItems(allItems);
|
||||
renderItems(allItems);
|
||||
countEl.textContent = `${allItems.length} prompts`;
|
||||
|
||||
searchInput.addEventListener('input', debounce((e) => {
|
||||
const query = e.target.value;
|
||||
const results = query ? search.search(query) : allItems;
|
||||
renderItems(results, query);
|
||||
countEl.textContent = `${results.length} of ${allItems.length} prompts`;
|
||||
}, 200));
|
||||
|
||||
setupModal();
|
||||
}
|
||||
|
||||
function renderItems(items, query = '') {
|
||||
const list = document.getElementById('resource-list');
|
||||
|
||||
if (items.length === 0) {
|
||||
list.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<h3>No prompts found</h3>
|
||||
<p>Try a different search term</p>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
list.innerHTML = items.map(item => `
|
||||
<div class="resource-item" onclick="openFileModal('${item.path}', '${resourceType}')">
|
||||
<div class="resource-info">
|
||||
<div class="resource-title">${query ? search.highlight(item.title, query) : escapeHtml(item.title)}</div>
|
||||
<div class="resource-description">${escapeHtml(item.description || 'No description')}</div>
|
||||
<div class="resource-meta">
|
||||
${item.model ? `<span class="resource-tag">Model: ${escapeHtml(item.model)}</span>` : ''}
|
||||
${item.agent ? `<span class="resource-tag">Agent: ${escapeHtml(item.agent)}</span>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-actions">
|
||||
<a href="${getVSCodeInstallUrl(resourceType, item.path)}" class="btn btn-primary" onclick="event.stopPropagation()">
|
||||
Install
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initPage);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
129
website/pages/samples.html
Normal file
129
website/pages/samples.html
Normal file
@@ -0,0 +1,129 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Samples - Awesome GitHub Copilot</title>
|
||||
<meta name="description" content="Code samples and examples for building with GitHub Copilot">
|
||||
<link rel="stylesheet" href="../css/styles.css">
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href="../index.html" class="logo">
|
||||
<span class="logo-icon">🤖</span>
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="agents.html">Agents</a>
|
||||
<a href="prompts.html">Prompts</a>
|
||||
<a href="instructions.html">Instructions</a>
|
||||
<a href="skills.html">Skills</a>
|
||||
<a href="collections.html">Collections</a>
|
||||
<a href="tools.html">Tools</a>
|
||||
<a href="samples.html" class="active">Samples</a>
|
||||
</nav>
|
||||
<a href="https://github.com/github/awesome-copilot" class="github-link" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24" fill="currentColor">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="page-header">
|
||||
<div class="container">
|
||||
<h1>📚 Samples</h1>
|
||||
<p>Code samples, tutorials, and examples for building with GitHub Copilot</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="container">
|
||||
<!-- Migration Notice -->
|
||||
<div class="placeholder-section" style="margin-bottom: 48px;">
|
||||
<h3>🚧 Content Migration in Progress</h3>
|
||||
<p>We're migrating the cookbook content from the <a href="https://github.com/github/copilot-sdk/tree/main/cookbook" target="_blank">Copilot SDK repository</a> to this location.</p>
|
||||
<p style="margin-top: 12px; font-size: 14px;">In the meantime, you can access the existing samples at the link below.</p>
|
||||
<div style="margin-top: 20px;">
|
||||
<a href="https://github.com/github/copilot-sdk/tree/main/cookbook" class="btn btn-primary" target="_blank">
|
||||
View Cookbook on GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Placeholder Categories -->
|
||||
<section>
|
||||
<h2 style="margin-bottom: 24px; color: var(--color-text-emphasis);">Sample Categories (Coming Soon)</h2>
|
||||
<div class="cards-grid">
|
||||
<div class="card tool-card" style="opacity: 0.6;">
|
||||
<div class="card-icon">🚀</div>
|
||||
<h3>Getting Started</h3>
|
||||
<p>Basic examples to help you get started with GitHub Copilot customization.</p>
|
||||
</div>
|
||||
|
||||
<div class="card tool-card" style="opacity: 0.6;">
|
||||
<div class="card-icon">🔌</div>
|
||||
<h3>MCP Integration</h3>
|
||||
<p>Examples of building and using MCP servers with Copilot.</p>
|
||||
</div>
|
||||
|
||||
<div class="card tool-card" style="opacity: 0.6;">
|
||||
<div class="card-icon">🤖</div>
|
||||
<h3>Custom Agents</h3>
|
||||
<p>Step-by-step tutorials for creating powerful custom agents.</p>
|
||||
</div>
|
||||
|
||||
<div class="card tool-card" style="opacity: 0.6;">
|
||||
<div class="card-icon">📝</div>
|
||||
<h3>Prompt Engineering</h3>
|
||||
<p>Best practices and examples for effective prompts.</p>
|
||||
</div>
|
||||
|
||||
<div class="card tool-card" style="opacity: 0.6;">
|
||||
<div class="card-icon">🏢</div>
|
||||
<h3>Enterprise Patterns</h3>
|
||||
<p>Patterns for deploying Copilot customizations at scale.</p>
|
||||
</div>
|
||||
|
||||
<div class="card tool-card" style="opacity: 0.6;">
|
||||
<div class="card-icon">🔧</div>
|
||||
<h3>Tooling & Automation</h3>
|
||||
<p>Scripts and tools for managing your Copilot configuration.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Contribute Section -->
|
||||
<section style="margin-top: 60px;">
|
||||
<div class="placeholder-section">
|
||||
<h3>Contribute a Sample</h3>
|
||||
<p>Have a useful example or tutorial? We'd love to include it! Samples help the community learn and adopt best practices.</p>
|
||||
<div style="margin-top: 20px;">
|
||||
<a href="https://github.com/github/awesome-copilot/blob/main/CONTRIBUTING.md" class="btn btn-primary" target="_blank">
|
||||
Contribution Guide
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="../js/utils.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
171
website/pages/skills.html
Normal file
171
website/pages/skills.html
Normal file
@@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Skills - Awesome GitHub Copilot</title>
|
||||
<meta name="description" content="Self-contained agent skills with instructions and bundled resources">
|
||||
<link rel="stylesheet" href="../css/styles.css">
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>⚡</text></svg>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href="../index.html" class="logo">
|
||||
<span class="logo-icon">🤖</span>
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="agents.html">Agents</a>
|
||||
<a href="prompts.html">Prompts</a>
|
||||
<a href="instructions.html">Instructions</a>
|
||||
<a href="skills.html" class="active">Skills</a>
|
||||
<a href="collections.html">Collections</a>
|
||||
<a href="tools.html">Tools</a>
|
||||
<a href="samples.html">Samples</a>
|
||||
</nav>
|
||||
<a href="https://github.com/github/awesome-copilot" class="github-link" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24" fill="currentColor">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="page-header">
|
||||
<div class="container">
|
||||
<h1>⚡ Agent Skills</h1>
|
||||
<p>Self-contained folders with instructions and bundled resources for specialized AI capabilities</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="container">
|
||||
<div class="search-bar">
|
||||
<input type="text" id="search-input" placeholder="Search skills..." autocomplete="off">
|
||||
</div>
|
||||
<div class="results-count" id="results-count"></div>
|
||||
<div class="resource-list" id="resource-list">
|
||||
<div class="loading">Loading skills...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- File Viewer Modal -->
|
||||
<div id="file-modal" class="modal hidden">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="modal-title">File</h3>
|
||||
<div class="modal-actions">
|
||||
<button id="copy-btn" class="btn btn-secondary" title="Copy to clipboard">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path>
|
||||
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
|
||||
</svg>
|
||||
Copy
|
||||
</button>
|
||||
<a id="install-vscode-btn" href="#" class="btn btn-primary" style="display:none" title="Install to VS Code">
|
||||
Install
|
||||
</a>
|
||||
<a id="github-btn" href="#" class="btn btn-secondary" target="_blank" title="View on GitHub">
|
||||
GitHub
|
||||
</a>
|
||||
<button id="close-modal" class="btn btn-icon" title="Close">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre id="modal-content"><code></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/search.js"></script>
|
||||
<script src="../js/app.js"></script>
|
||||
<script>
|
||||
const resourceType = 'skill';
|
||||
const dataFile = 'skills.json';
|
||||
let allItems = [];
|
||||
let search = new FuzzySearch();
|
||||
|
||||
async function initPage() {
|
||||
const list = document.getElementById('resource-list');
|
||||
const countEl = document.getElementById('results-count');
|
||||
const searchInput = document.getElementById('search-input');
|
||||
|
||||
const data = await fetchData(dataFile);
|
||||
if (!data) {
|
||||
list.innerHTML = '<div class="empty-state"><h3>Failed to load data</h3></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
allItems = data;
|
||||
search.setItems(allItems);
|
||||
renderItems(allItems);
|
||||
countEl.textContent = `${allItems.length} skills`;
|
||||
|
||||
searchInput.addEventListener('input', debounce((e) => {
|
||||
const query = e.target.value;
|
||||
const results = query ? search.search(query) : allItems;
|
||||
renderItems(results, query);
|
||||
countEl.textContent = `${results.length} of ${allItems.length} skills`;
|
||||
}, 200));
|
||||
|
||||
setupModal();
|
||||
}
|
||||
|
||||
function renderItems(items, query = '') {
|
||||
const list = document.getElementById('resource-list');
|
||||
|
||||
if (items.length === 0) {
|
||||
list.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<h3>No skills found</h3>
|
||||
<p>Try a different search term</p>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
list.innerHTML = items.map(item => `
|
||||
<div class="resource-item" onclick="openFileModal('${item.skillFile}', '${resourceType}')">
|
||||
<div class="resource-info">
|
||||
<div class="resource-title">${query ? search.highlight(item.title, query) : escapeHtml(item.title)}</div>
|
||||
<div class="resource-description">${escapeHtml(item.description || 'No description')}</div>
|
||||
${item.assets?.length ? `
|
||||
<div class="resource-meta">
|
||||
<span class="resource-tag">${item.assets.length} bundled asset${item.assets.length === 1 ? '' : 's'}</span>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
<div class="resource-actions">
|
||||
<a href="${getGitHubUrl(item.path)}" class="btn btn-secondary" target="_blank" onclick="event.stopPropagation()">
|
||||
View Folder
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initPage);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
136
website/pages/tools.html
Normal file
136
website/pages/tools.html
Normal file
@@ -0,0 +1,136 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tools - Awesome GitHub Copilot</title>
|
||||
<meta name="description" content="MCP servers and developer tools for GitHub Copilot">
|
||||
<link rel="stylesheet" href="../css/styles.css">
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🔧</text></svg>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<a href="../index.html" class="logo">
|
||||
<span class="logo-icon">🤖</span>
|
||||
<span class="logo-text">Awesome Copilot</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="agents.html">Agents</a>
|
||||
<a href="prompts.html">Prompts</a>
|
||||
<a href="instructions.html">Instructions</a>
|
||||
<a href="skills.html">Skills</a>
|
||||
<a href="collections.html">Collections</a>
|
||||
<a href="tools.html" class="active">Tools</a>
|
||||
<a href="samples.html">Samples</a>
|
||||
</nav>
|
||||
<a href="https://github.com/github/awesome-copilot" class="github-link" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24" fill="currentColor">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="page-header">
|
||||
<div class="container">
|
||||
<h1>🔧 Tools</h1>
|
||||
<p>MCP servers and developer tools to enhance your GitHub Copilot workflow</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="container">
|
||||
<!-- MCP Server Section -->
|
||||
<section style="margin-bottom: 48px;">
|
||||
<h2 style="margin-bottom: 24px; color: var(--color-text-emphasis);">MCP Server</h2>
|
||||
<div class="cards-grid">
|
||||
<div class="card tool-card">
|
||||
<h3>
|
||||
Awesome Copilot MCP Server
|
||||
<span class="tool-status available">Available</span>
|
||||
</h3>
|
||||
<p>A Model Context Protocol (MCP) Server that provides prompts for searching and installing resources directly from this repository.</p>
|
||||
<div style="margin-top: 16px;">
|
||||
<h4 style="font-size: 14px; margin-bottom: 8px; color: var(--color-text);">Features:</h4>
|
||||
<ul style="font-size: 14px; color: var(--color-text-muted); margin-left: 20px;">
|
||||
<li>Search agents, prompts, instructions, and skills</li>
|
||||
<li>Install resources directly to your editor</li>
|
||||
<li>Browse curated collections</li>
|
||||
<li>Docker-based deployment</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style="margin-top: 20px; display: flex; gap: 12px;">
|
||||
<a href="https://github.com/github/awesome-copilot#mcp-server" class="btn btn-primary" target="_blank">
|
||||
Documentation
|
||||
</a>
|
||||
<a href="https://github.com/github/awesome-copilot" class="btn btn-secondary" target="_blank">
|
||||
View on GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Coming Soon Section -->
|
||||
<section>
|
||||
<h2 style="margin-bottom: 24px; color: var(--color-text-emphasis);">Coming Soon</h2>
|
||||
<div class="cards-grid">
|
||||
<div class="card tool-card" style="opacity: 0.7;">
|
||||
<h3>
|
||||
CLI Tool
|
||||
<span class="tool-status coming-soon">Coming Soon</span>
|
||||
</h3>
|
||||
<p>Command-line interface for managing and installing Copilot resources from your terminal.</p>
|
||||
</div>
|
||||
|
||||
<div class="card tool-card" style="opacity: 0.7;">
|
||||
<h3>
|
||||
VS Code Extension
|
||||
<span class="tool-status coming-soon">Coming Soon</span>
|
||||
</h3>
|
||||
<p>Browse and install resources directly from within VS Code with a dedicated sidebar.</p>
|
||||
</div>
|
||||
|
||||
<div class="card tool-card" style="opacity: 0.7;">
|
||||
<h3>
|
||||
Resource Validator
|
||||
<span class="tool-status coming-soon">Coming Soon</span>
|
||||
</h3>
|
||||
<p>Validate your custom agents, prompts, and instructions before contributing.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Contribute Section -->
|
||||
<section style="margin-top: 60px;">
|
||||
<div class="placeholder-section">
|
||||
<h3>Have a Tool Idea?</h3>
|
||||
<p>We welcome contributions! If you have an idea for a tool that would help the community, open an issue or submit a pull request.</p>
|
||||
<div style="margin-top: 20px;">
|
||||
<a href="https://github.com/github/awesome-copilot/issues/new" class="btn btn-primary" target="_blank">
|
||||
Suggest a Tool
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="../js/utils.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user