diff --git a/.schemas/collection.schema.json b/.schemas/collection.schema.json index 0119882..d69ea69 100644 --- a/.schemas/collection.schema.json +++ b/.schemas/collection.schema.json @@ -50,7 +50,7 @@ "path": { "type": "string", "description": "Relative path from repository root to the item file", - "pattern": "^(prompts|instructions|chatmodes)\/[^\/]+\\.(prompt|instructions|chatmode)\\.md$", + "pattern": "^(prompts|instructions|chatmodes)/[^/]+\\.(prompt|instructions|chatmode)\\.md$", "minLength": 1 }, "kind": { @@ -81,6 +81,11 @@ "type": "boolean", "description": "Whether to show collection badge on items", "default": false + }, + "promoted": { + "type": "boolean", + "description": "Whether this collection is promoted on the main page", + "default": false } } } diff --git a/.vscode/settings.json b/.vscode/settings.json index bf65aac..f3bd8d6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,13 +1,4 @@ { - "chat.modeFilesLocations": { - "chatmodes": true - }, - "chat.promptFilesLocations": { - "prompts": true - }, - "chat.instructionsFilesLocations": { - "instructions": true - }, "files.eol": "\n", "files.insertFinalNewline": true, "files.trimTrailingWhitespace": true, diff --git a/README.collections.md b/README.collections.md index 505f47d..d6a1824 100644 --- a/README.collections.md +++ b/README.collections.md @@ -4,6 +4,7 @@ Curated collections of related prompts, instructions, and chat modes organized a ### How to Use Collections **Browse Collections:** +- ⭐ Featured collections are highlighted and appear at the top of the list - 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 @@ -15,6 +16,7 @@ Curated collections of related prompts, instructions, and chat modes organized a | Name | Description | Items | Tags | | ---- | ----------- | ----- | ---- | +| [⭐ Partners](collections/partners.md) | Custom agents that have been created by GitHub partners | 10 items | tag1, tag2, tag3 | | [Azure & Cloud Development](collections/azure-cloud-development.md) | Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 18 items | azure, cloud, infrastructure, bicep, terraform, serverless, architecture, devops | | [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 | | [C# MCP Server Development](collections/csharp-mcp-development.md) | Complete toolkit for building Model Context Protocol (MCP) servers in C# using the official SDK. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 3 items | csharp, mcp, model-context-protocol, dotnet, server-development | diff --git a/README.md b/README.md index 80753d0..6c74922 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,15 @@ This repository provides a comprehensive toolkit for enhancing GitHub Copilot wi - **[![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 +## 🌟 Featured Collections + +Discover our curated collections of prompts, instructions, and chat modes organized around specific themes and workflows. + +| Name | Description | Items | Tags | +| ---- | ----------- | ----- | ---- | +| [Partners](collections/partners.md) | Custom agents that have been created by GitHub partners | 10 items | tag1, tag2, tag3 | + + ## MCP Server To make it easy to add these customizations to your editor, we have created a [MCP Server](https://developer.microsoft.com/blog/announcing-awesome-copilot-mcp-server) that provides a prompt for searching and installing prompts, instructions, and chat modes directly from this repository. You'll need to have Docker installed and running to run the server. diff --git a/collections/partners.collection.yml b/collections/partners.collection.yml new file mode 100644 index 0000000..55a8f8d --- /dev/null +++ b/collections/partners.collection.yml @@ -0,0 +1,29 @@ +id: partners +name: Partners +description: Custom agents that have been created by GitHub partners +tags: [tag1, tag2, tag3] +items: + - path: chatmodes/api-architect.chatmode.md + kind: chat-mode + - path: chatmodes/azure-logic-apps-expert.chatmode.md + kind: chat-mode + - path: chatmodes/blueprint-mode-codex.chatmode.md + kind: chat-mode + - path: chatmodes/clojure-interactive-programming.chatmode.md + kind: chat-mode + - path: chatmodes/expert-cpp-software-engineer.chatmode.md + kind: chat-mode + - path: chatmodes/gilfoyle.chatmode.md + kind: chat-mode + - path: chatmodes/java-mcp-expert.chatmode.md + kind: chat-mode + - path: chatmodes/meta-agentic-project-scaffold.chatmode.md + kind: chat-mode + - path: chatmodes/power-platform-expert.chatmode.md + kind: chat-mode + - path: chatmodes/ruby-mcp-expert.chatmode.md + kind: chat-mode +display: + ordering: alpha # or "manual" to preserve the order above + show_badge: false # set to true to show collection badge on items + promoted: true diff --git a/collections/partners.md b/collections/partners.md new file mode 100644 index 0000000..bde0171 --- /dev/null +++ b/collections/partners.md @@ -0,0 +1,23 @@ +# Partners + +Custom agents that have been created by GitHub partners + +**Tags:** tag1, tag2, tag3 + +## Items in this Collection + +| Title | Type | Description | +| ----- | ---- | ----------- | +| [API Architect mode instructions](../chatmodes/api-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%2Fapi-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%2Fapi-architect.chatmode.md) | Chat Mode | Your role is that of an API architect. Help mentor the engineer by providing guidance, support, and working code. | +| [Azure Logic Apps Expert Mode](../chatmodes/azure-logic-apps-expert.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-logic-apps-expert.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-logic-apps-expert.chatmode.md) | Chat Mode | Expert guidance for Azure Logic Apps development focusing on workflow design, integration patterns, and JSON-based Workflow Definition Language. | +| [Blueprint Mode Codex v1](../chatmodes/blueprint-mode-codex.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%2Fblueprint-mode-codex.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%2Fblueprint-mode-codex.chatmode.md) | Chat Mode | Executes structured workflows with strict correctness and maintainability. Enforces a minimal tool usage policy, never assumes facts, prioritizes reproducible solutions, self-correction, and edge-case handling. | +| [Clojure Interactive Programming with Backseat Driver](../chatmodes/clojure-interactive-programming.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%2Fclojure-interactive-programming.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%2Fclojure-interactive-programming.chatmode.md) | Chat Mode | Expert Clojure pair programmer with REPL-first methodology, architectural oversight, and interactive problem-solving. Enforces quality standards, prevents workarounds, and develops solutions incrementally through live REPL evaluation before file modifications. | +| [Expert C++ software engineer mode instructions](../chatmodes/expert-cpp-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-cpp-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-cpp-software-engineer.chatmode.md) | Chat Mode | Provide expert C++ software engineering guidance using modern C++ and industry best practices. | +| [Gilfoyle Code Review Mode](../chatmodes/gilfoyle.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%2Fgilfoyle.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%2Fgilfoyle.chatmode.md) | Chat Mode | Code review and analysis with the sardonic wit and technical elitism of Bertram Gilfoyle from Silicon Valley. Prepare for brutal honesty about your code. | +| [Java MCP Expert](../chatmodes/java-mcp-expert.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%2Fjava-mcp-expert.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%2Fjava-mcp-expert.chatmode.md) | Chat Mode | Expert assistance for building Model Context Protocol servers in Java using reactive streams, the official MCP Java SDK, and Spring Boot integration. | +| [Meta Agentic Project Scaffold](../chatmodes/meta-agentic-project-scaffold.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%2Fmeta-agentic-project-scaffold.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%2Fmeta-agentic-project-scaffold.chatmode.md) | Chat Mode | Meta agentic project creation assistant to help users create and manage project workflows effectively. | +| [Power Platform Expert](../chatmodes/power-platform-expert.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%2Fpower-platform-expert.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%2Fpower-platform-expert.chatmode.md) | Chat Mode | Power Platform expert providing guidance on Code Apps, canvas apps, Dataverse, connectors, and Power Platform best practices | +| [Ruby MCP Expert](../chatmodes/ruby-mcp-expert.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%2Fruby-mcp-expert.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%2Fruby-mcp-expert.chatmode.md) | Chat Mode | Expert assistance for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration. | + +--- +*This collection includes 10 curated items for **Partners**.* \ No newline at end of file diff --git a/update-readme.js b/update-readme.js index 0668d7c..bc9f8f1 100755 --- a/update-readme.js +++ b/update-readme.js @@ -58,6 +58,7 @@ Curated collections of related prompts, instructions, and chat modes organized a collectionsUsage: `### How to Use Collections **Browse Collections:** +- ⭐ Featured collections are highlighted and appear at the top of the list - 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 @@ -66,6 +67,10 @@ Curated collections of related prompts, instructions, and chat modes organized a - 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`, + + promotedCollectionsSection: `## 🌟 Featured Collections + +Discover our curated collections of prompts, instructions, and chat modes organized around specific themes and workflows.`, }; // Add error handling utility @@ -525,17 +530,32 @@ function generateCollectionsSection(collectionsDir) { const collectionId = collection.id || path.basename(file, ".collection.yml"); const name = collection.name || collectionId; - return { file, filePath, collection, collectionId, name }; + const isPromoted = collection.display?.promoted === true; + return { file, filePath, collection, collectionId, name, isPromoted }; }) .filter((entry) => entry !== null); // Remove failed parses - // Sort by name alphabetically - collectionEntries.sort((a, b) => a.name.localeCompare(b.name)); + // Separate promoted and regular collections + const promotedCollections = collectionEntries.filter( + (entry) => entry.isPromoted + ); + const regularCollections = collectionEntries.filter( + (entry) => !entry.isPromoted + ); - console.log(`Found ${collectionEntries.length} collection files`); + // Sort each group alphabetically by name + promotedCollections.sort((a, b) => a.name.localeCompare(b.name)); + regularCollections.sort((a, b) => a.name.localeCompare(b.name)); + + // Combine: promoted first, then regular + const sortedEntries = [...promotedCollections, ...regularCollections]; + + console.log( + `Found ${collectionEntries.length} collection files (${promotedCollections.length} promoted)` + ); // If no collections, return empty string - if (collectionEntries.length === 0) { + if (sortedEntries.length === 0) { return ""; } @@ -544,20 +564,95 @@ function generateCollectionsSection(collectionsDir) { "| Name | Description | Items | Tags |\n| ---- | ----------- | ----- | ---- |\n"; // Generate table rows for each collection file - for (const entry of collectionEntries) { - const { collection, collectionId, name } = entry; + for (const entry of sortedEntries) { + const { collection, collectionId, name, isPromoted } = entry; 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`; + const displayName = isPromoted ? `⭐ ${name}` : name; - collectionsContent += `| [${name}](${link}) | ${description} | ${itemCount} items | ${tags} |\n`; + collectionsContent += `| [${displayName}](${link}) | ${description} | ${itemCount} items | ${tags} |\n`; } return `${TEMPLATES.collectionsSection}\n${TEMPLATES.collectionsUsage}\n\n${collectionsContent}`; } +/** + * Generate the promoted collections section for the main README + */ +function generatePromotedCollectionsSection(collectionsDir) { + // Check if collections directory exists + if (!fs.existsSync(collectionsDir)) { + return ""; + } + + // Get all collection files + const collectionFiles = fs + .readdirSync(collectionsDir) + .filter((file) => file.endsWith(".collection.yml")); + + // Map collection files to objects with name for sorting, filter for promoted + const promotedCollections = collectionFiles + .map((file) => { + const filePath = path.join(collectionsDir, file); + return safeFileOperation( + () => { + const collection = parseCollectionYaml(filePath); + if (!collection) return null; + + // Only include collections with promoted: true + if (!collection.display?.promoted) return null; + + const collectionId = + collection.id || path.basename(file, ".collection.yml"); + const name = collection.name || collectionId; + const description = collection.description || "No description"; + const tags = collection.tags ? collection.tags.join(", ") : ""; + const itemCount = collection.items ? collection.items.length : 0; + + return { + file, + collection, + collectionId, + name, + description, + tags, + itemCount, + }; + }, + filePath, + null + ); + }) + .filter((entry) => entry !== null); // Remove non-promoted and failed parses + + // Sort by name alphabetically + promotedCollections.sort((a, b) => a.name.localeCompare(b.name)); + + console.log(`Found ${promotedCollections.length} promoted collection(s)`); + + // If no promoted collections, return empty string + if (promotedCollections.length === 0) { + return ""; + } + + // Create table header + let promotedContent = + "| Name | Description | Items | Tags |\n| ---- | ----------- | ----- | ---- |\n"; + + // Generate table rows for each promoted collection + for (const entry of promotedCollections) { + const { collectionId, name, description, tags, itemCount } = entry; + const readmeLink = `collections/${collectionId}.md`; + + promotedContent += `| [${name}](${readmeLink}) | ${description} | ${itemCount} items | ${tags} |\n`; + } + + return `${TEMPLATES.promotedCollectionsSection}\n\n${promotedContent}`; +} + /** * Generate individual collection README file */ @@ -761,6 +856,52 @@ try { } } } + + // Generate promoted collections section and update main README.md + console.log("Updating main README.md with promoted collections..."); + const promotedSection = generatePromotedCollectionsSection(collectionsDir); + + if (promotedSection) { + const mainReadmePath = path.join(__dirname, "README.md"); + + if (fs.existsSync(mainReadmePath)) { + let readmeContent = fs.readFileSync(mainReadmePath, "utf8"); + + // Define markers to identify where to insert the promoted collections + const startMarker = "## 🌟 Featured Collections"; + const endMarker = "## MCP Server"; + + // Check if the section already exists + const startIndex = readmeContent.indexOf(startMarker); + + if (startIndex !== -1) { + // Section exists, replace it + const endIndex = readmeContent.indexOf(endMarker, startIndex); + if (endIndex !== -1) { + // Replace the existing section + const beforeSection = readmeContent.substring(0, startIndex); + const afterSection = readmeContent.substring(endIndex); + readmeContent = + beforeSection + promotedSection + "\n\n" + afterSection; + } + } else { + // Section doesn't exist, insert it before "## MCP Server" + const mcpIndex = readmeContent.indexOf(endMarker); + if (mcpIndex !== -1) { + const beforeMcp = readmeContent.substring(0, mcpIndex); + const afterMcp = readmeContent.substring(mcpIndex); + readmeContent = beforeMcp + promotedSection + "\n\n" + afterMcp; + } + } + + writeFileIfChanged(mainReadmePath, readmeContent); + console.log("Main README.md updated with promoted collections"); + } else { + console.warn("README.md not found, skipping promoted collections update"); + } + } else { + console.log("No promoted collections found to add to README.md"); + } } catch (error) { console.error(`Error generating category README files: ${error.message}`); process.exit(1);