From 406b613cf8230fe6cf9e81f451d34f25b1914ace Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Sep 2025 01:31:17 +0000 Subject: [PATCH] Implement core Collections feature with YAML parsing and README generation Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com> --- .schemas/collection.schema.json | 84 ++++++ README.collections.md | 19 ++ README.md | 4 +- .../csharp-dotnet-development.collection.yml | 22 ++ collections/csharp-dotnet-development.md | 17 ++ collections/devops-oncall.collection.yml | 18 ++ collections/devops-oncall.md | 18 ++ update-readme.js | 258 +++++++++++++++++- 8 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 .schemas/collection.schema.json create mode 100644 README.collections.md create mode 100644 collections/csharp-dotnet-development.collection.yml create mode 100644 collections/csharp-dotnet-development.md create mode 100644 collections/devops-oncall.collection.yml create mode 100644 collections/devops-oncall.md 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 - **[![Awesome Prompts](https://img.shields.io/badge/Awesome-Prompts-blue?logo=githubcopilot)](README.prompts.md)** - Focused, task-specific prompts for generating code, documentation, and solving specific problems - **[![Awesome Instructions](https://img.shields.io/badge/Awesome-Instructions-blue?logo=githubcopilot)](README.instructions.md)** - Comprehensive coding standards and best practices that apply to specific file patterns or entire projects - **[![Awesome Chat Modes](https://img.shields.io/badge/Awesome-Chat_Modes-blue?logo=githubcopilot)](README.chatmodes.md)** - Specialized AI personas and conversation modes for different roles and contexts +- **[![Awesome Collections](https://img.shields.io/badge/Awesome-Collections-blue?logo=githubcopilot)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](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)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](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);