diff --git a/.schemas/collection.schema.json b/.schemas/collection.schema.json
new file mode 100644
index 0000000..e4efe3a
--- /dev/null
+++ b/.schemas/collection.schema.json
@@ -0,0 +1,84 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Collection Manifest",
+ "description": "Schema for awesome-copilot collection manifest files",
+ "type": "object",
+ "required": ["id", "name", "description", "items"],
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier for the collection",
+ "pattern": "^[a-z0-9-]+$",
+ "minLength": 1,
+ "maxLength": 50
+ },
+ "name": {
+ "type": "string",
+ "description": "Display name for the collection",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "description": {
+ "type": "string",
+ "description": "Description of what this collection contains",
+ "minLength": 1,
+ "maxLength": 500
+ },
+ "tags": {
+ "type": "array",
+ "description": "Optional tags for discovery",
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z0-9-]+$",
+ "minLength": 1,
+ "maxLength": 30
+ },
+ "uniqueItems": true,
+ "maxItems": 10
+ },
+ "items": {
+ "type": "array",
+ "description": "List of items in this collection",
+ "minItems": 1,
+ "maxItems": 50,
+ "items": {
+ "type": "object",
+ "required": ["path", "kind"],
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string",
+ "description": "Relative path from repository root to the item file",
+ "pattern": "^(prompts|instructions|chatmodes)\/[^\/]+\\.(prompt|instructions|chatmode)\\.md$",
+ "minLength": 1
+ },
+ "kind": {
+ "type": "string",
+ "description": "Type of the item",
+ "enum": ["prompt", "instruction", "chat-mode"]
+ }
+ }
+ },
+ "uniqueItems": true
+ },
+ "display": {
+ "type": "object",
+ "description": "Optional display settings for the collection",
+ "additionalProperties": false,
+ "properties": {
+ "ordering": {
+ "type": "string",
+ "description": "How to order items in the collection",
+ "enum": ["manual", "alpha"],
+ "default": "alpha"
+ },
+ "show_badge": {
+ "type": "boolean",
+ "description": "Whether to show collection badge on items",
+ "default": false
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/README.collections.md b/README.collections.md
new file mode 100644
index 0000000..3426512
--- /dev/null
+++ b/README.collections.md
@@ -0,0 +1,19 @@
+# 📦 Collections
+
+Curated collections of related prompts, instructions, and chat modes organized around specific themes, workflows, or use cases.
+### How to Use Collections
+
+**Browse Collections:**
+- Explore themed collections that group related customizations
+- Each collection includes prompts, instructions, and chat modes for specific workflows
+- Collections make it easy to adopt comprehensive toolkits for particular scenarios
+
+**Install Items:**
+- Click install buttons for individual items within collections
+- Or browse to the individual files to copy content manually
+- Collections help you discover related customizations you might have missed
+
+| Name | Description | Items | Tags |
+| ---- | ----------- | ----- | ---- |
+| [C# .NET Development](collections/csharp-dotnet-development.md) | Essential prompts, instructions, and chat modes for C# and .NET development including testing, documentation, and best practices. | 7 items | csharp, dotnet, aspnet, testing |
+| [DevOps On-Call](collections/devops-oncall.md) | A focused set of prompts, instructions, and a chat mode to help triage incidents and respond quickly with DevOps tools and Azure resources. | 5 items | devops, incident-response, oncall, azure |
diff --git a/README.md b/README.md
index 0392120..37b00ca 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ This repository provides a comprehensive toolkit for enhancing GitHub Copilot wi
- **[](README.prompts.md)** - Focused, task-specific prompts for generating code, documentation, and solving specific problems
- **[](README.instructions.md)** - Comprehensive coding standards and best practices that apply to specific file patterns or entire projects
- **[](README.chatmodes.md)** - Specialized AI personas and conversation modes for different roles and contexts
+- **[](README.collections.md)** - Curated collections of related prompts, instructions, and chat modes organized around specific themes and workflows
## MCP Server
@@ -76,12 +77,13 @@ We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.
├── prompts/ # Task-specific prompts (.prompt.md)
├── instructions/ # Coding standards and best practices (.instructions.md)
├── chatmodes/ # AI personas and specialized modes (.chatmode.md)
+├── collections/ # Curated collections of related items (.collection.yml)
└── scripts/ # Utility scripts for maintenance
```
## 🌟 Getting Started
-1. **Browse the Collections**: Check out our comprehensive lists of [prompts](README.prompts.md), [instructions](README.instructions.md), and [chat modes](README.chatmodes.md).
+1. **Browse the Collections**: Check out our comprehensive lists of [collections](README.collections.md), [prompts](README.prompts.md), [instructions](README.instructions.md), and [chat modes](README.chatmodes.md).
2. **Add to your editor**: Click the "Install" button to install to VS Code, or copy the file contents for other editors.
3. **Start Using**: Copy prompts to use with `/` commands, let instructions enhance your coding experience, or activate chat modes for specialized assistance.
diff --git a/collections/csharp-dotnet-development.collection.yml b/collections/csharp-dotnet-development.collection.yml
new file mode 100644
index 0000000..49bff71
--- /dev/null
+++ b/collections/csharp-dotnet-development.collection.yml
@@ -0,0 +1,22 @@
+id: csharp-dotnet-development
+name: C# .NET Development
+description: Essential prompts, instructions, and chat modes for C# and .NET development including testing, documentation, and best practices.
+tags: [csharp, dotnet, aspnet, testing]
+items:
+ - path: prompts/csharp-async.prompt.md
+ kind: prompt
+ - path: prompts/aspnet-minimal-api-openapi.prompt.md
+ kind: prompt
+ - path: instructions/csharp.instructions.md
+ kind: instruction
+ - path: instructions/dotnet-architecture-good-practices.instructions.md
+ kind: instruction
+ - path: chatmodes/expert-dotnet-software-engineer.chatmode.md
+ kind: chat-mode
+ - path: prompts/csharp-xunit.prompt.md
+ kind: prompt
+ - path: prompts/dotnet-best-practices.prompt.md
+ kind: prompt
+display:
+ ordering: alpha
+ show_badge: false
\ No newline at end of file
diff --git a/collections/csharp-dotnet-development.md b/collections/csharp-dotnet-development.md
new file mode 100644
index 0000000..cbd3698
--- /dev/null
+++ b/collections/csharp-dotnet-development.md
@@ -0,0 +1,17 @@
+# C# .NET Development
+
+Essential prompts, instructions, and chat modes for C# and .NET development including testing, documentation, and best practices.
+
+**Tags:** csharp, dotnet, aspnet, testing
+
+## Items in this Collection
+
+| Title | Type | Description |
+| ----- | ---- | ----------- |
+| [.NET/C# Best Practices](../prompts/dotnet-best-practices.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fdotnet-best-practices.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fdotnet-best-practices.prompt.md) | Prompt | Ensure .NET/C# code meets best practices for the solution/project. |
+| [ASP.NET Minimal API with OpenAPI](../prompts/aspnet-minimal-api-openapi.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Faspnet-minimal-api-openapi.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Faspnet-minimal-api-openapi.prompt.md) | Prompt | Create ASP.NET Minimal API endpoints with proper OpenAPI documentation |
+| [C# Async Programming Best Practices](../prompts/csharp-async.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fcsharp-async.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fcsharp-async.prompt.md) | Prompt | Get best practices for C# async programming |
+| [C# Development](../instructions/csharp.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcsharp.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcsharp.instructions.md) | Instruction | Guidelines for building C# applications |
+| [DDD Systems & .NET Guidelines](../instructions/dotnet-architecture-good-practices.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fdotnet-architecture-good-practices.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fdotnet-architecture-good-practices.instructions.md) | Instruction | DDD and .NET architecture guidelines |
+| [Expert .NET software engineer mode instructions](../chatmodes/expert-dotnet-software-engineer.chatmode.md)
[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fexpert-dotnet-software-engineer.chatmode.md)
[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fexpert-dotnet-software-engineer.chatmode.md) | Chat Mode | Provide expert .NET software engineering guidance using modern software design patterns. |
+| [XUnit Best Practices](../prompts/csharp-xunit.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fcsharp-xunit.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fcsharp-xunit.prompt.md) | Prompt | Get best practices for XUnit unit testing, including data-driven tests |
diff --git a/collections/devops-oncall.collection.yml b/collections/devops-oncall.collection.yml
new file mode 100644
index 0000000..cbbc00c
--- /dev/null
+++ b/collections/devops-oncall.collection.yml
@@ -0,0 +1,18 @@
+id: devops-oncall
+name: DevOps On-Call
+description: A focused set of prompts, instructions, and a chat mode to help triage incidents and respond quickly with DevOps tools and Azure resources.
+tags: [devops, incident-response, oncall, azure]
+items:
+ - path: prompts/azure-resource-health-diagnose.prompt.md
+ kind: prompt
+ - path: instructions/devops-core-principles.instructions.md
+ kind: instruction
+ - path: instructions/containerization-docker-best-practices.instructions.md
+ kind: instruction
+ - path: chatmodes/azure-principal-architect.chatmode.md
+ kind: chat-mode
+ - path: prompts/multi-stage-dockerfile.prompt.md
+ kind: prompt
+display:
+ ordering: manual
+ show_badge: true
\ No newline at end of file
diff --git a/collections/devops-oncall.md b/collections/devops-oncall.md
new file mode 100644
index 0000000..b4513e8
--- /dev/null
+++ b/collections/devops-oncall.md
@@ -0,0 +1,18 @@
+# DevOps On-Call
+
+A focused set of prompts, instructions, and a chat mode to help triage incidents and respond quickly with DevOps tools and Azure resources.
+
+**Tags:** devops, incident-response, oncall, azure
+
+## Items in this Collection
+
+| Title | Type | Description |
+| ----- | ---- | ----------- |
+| [Azure Resource Health & Issue Diagnosis](../prompts/azure-resource-health-diagnose.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fazure-resource-health-diagnose.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fazure-resource-health-diagnose.prompt.md) | Prompt | Analyze Azure resource health, diagnose issues from logs and telemetry, and create a remediation plan for identified problems. |
+| [DevOps Core Principles](../instructions/devops-core-principles.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fdevops-core-principles.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fdevops-core-principles.instructions.md) | Instruction | Foundational instructions covering core DevOps principles, culture (CALMS), and key metrics (DORA) to guide GitHub Copilot in understanding and promoting effective software delivery. |
+| [Containerization & Docker Best Practices](../instructions/containerization-docker-best-practices.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcontainerization-docker-best-practices.instructions.md)
[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcontainerization-docker-best-practices.instructions.md) | Instruction | Comprehensive best practices for creating optimized, secure, and efficient Docker images and managing containers. Covers multi-stage builds, image layer optimization, security scanning, and runtime best practices. |
+| [Azure Principal Architect mode instructions](../chatmodes/azure-principal-architect.chatmode.md)
[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fazure-principal-architect.chatmode.md)
[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fazure-principal-architect.chatmode.md) | Chat Mode | Provide expert Azure Principal Architect guidance using Azure Well-Architected Framework principles and Microsoft best practices. |
+| [Multi Stage Dockerfile](../prompts/multi-stage-dockerfile.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fmulti-stage-dockerfile.prompt.md)
[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fmulti-stage-dockerfile.prompt.md) | Prompt | Create optimized multi-stage Dockerfiles for any language or framework |
+
+---
+*This collection includes 5 curated items for devops on-call.*
\ No newline at end of file
diff --git a/update-readme.js b/update-readme.js
index 5fb219b..ab3f152 100755
--- a/update-readme.js
+++ b/update-readme.js
@@ -49,6 +49,22 @@ Custom chat modes define specific behaviors and tools for GitHub Copilot Chat, e
- Import the chat mode configuration into your VS Code settings
- Access the installed chat modes through the VS Code Chat interface
- Select the desired chat mode from the available options in VS Code Chat`,
+
+ collectionsSection: `## 📦 Collections
+
+Curated collections of related prompts, instructions, and chat modes organized around specific themes, workflows, or use cases.`,
+
+ collectionsUsage: `### How to Use Collections
+
+**Browse Collections:**
+- Explore themed collections that group related customizations
+- Each collection includes prompts, instructions, and chat modes for specific workflows
+- Collections make it easy to adopt comprehensive toolkits for particular scenarios
+
+**Install Items:**
+- Click install buttons for individual items within collections
+- Or browse to the individual files to copy content manually
+- Collections help you discover related customizations you might have missed`,
};
// Add error handling utility
@@ -61,6 +77,110 @@ function safeFileOperation(operation, filePath, defaultValue = null) {
}
}
+/**
+ * Simple YAML parser for collection manifests
+ * Handles our specific YAML structure without external dependencies
+ */
+function parseCollectionYaml(filePath) {
+ return safeFileOperation(
+ () => {
+ const content = fs.readFileSync(filePath, "utf8");
+ const lines = content.split("\n");
+ const result = {};
+ let currentKey = null;
+ let currentArray = null;
+ let currentObject = null;
+
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i];
+ const trimmed = line.trim();
+
+ if (!trimmed || trimmed.startsWith("#")) continue;
+
+ const leadingSpaces = line.length - line.trimLeft().length;
+
+ // Handle array items starting with -
+ if (trimmed.startsWith("- ")) {
+ if (currentKey === "items") {
+ if (!currentArray) {
+ currentArray = [];
+ result[currentKey] = currentArray;
+ }
+
+ // Parse item object
+ const item = {};
+ currentArray.push(item);
+ currentObject = item;
+
+ // Handle inline properties on same line as -
+ const restOfLine = trimmed.substring(2).trim();
+ if (restOfLine) {
+ const colonIndex = restOfLine.indexOf(":");
+ if (colonIndex > -1) {
+ const key = restOfLine.substring(0, colonIndex).trim();
+ const value = restOfLine.substring(colonIndex + 1).trim();
+ item[key] = value;
+ }
+ }
+ } else if (currentKey === "tags") {
+ if (!currentArray) {
+ currentArray = [];
+ result[currentKey] = currentArray;
+ }
+ const value = trimmed.substring(2).trim();
+ currentArray.push(value);
+ }
+ }
+ // Handle key-value pairs
+ else if (trimmed.includes(":")) {
+ const colonIndex = trimmed.indexOf(":");
+ const key = trimmed.substring(0, colonIndex).trim();
+ let value = trimmed.substring(colonIndex + 1).trim();
+
+ if (leadingSpaces === 0) {
+ // Top-level property
+ currentKey = key;
+ currentArray = null;
+ currentObject = null;
+
+ if (value) {
+ // Handle array format [item1, item2, item3]
+ if (value.startsWith("[") && value.endsWith("]")) {
+ const arrayContent = value.slice(1, -1);
+ if (arrayContent.trim()) {
+ result[key] = arrayContent.split(",").map(item => item.trim());
+ } else {
+ result[key] = [];
+ }
+ currentKey = null; // Reset since we handled the array
+ } else {
+ result[key] = value;
+ }
+ } else if (key === "items" || key === "tags") {
+ // Will be populated by array items
+ result[key] = [];
+ currentArray = result[key];
+ } else if (key === "display") {
+ result[key] = {};
+ currentObject = result[key];
+ }
+ } else if (currentObject && leadingSpaces > 0) {
+ // Property of current object (e.g., display properties)
+ currentObject[key] = value === "true" ? true : value === "false" ? false : value;
+ } else if (currentArray && currentObject && leadingSpaces > leadingSpaces) {
+ // Property of array item object
+ currentObject[key] = value;
+ }
+ }
+ }
+
+ return result;
+ },
+ filePath,
+ null
+ );
+}
+
function extractTitle(filePath) {
return safeFileOperation(
() => {
@@ -409,6 +529,110 @@ function generateChatModesSection(chatmodesDir) {
return `${TEMPLATES.chatmodesSection}\n${TEMPLATES.chatmodesUsage}\n\n${chatmodesContent}`;
}
+/**
+ * Generate the collections section with a table of all collections
+ */
+function generateCollectionsSection(collectionsDir) {
+ // Check if collections directory exists
+ if (!fs.existsSync(collectionsDir)) {
+ console.log("Collections directory does not exist");
+ return "";
+ }
+
+ // Get all collection files
+ const collectionFiles = fs
+ .readdirSync(collectionsDir)
+ .filter((file) => file.endsWith(".collection.yml"))
+ .sort();
+
+ console.log(`Found ${collectionFiles.length} collection files`);
+
+ // If no collections, return empty string
+ if (collectionFiles.length === 0) {
+ return "";
+ }
+
+ // Create table header
+ let collectionsContent =
+ "| Name | Description | Items | Tags |\n| ---- | ----------- | ----- | ---- |\n";
+
+ // Generate table rows for each collection file
+ for (const file of collectionFiles) {
+ const filePath = path.join(collectionsDir, file);
+ const collection = parseCollectionYaml(filePath);
+
+ if (!collection) {
+ console.warn(`Failed to parse collection: ${file}`);
+ continue;
+ }
+
+ const collectionId = collection.id || path.basename(file, ".collection.yml");
+ const name = collection.name || collectionId;
+ const description = collection.description || "No description";
+ const itemCount = collection.items ? collection.items.length : 0;
+ const tags = collection.tags ? collection.tags.join(", ") : "";
+
+ const link = `collections/${collectionId}.md`;
+
+ collectionsContent += `| [${name}](${link}) | ${description} | ${itemCount} items | ${tags} |\n`;
+ }
+
+ return `${TEMPLATES.collectionsSection}\n${TEMPLATES.collectionsUsage}\n\n${collectionsContent}`;
+}
+
+/**
+ * Generate individual collection README file
+ */
+function generateCollectionReadme(collection, collectionId) {
+ if (!collection || !collection.items) {
+ return `# ${collectionId}\n\nCollection not found or invalid.`;
+ }
+
+ const name = collection.name || collectionId;
+ const description = collection.description || "No description provided.";
+ const tags = collection.tags ? collection.tags.join(", ") : "None";
+
+ let content = `# ${name}\n\n${description}\n\n`;
+
+ if (collection.tags && collection.tags.length > 0) {
+ content += `**Tags:** ${tags}\n\n`;
+ }
+
+ content += `## Items in this Collection\n\n`;
+ content += `| Title | Type | Description |\n| ----- | ---- | ----------- |\n`;
+
+ // Sort items based on display.ordering setting
+ const items = [...collection.items];
+ if (collection.display?.ordering === "alpha") {
+ items.sort((a, b) => {
+ const titleA = extractTitle(path.join(__dirname, a.path));
+ const titleB = extractTitle(path.join(__dirname, b.path));
+ return titleA.localeCompare(titleB);
+ });
+ }
+
+ for (const item of items) {
+ const filePath = path.join(__dirname, item.path);
+ const title = extractTitle(filePath);
+ const description = extractDescription(filePath) || "No description";
+ const typeDisplay = item.kind === "chat-mode" ? "Chat Mode" :
+ item.kind === "instruction" ? "Instruction" : "Prompt";
+ const link = `../${item.path}`;
+
+ // Create install badges for each item
+ const badges = makeBadges(item.path, item.kind === "instruction" ? "instructions" :
+ item.kind === "chat-mode" ? "mode" : "prompt");
+
+ content += `| [${title}](${link})
${badges} | ${typeDisplay} | ${description} |\n`;
+ }
+
+ if (collection.display?.show_badge) {
+ content += `\n---\n*This collection includes ${items.length} curated items for ${name.toLowerCase()}.*`;
+ }
+
+ return content;
+}
+
// Utility: write file only if content changed
function writeFileIfChanged(filePath, content) {
const exists = fs.existsSync(filePath);
@@ -441,11 +665,13 @@ try {
const instructionsDir = path.join(__dirname, "instructions");
const promptsDir = path.join(__dirname, "prompts");
const chatmodesDir = path.join(__dirname, "chatmodes");
+ const collectionsDir = path.join(__dirname, "collections");
// Compose headers for standalone files by converting section headers to H1
const instructionsHeader = TEMPLATES.instructionsSection.replace(/^##\s/m, "# ");
const promptsHeader = TEMPLATES.promptsSection.replace(/^##\s/m, "# ");
const chatmodesHeader = TEMPLATES.chatmodesSection.replace(/^##\s/m, "# ");
+ const collectionsHeader = TEMPLATES.collectionsSection.replace(/^##\s/m, "# ");
const instructionsReadme = buildCategoryReadme(
generateInstructionsSection,
@@ -465,11 +691,41 @@ try {
chatmodesHeader,
TEMPLATES.chatmodesUsage
);
+
+ // Generate collections README
+ const collectionsReadme = buildCategoryReadme(
+ generateCollectionsSection,
+ collectionsDir,
+ collectionsHeader,
+ TEMPLATES.collectionsUsage
+ );
- // Write outputs
+ // Write category outputs
writeFileIfChanged(path.join(__dirname, "README.instructions.md"), instructionsReadme);
writeFileIfChanged(path.join(__dirname, "README.prompts.md"), promptsReadme);
writeFileIfChanged(path.join(__dirname, "README.chatmodes.md"), chatmodesReadme);
+ writeFileIfChanged(path.join(__dirname, "README.collections.md"), collectionsReadme);
+
+ // Generate individual collection README files
+ if (fs.existsSync(collectionsDir)) {
+ console.log("Generating individual collection README files...");
+
+ const collectionFiles = fs
+ .readdirSync(collectionsDir)
+ .filter((file) => file.endsWith(".collection.yml"));
+
+ for (const file of collectionFiles) {
+ const filePath = path.join(collectionsDir, file);
+ const collection = parseCollectionYaml(filePath);
+
+ if (collection) {
+ const collectionId = collection.id || path.basename(file, ".collection.yml");
+ const readmeContent = generateCollectionReadme(collection, collectionId);
+ const readmeFile = path.join(collectionsDir, `${collectionId}.md`);
+ writeFileIfChanged(readmeFile, readmeContent);
+ }
+ }
+ }
} catch (error) {
console.error(`Error generating category README files: ${error.message}`);
process.exit(1);