Update development instructions and guidelines (#29)

* Delete outdated development instructions for Next.js + Tailwind and Python; add comprehensive guidelines for PostgreSQL DBA, Angular, ASP.NET REST APIs, Azure Functions with TypeScript, Bicep, Blazor, CMake with vcpkg, C#, .NET MAUI, GenAIScript, Terraform for Azure, localization, and markdown standards.

* Update documentation and prompts for consistency and clarity

- Standardized description formatting in various markdown files to use single quotes.
- Added error handling utility in update-readme.js for safer file operations.
- Improved title extraction logic in update-readme.js to handle frontmatter more robustly.
- Updated chat modes section in README to reflect new emoji and sorted chat mode links.
- Cleaned up various instruction files for better readability and consistency.
- Ensured all markdown files end with a newline for better compatibility with version control.

* Remove standardize-frontmatter.js script

* Add usage instructions for creating and switching chat modes in README.md

* Update README.md generation script to enhance instructions and usage details for custom chat modes

* Update README.md and update-readme.js for improved instruction clarity and consistency

* Refactor README.md links and update readme script for improved clarity and consistency in instructions

* Update README.md and update-readme.js for improved instruction clarity and consistency

* Changing from a patch to regen approach for the readme

* Bit more cleanup for how to show things in the readme

* Adding missing description

* Another missing description

---------

Co-authored-by: Aaron Powell <me@aaron-powell.com>
This commit is contained in:
James Montemagno 2025-07-02 18:18:52 -07:00 committed by GitHub
parent d1256681e7
commit 6fb794bc79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
39 changed files with 447 additions and 486 deletions

View File

@ -6,7 +6,7 @@ Enhance your GitHub Copilot experience with community-contributed instructions,
GitHub Copilot provides three main ways to customize AI responses and tailor assistance to your specific workflows, team guidelines, and project requirements: GitHub Copilot provides three main ways to customize AI responses and tailor assistance to your specific workflows, team guidelines, and project requirements:
| **🔧 Custom Instructions** | **📝 Reusable Prompts** | **🎭 Custom Chat Modes** | | **🔧 Custom Instructions** | **📝 Reusable Prompts** | **🧩 Custom Chat Modes** |
| --- | --- | --- | | --- | --- | --- |
| Define common guidelines for tasks like code generation, reviews, and commit messages. Describe *how* tasks should be performed<br><br>**Benefits:**<br>• Automatic inclusion in every chat request<br>• Repository-wide consistency<br>• Multiple implementation options | Create reusable, standalone prompts for specific tasks. Describe *what* should be done with optional task-specific guidelines<br><br>**Benefits:**<br>• Eliminate repetitive prompt writing<br>• Shareable across teams<br>• Support for variables and dependencies | Define chat behavior, available tools, and codebase interaction patterns within specific boundaries for each request<br><br>**Benefits:**<br>• Context-aware assistance<br>• Tool configuration<br>• Role-specific workflows | | Define common guidelines for tasks like code generation, reviews, and commit messages. Describe *how* tasks should be performed<br><br>**Benefits:**<br>• Automatic inclusion in every chat request<br>• Repository-wide consistency<br>• Multiple implementation options | Create reusable, standalone prompts for specific tasks. Describe *what* should be done with optional task-specific guidelines<br><br>**Benefits:**<br>• Eliminate repetitive prompt writing<br>• Shareable across teams<br>• Support for variables and dependencies | Define chat behavior, available tools, and codebase interaction patterns within specific boundaries for each request<br><br>**Benefits:**<br>• Context-aware assistance<br>• Tool configuration<br>• Role-specific workflows |
@ -21,22 +21,21 @@ We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md)
Team and project-specific instructions to enhance GitHub Copilot's behavior for specific technologies and coding practices: Team and project-specific instructions to enhance GitHub Copilot's behavior for specific technologies and coding practices:
- [Angular Development Instructions](instructions/angular.md) - Angular-specific coding standards and best practices - [Angular Development Instructions](instructions/angular.instructions.md) - Angular-specific coding standards and best practices
- [ASP.NET REST API Development](instructions/aspnet-rest-apis.md) - Guidelines for building REST APIs with ASP.NET - [ASP.NET REST API Development](instructions/aspnet-rest-apis.instructions.md) - Guidelines for building REST APIs with ASP.NET
- [Azure Functions Typescript](instructions/azure-functions-typescript.md) - TypeScript patterns for Azure Functions - [Azure Functions Typescript](instructions/azure-functions-typescript.instructions.md) - TypeScript patterns for Azure Functions
- [Bicep Code Best Practices](instructions/bicep-code-best-practices.md) - Infrastructure as Code with Bicep - [Bicep Code Best Practices](instructions/bicep-code-best-practices.instructions.md) - Infrastructure as Code with Bicep
- [Blazor](instructions/blazor.md) - Blazor component and application patterns - [Blazor](instructions/blazor.instructions.md) - Blazor component and application patterns
- [Cmake Vcpkg](instructions/cmake-vcpkg.md) - C++ project configuration and package management - [Cmake Vcpkg](instructions/cmake-vcpkg.instructions.md) - C++ project configuration and package management
- [Copilot Process tracking Instructions](instructions/copilot-thought-logging.instructions.md) - See process Copilot is following where you can edit this to reshape the interaction or save when follow up may be needed - [Copilot Process tracking Instructions](instructions/copilot-thought-logging.instructions.md) - See process Copilot is following where you can edit this to reshape the interaction or save when follow up may be needed
- [C# Development](instructions/csharp.md) - Guidelines for building C# applications - [C# Development](instructions/csharp.instructions.md) - Guidelines for building C# applications
- [Dotnet Maui](instructions/dotnet-maui.md) - MAUI component and application patterns - [.NET MAUI](instructions/dotnet-maui.instructions.md) - .NET MAUI component and application patterns
- [Genaiscript](instructions/genaiscript.md) - AI-powered script generation guidelines - [Genaiscript](instructions/genaiscript.instructions.md) - AI-powered script generation guidelines
- [Generate Modern Terraform Code For Azure](instructions/generate-modern-terraform-code-for-azure.md) - Guidelines for generating modern Terraform code for Azure - [Generate Modern Terraform Code For Azure](instructions/generate-modern-terraform-code-for-azure.instructions.md) - Guidelines for generating modern Terraform code for Azure
- [Guidance for Localization](instructions/localization.md) - Guidelines for localizing markdown documents - [Guidance for Localization](instructions/localization.instructions.md) - Guidelines for localizing markdown documents
- [Markdown](instructions/markdown.md) - Documentation and content creation standards - [Markdown](instructions/markdown.instructions.md) - Documentation and content creation standards
- [Next.js + Tailwind Development Instructions](instructions/nextjs-tailwind.md) - Next.js + Tailwind development standards and instructions - [Next.js + Tailwind Development Instructions](instructions/nextjs-tailwind.instructions.md) - Next.js + Tailwind development standards and instructions
- [Python Coding Conventions](instructions/python.md) - Python coding conventions and guidelines - [Python Coding Conventions](instructions/python.instructions.md) - Python coding conventions and guidelines
> 💡 **Usage**: Copy these instructions to your `.github/copilot-instructions.md` file or create task-specific `.github/.instructions.md` files in your workspace's `.github/instructions` folder. > 💡 **Usage**: Copy these instructions to your `.github/copilot-instructions.md` file or create task-specific `.github/.instructions.md` files in your workspace's `.github/instructions` folder.
@ -44,27 +43,20 @@ Team and project-specific instructions to enhance GitHub Copilot's behavior for
Ready-to-use prompt templates for specific development scenarios and tasks, defining prompt text with a specific mode, model, and available set of tools. Ready-to-use prompt templates for specific development scenarios and tasks, defining prompt text with a specific mode, model, and available set of tools.
### Backend Development - [ASP.NET Minimal API with OpenAPI](prompts/aspnet-minimal-api-openapi.prompt.md) - Create ASP.NET Minimal API endpoints with proper OpenAPI documentation
- [ASP.NET Minimal API with OpenAPI](prompts/aspnet-minimal-api-openapi.prompt.md) - Generate API endpoints with proper documentation - [Azure Cost Optimize](prompts/az-cost-optimize.prompt.md) - Analyze Azure resources used in the app (IaC files and/or resources in a target rg) and optimize costs - creating GitHub issues for identified optimizations.
- [Entity Framework Core Best Practices](prompts/ef-core.prompt.md) - Database operations and ORM patterns - [Comment Code Generate A Tutorial](prompts/comment-code-generate-a-tutorial.prompt.md) - Transform this Python script into a polished, beginner-friendly project by refactoring the code, adding clear instructional comments, and generating a complete markdown tutorial.
- [Multi-Stage Dockerfile](prompts/multi-stage-dockerfile.prompt.md) - Optimized container builds for any technology - [C# Async Programming Best Practices](prompts/csharp-async.prompt.md) - Get best practices for C# async programming
- [C# Documentation Best Practices](prompts/csharp-docs.prompt.md) - Ensure that C# types are documented with XML comments and follow best practices for documentation.
### Testing & Quality - [MSTest Best Practices](prompts/csharp-mstest.prompt.md) - Get best practices for MSTest unit testing, including data-driven tests
- [C# Async Programming](prompts/csharp-async.prompt.md) - Asynchronous programming best practices - [NUnit Best Practices](prompts/csharp-nunit.prompt.md) - Get best practices for NUnit unit testing, including data-driven tests
- [MSTest Best Practices](prompts/csharp-mstest.prompt.md) - MSTest unit testing with data-driven tests - [XUnit Best Practices](prompts/csharp-xunit.prompt.md) - Get best practices for XUnit unit testing, including data-driven tests
- [NUnit Best Practices](prompts/csharp-nunit.prompt.md) - NUnit testing patterns and assertions - [Entity Framework Core Best Practices](prompts/ef-core.prompt.md) - Get best practices for Entity Framework Core
- [XUnit Best Practices](prompts/csharp-xunit.prompt.md) - XUnit testing with modern C# features - [Product Manager Assistant: Feature Identification and Specification](prompts/gen-specs-as-issues.prompt.md) - This workflow guides you through a systematic approach to identify missing features, prioritize them, and create detailed specifications for implementation.
- [JavaScript/TypeScript Jest](prompts/javascript-typescript-jest.prompt.md) - Jest testing patterns, mocking, and structure - [Javascript Typescript Jest](prompts/javascript-typescript-jest.prompt.md) - Best practices for writing JavaScript/TypeScript tests using Jest, including mocking strategies, test structure, and common patterns.
- [Multi Stage Dockerfile](prompts/multi-stage-dockerfile.prompt.md) - Create optimized multi-stage Dockerfiles for any language or framework
### Documentation & Project Management
- [Comment Code Generate Tutorial](prompts/comment-code-generate-a-tutorial.prompt.md) - Transform code into educational content
- [Generate Specs as Issues](prompts/gen-specs-as-issues.prompt.md) - Convert requirements into GitHub issues
- [My Issues](prompts/my-issues.prompt.md) - [My Issues](prompts/my-issues.prompt.md)
- [My Pull Requests](prompts/my-pull-requests.prompt.md) - [My Pull Requests](prompts/my-pull-requests.prompt.md)
- [C# Documentation Best Practices](prompts/csharp-docs.prompt.md) - Ensure that C# types are documented with XML comments and follow best practices for documentation.
### FinOps
- [Azure Cost Optimize](prompts/az-cost-optimize.prompt.md) - Analyze Azure resources used in the app (IaC files and/or resources in a target rg) and optimize costs - creating GitHub issues for identified optimizations.
> 💡 **Usage**: Use `/prompt-name` in VS Code chat, run `Chat: Run Prompt` command, or hit the run button while you have a prompt open. > 💡 **Usage**: Use `/prompt-name` in VS Code chat, run `Chat: Run Prompt` command, or hit the run button while you have a prompt open.
@ -73,12 +65,11 @@ Ready-to-use prompt templates for specific development scenarios and tasks, defi
Custom chat modes define specific behaviors and tools for GitHub Copilot Chat, enabling enhanced context-aware assistance for particular tasks or workflows. Custom chat modes define specific behaviors and tools for GitHub Copilot Chat, enabling enhanced context-aware assistance for particular tasks or workflows.
- [4.1 Beast Mode](chatmodes/4.1-Beast.chatmode.md) - A custom prompt to get GPT 4.1 to behave like a top-notch coding agent. - [4.1 Beast Mode](chatmodes/4.1-Beast.chatmode.md) - A custom prompt to get GPT 4.1 to behave like a top-notch coding agent.
- [Database Administrator Chat Mode](chatmodes/PostgreSQL%20DBA.chatmode.md) - Work with PostgreSQL databases using the PostgreSQL extension.
- [Debug Mode Instructions](chatmodes/debug.chatmode.md) - Debug your application to find and fix a bug - [Debug Mode Instructions](chatmodes/debug.chatmode.md) - Debug your application to find and fix a bug
- [Planning mode instructions](chatmodes/planner.chatmode.md) - Generate an implementation plan for new features or refactoring existing code. - [Planning mode instructions](chatmodes/planner.chatmode.md) - Generate an implementation plan for new features or refactoring existing code.
- [PostgreSQL Database Administrator](chatmodes/postgresql-dba.chatmode.md) - Work with PostgreSQL databases using the PostgreSQL extension.
- [Refine Requirement or Issue Chat Mode](chatmodes/refine-issue.chatmode.md) - Refine the requirement or issue with Acceptance Criteria, Technical Considerations, Edge Cases, and NFRs - [Refine Requirement or Issue Chat Mode](chatmodes/refine-issue.chatmode.md) - Refine the requirement or issue with Acceptance Criteria, Technical Considerations, Edge Cases, and NFRs
> 💡 **Usage**: Create new chat modes using the command `Chat: Configure Chat Modes...`, then switch your chat mode in the Chat input from _Agent_ or _Ask_ to your own mode. > 💡 **Usage**: Create new chat modes using the command `Chat: Configure Chat Modes...`, then switch your chat mode in the Chat input from _Agent_ or _Ask_ to your own mode.
## 📚 Additional Resources ## 📚 Additional Resources

View File

@ -1,5 +1,5 @@
--- ---
description: Debug your application to find and fix a bug description: 'Debug your application to find and fix a bug'
tools: ['codebase', 'readFiles', 'editFiles', 'githubRepo', 'runCommands', 'fetch', 'search', 'usages', 'findTestFiles', 'get_errors', 'test_failure', 'run_in_terminal', 'get_terminal_output'] tools: ['codebase', 'readFiles', 'editFiles', 'githubRepo', 'runCommands', 'fetch', 'search', 'usages', 'findTestFiles', 'get_errors', 'test_failure', 'run_in_terminal', 'get_terminal_output']
--- ---

View File

@ -1,5 +1,5 @@
--- ---
description: Generate an implementation plan for new features or refactoring existing code. description: 'Generate an implementation plan for new features or refactoring existing code.'
tools: ['codebase', 'fetch', 'findTestFiles', 'githubRepo', 'search', 'usages'] tools: ['codebase', 'fetch', 'findTestFiles', 'githubRepo', 'search', 'usages']
--- ---
# Planning mode instructions # Planning mode instructions

View File

@ -1,9 +1,11 @@
--- ---
description: 'Work with PostgreSQL databases using the PostgreSQL extension.' description: 'Work with PostgreSQL databases using the PostgreSQL extension.'
tools: ['codebase', 'editFiles', 'githubRepo', 'runCommands', 'database', 'pgsql_bulkLoadCsv', 'pgsql_connect', 'pgsql_describeCsv', 'pgsql_disconnect', 'pgsql_listDatabases', 'pgsql_listServers', 'pgsql_modifyDatabase', 'pgsql_open_script', 'pgsql_query', 'pgsql_visualizeSchema'] tools: ['codebase', 'editFiles', 'githubRepo', 'extensions', 'runCommands', 'database', 'pgsql_bulkLoadCsv', 'pgsql_connect', 'pgsql_describeCsv', 'pgsql_disconnect', 'pgsql_listDatabases', 'pgsql_listServers', 'pgsql_modifyDatabase', 'pgsql_open_script', 'pgsql_query', 'pgsql_visualizeSchema']
--- ---
# Database Administrator Chat Mode # PostgreSQL Database Administrator
Before running any tools, use #extensions to ensure that `ms-ossdata.vscode-pgsql` is installed and enabled. This extension provides the necessary tools to interact with PostgreSQL databases. If it is not installed, ask the user to install it before continuing.
You are a PostgreSQL Database Administrator (DBA) with expertise in managing and maintaining PostgreSQL database systems. You can perform tasks such as: You are a PostgreSQL Database Administrator (DBA) with expertise in managing and maintaining PostgreSQL database systems. You can perform tasks such as:
- Creating and managing databases - Creating and managing databases

View File

@ -1,6 +1,6 @@
--- ---
description: | description: 'Angular-specific coding standards and best practices'
Angular-specific coding standards and best practices applyTo: '**/*.ts, **/*.html, **/*.scss, **/*.css'
--- ---
# Angular Development Instructions # Angular Development Instructions

View File

@ -1,5 +1,6 @@
--- ---
description: Guidelines for building REST APIs with ASP.NET description: 'Guidelines for building REST APIs with ASP.NET'
applyTo: '**/*.cs, **/*.json'
--- ---
# ASP.NET REST API Development # ASP.NET REST API Development

View File

@ -1,5 +1,6 @@
--- ---
description: TypeScript patterns for Azure Functions description: 'TypeScript patterns for Azure Functions'
applyTo: '**/*.ts, **/*.js, **/*.json'
--- ---
## Guidance for Code Generation ## Guidance for Code Generation

View File

@ -1,6 +1,6 @@
--- ---
description: Infrastructure as Code with Bicep description: 'Infrastructure as Code with Bicep'
applyTo: "**/*.bicep" applyTo: '**/*.bicep'
--- ---
## Naming Conventions ## Naming Conventions

View File

@ -1,6 +1,6 @@
--- ---
description: Blazor component and application patterns description: 'Blazor component and application patterns'
applyTo: "**/*.razor, **/*.razor.cs, **/*.razor.css" applyTo: '**/*.razor, **/*.razor.cs, **/*.razor.css'
--- ---
## Blazor Code Style and Structure ## Blazor Code Style and Structure

View File

@ -1,5 +1,6 @@
--- ---
description: C++ project configuration and package management description: 'C++ project configuration and package management'
applyTo: '**/*.cmake, **/CMakeLists.txt, **/*.cpp, **/*.h, **/*.hpp'
--- ---
This project uses vcpkg in manifest mode. Please keep this in mind when giving vcpkg suggestions. Do not provide suggestions like vcpkg install library, as they will not work as expected. This project uses vcpkg in manifest mode. Please keep this in mind when giving vcpkg suggestions. Do not provide suggestions like vcpkg install library, as they will not work as expected.

View File

@ -1,6 +1,5 @@
--- ---
applyTo: '**' applyTo: '**'
mode: "agent"
description: 'See process Copilot is following where you can edit this to reshape the interaction or save when follow up may be needed' description: 'See process Copilot is following where you can edit this to reshape the interaction or save when follow up may be needed'
--- ---

View File

@ -1,5 +1,6 @@
--- ---
description: Guidelines for building C# applications description: 'Guidelines for building C# applications'
applyTo: '**/*.cs'
--- ---
# C# Development # C# Development

View File

@ -1,12 +1,14 @@
--- ---
description: MAUI component and application patterns description: '.NET MAUI component and application patterns'
appliesTo: "**/*.xaml, **/*.cs" applyTo: '**/*.xaml, **/*.cs'
--- ---
## MAUI Code Style and Structure # .NET MAUI
- Write idiomatic and efficient MAUI and C# code. ## .NET MAUI Code Style and Structure
- Follow .NET and MAUI conventions.
- Write idiomatic and efficient .NET MAUI and C# code.
- Follow .NET and .NET MAUI conventions.
- Prefer inline functions for smaller components but separate complex logic into code-behind or service classes. - Prefer inline functions for smaller components but separate complex logic into code-behind or service classes.
- Async/await should be used where applicable to ensure non-blocking UI operations. - Async/await should be used where applicable to ensure non-blocking UI operations.
@ -16,16 +18,16 @@ appliesTo: "**/*.xaml, **/*.cs"
- Use camelCase for private fields and local variables. - Use camelCase for private fields and local variables.
- Prefix interface names with "I" (e.g., IUserService). - Prefix interface names with "I" (e.g., IUserService).
## MAUI and .NET Specific Guidelines ## .NET MAUI and .NET Specific Guidelines
- Utilize MAUI's built-in features for component lifecycle (e.g. OnAppearing, OnDisappearing). - Utilize .NET MAUI's built-in features for component lifecycle (e.g. OnAppearing, OnDisappearing).
- Use data binding effectively with {Binding}. - Use data binding effectively with {Binding}.
- Structure MAUI components and services following Separation of Concerns. - Structure .NET MAUI components and services following Separation of Concerns.
- Always use the latest version C#, currently C# 13 features like record types, pattern matching, and global usings. - Always use the latest version C#, currently C# 13 features like record types, pattern matching, and global usings.
## Error Handling and Validation ## Error Handling and Validation
- Implement proper error handling for MAUI pages and API calls. - Implement proper error handling for .NET MAUI pages and API calls.
- Use logging for error tracking in the backend and consider capturing UI-level errors in MAUI with tools like MAUI Community Toolkit's Logger. - Use logging for error tracking in the backend and consider capturing UI-level errors in MAUI with tools like MAUI Community Toolkit's Logger.
- Implement validation using FluentValidation or DataAnnotations in forms. - Implement validation using FluentValidation or DataAnnotations in forms.

View File

@ -1,6 +1,6 @@
--- ---
applyTo: "**/*.genai.*" description: 'AI-powered script generation guidelines'
description: AI-powered script generation guidelines applyTo: '**/*.genai.*'
--- ---
## Role ## Role

View File

@ -1,6 +1,6 @@
--- ---
description: Guidelines for generating modern Terraform code for Azure description: 'Guidelines for generating modern Terraform code for Azure'
applyTo: "**/*.tf" applyTo: '**/*.tf'
--- ---
## 1. Use Latest Terraform and Providers ## 1. Use Latest Terraform and Providers

View File

@ -1,6 +1,6 @@
--- ---
description: Guidelines for localizing markdown documents description: 'Guidelines for localizing markdown documents'
applyTo: "**/*.md" applyTo: '**/*.md'
--- ---
# Guidance for Localization # Guidance for Localization

View File

@ -1,6 +1,6 @@
--- ---
description: Documentation and content creation standards description: 'Documentation and content creation standards'
applyTo: "**/*.md" applyTo: '**/*.md'
--- ---
## Markdown Content Rules ## Markdown Content Rules

View File

@ -1,5 +1,6 @@
--- ---
description: Next.js + Tailwind development standards and instructions description: 'Next.js + Tailwind development standards and instructions'
applyTo: '**/*.tsx, **/*.ts, **/*.jsx, **/*.js, **/*.css'
--- ---
# Next.js + Tailwind Development Instructions # Next.js + Tailwind Development Instructions

View File

@ -1,5 +1,6 @@
--- ---
description: Python coding conventions and guidelines description: 'Python coding conventions and guidelines'
applyTo: '**/*.py'
--- ---
# Python Coding Conventions # Python Coding Conventions

View File

@ -1,9 +1,11 @@
--- ---
mode: "agent" mode: 'agent'
tools: ["changes", "codebase", "editFiles", "problems"] tools: ['changes', 'codebase', 'editFiles', 'problems']
description: "Create ASP.NET Minimal API endpoints with proper OpenAPI documentation" description: 'Create ASP.NET Minimal API endpoints with proper OpenAPI documentation'
--- ---
# ASP.NET Minimal API with OpenAPI
Your goal is to help me create well-structured ASP.NET Minimal API endpoints with correct types and comprehensive OpenAPI/Swagger documentation. Your goal is to help me create well-structured ASP.NET Minimal API endpoints with correct types and comprehensive OpenAPI/Swagger documentation.
## API Organization ## API Organization

View File

@ -1,9 +1,10 @@
--- ---
mode: agent mode: 'agent'
description: Analyze Azure resources used in the app (IaC files and/or resources in a target rg) and optimize costs - creating GitHub issues for identified optimizations. description: 'Analyze Azure resources used in the app (IaC files and/or resources in a target rg) and optimize costs - creating GitHub issues for identified optimizations.'
--- ---
## Overview # Azure Cost Optimize
This workflow analyzes Infrastructure-as-Code (IaC) files and Azure resources to generate cost optimization recommendations. It creates individual GitHub issues for each optimization opportunity plus one EPIC issue to coordinate implementation, enabling efficient tracking and execution of cost savings initiatives. This workflow analyzes Infrastructure-as-Code (IaC) files and Azure resources to generate cost optimization recommendations. It creates individual GitHub issues for each optimization opportunity plus one EPIC issue to coordinate implementation, enabling efficient tracking and execution of cost savings initiatives.
## Prerequisites ## Prerequisites

View File

@ -1,3 +1,7 @@
---
description: 'Transform this Python script into a polished, beginner-friendly project by refactoring the code, adding clear instructional comments, and generating a complete markdown tutorial.'
---
Transform this Python script into a polished, beginner-friendly project by refactoring the code, adding clear instructional comments, and generating a complete markdown tutorial. Transform this Python script into a polished, beginner-friendly project by refactoring the code, adding clear instructional comments, and generating a complete markdown tutorial.
1. **Refactor the code** 1. **Refactor the code**

View File

@ -1,7 +1,7 @@
--- ---
mode: "agent" mode: 'agent'
tools: ["changes", "codebase", "editFiles", "problems"] tools: ['changes', 'codebase', 'editFiles', 'problems']
description: "Get best practices for C# async programming" description: 'Get best practices for C# async programming'
--- ---
# C# Async Programming Best Practices # C# Async Programming Best Practices

View File

@ -1,7 +1,7 @@
--- ---
mode: "agent" mode: 'agent'
tools: ["changes", "codebase", "editFiles", "problems"] tools: ['changes', 'codebase', 'editFiles', 'problems']
description: "Ensure that C# types are documented with XML comments and follow best practices for documentation." description: 'Ensure that C# types are documented with XML comments and follow best practices for documentation.'
--- ---
# C# Documentation Best Practices # C# Documentation Best Practices

View File

@ -1,7 +1,7 @@
--- ---
mode: "agent" mode: 'agent'
tools: ["changes", "codebase", "editFiles", "problems", "search"] tools: ['changes', 'codebase', 'editFiles', 'problems', 'search']
description: "Get best practices for MSTest unit testing, including data-driven tests" description: 'Get best practices for MSTest unit testing, including data-driven tests'
--- ---
# MSTest Best Practices # MSTest Best Practices

View File

@ -1,7 +1,7 @@
--- ---
mode: "agent" mode: 'agent'
tools: ["changes", "codebase", "editFiles", "problems", "search"] tools: ['changes', 'codebase', 'editFiles', 'problems', 'search']
description: "Get best practices for NUnit unit testing, including data-driven tests" description: 'Get best practices for NUnit unit testing, including data-driven tests'
--- ---
# NUnit Best Practices # NUnit Best Practices

View File

@ -1,7 +1,7 @@
--- ---
mode: "agent" mode: 'agent'
tools: ["changes", "codebase", "editFiles", "problems", "search"] tools: ['changes', 'codebase', 'editFiles', 'problems', 'search']
description: "Get best practices for XUnit unit testing, including data-driven tests" description: 'Get best practices for XUnit unit testing, including data-driven tests'
--- ---
# XUnit Best Practices # XUnit Best Practices

View File

@ -1,7 +1,7 @@
--- ---
mode: "agent" mode: 'agent'
tools: ["changes", "codebase", "editFiles", "problems", "runCommands"] tools: ['changes', 'codebase', 'editFiles', 'problems', 'runCommands']
description: "Get best practices for Entity Framework Core" description: 'Get best practices for Entity Framework Core'
--- ---
# Entity Framework Core Best Practices # Entity Framework Core Best Practices

View File

@ -1,3 +1,7 @@
---
description: 'This workflow guides you through a systematic approach to identify missing features, prioritize them, and create detailed specifications for implementation.'
---
# Product Manager Assistant: Feature Identification and Specification # Product Manager Assistant: Feature Identification and Specification
This workflow guides you through a systematic approach to identify missing features, prioritize them, and create detailed specifications for implementation. This workflow guides you through a systematic approach to identify missing features, prioritize them, and create detailed specifications for implementation.

View File

@ -1,5 +1,5 @@
--- ---
description: "Best practices for writing JavaScript/TypeScript tests using Jest, including mocking strategies, test structure, and common patterns." description: 'Best practices for writing JavaScript/TypeScript tests using Jest, including mocking strategies, test structure, and common patterns.'
--- ---
### Test Structure ### Test Structure

View File

@ -1,7 +1,7 @@
--- ---
mode: "agent" mode: 'agent'
tools: ["codebase"] tools: ['codebase']
description: "Create optimized multi-stage Dockerfiles for any language or framework" description: 'Create optimized multi-stage Dockerfiles for any language or framework'
--- ---
Your goal is to help me create efficient multi-stage Dockerfiles that follow best practices, resulting in smaller, more secure container images. Your goal is to help me create efficient multi-stage Dockerfiles that follow best practices, resulting in smaller, more secure container images.

View File

@ -1,7 +1,7 @@
--- ---
mode: agent mode: 'agent'
tools: ['githubRepo', 'github', 'get_issue', 'get_issue_comments', 'get_me', 'list_issues'] tools: ['githubRepo', 'github', 'get_issue', 'get_issue_comments', 'get_me', 'list_issues']
description: "List my issues in the current repository" description: 'List my issues in the current repository'
--- ---
Search the current repo (using #githubRepo for the repo info) and list any issues you find (using #list_issues) that are assigned to me. Search the current repo (using #githubRepo for the repo info) and list any issues you find (using #list_issues) that are assigned to me.

View File

@ -1,7 +1,7 @@
--- ---
mode: agent mode: 'agent'
tools: ['githubRepo', 'github', 'get_me', 'get_pull_request', 'get_pull_request_comments', 'get_pull_request_diff', 'get_pull_request_files', 'get_pull_request_reviews', 'get_pull_request_status', 'list_pull_requests', 'request_copilot_review'] tools: ['githubRepo', 'github', 'get_me', 'get_pull_request', 'get_pull_request_comments', 'get_pull_request_diff', 'get_pull_request_files', 'get_pull_request_reviews', 'get_pull_request_status', 'list_pull_requests', 'request_copilot_review']
description: "List my pull requests in the current repository" description: 'List my pull requests in the current repository'
--- ---
Search the current repo (using #githubRepo for the repo info) and list any pull requests you find (using #list_pull_requests) that are assigned to me. Search the current repo (using #githubRepo for the repo info) and list any pull requests you find (using #list_pull_requests) that are assigned to me.

View File

@ -3,8 +3,83 @@
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
function extractTitle(filePath) { // Template sections for the README
const TEMPLATES = {
header: `# 🤖 Awesome GitHub Copilot Customizations
Enhance your GitHub Copilot experience with community-contributed instructions, prompts, and configurations. Get consistent AI assistance that follows your team's coding standards and project requirements.
## 🎯 GitHub Copilot Customization Features
GitHub Copilot provides three main ways to customize AI responses and tailor assistance to your specific workflows, team guidelines, and project requirements:
| **🔧 Custom Instructions** | **📝 Reusable Prompts** | **🧩 Custom Chat Modes** |
| --- | --- | --- |
| Define common guidelines for tasks like code generation, reviews, and commit messages. Describe *how* tasks should be performed<br><br>**Benefits:**<br> Automatic inclusion in every chat request<br> Repository-wide consistency<br> Multiple implementation options | Create reusable, standalone prompts for specific tasks. Describe *what* should be done with optional task-specific guidelines<br><br>**Benefits:**<br> Eliminate repetitive prompt writing<br> Shareable across teams<br> Support for variables and dependencies | Define chat behavior, available tools, and codebase interaction patterns within specific boundaries for each request<br><br>**Benefits:**<br> Context-aware assistance<br> Tool configuration<br> Role-specific workflows |
> **💡 Pro Tip:** Custom instructions only affect Copilot Chat (not inline code completions). You can combine all three customization types - use custom instructions for general guidelines, prompt files for specific tasks, and chat modes to control the interaction context.
## 📝 Contributing
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details on how to submit new instructions and prompts.`,
instructionsSection: `## 📋 Custom Instructions
Team and project-specific instructions to enhance GitHub Copilot's behavior for specific technologies and coding practices:`,
instructionsUsage: `> 💡 **Usage**: Copy these instructions to your \`.github/copilot-instructions.md\` file or create task-specific \`.github/.instructions.md\` files in your workspace's \`.github/instructions\` folder.`,
promptsSection: `## 🎯 Reusable Prompts
Ready-to-use prompt templates for specific development scenarios and tasks, defining prompt text with a specific mode, model, and available set of tools.`,
promptsUsage: `> 💡 **Usage**: Use \`/prompt-name\` in VS Code chat, run \`Chat: Run Prompt\` command, or hit the run button while you have a prompt open.`,
chatmodesSection: `## 🧩 Custom Chat Modes
Custom chat modes define specific behaviors and tools for GitHub Copilot Chat, enabling enhanced context-aware assistance for particular tasks or workflows.`,
chatmodesUsage: `> 💡 **Usage**: Create new chat modes using the command \`Chat: Configure Chat Modes...\`, then switch your chat mode in the Chat input from _Agent_ or _Ask_ to your own mode.`,
footer: `## 📚 Additional Resources
- [VS Code Copilot Customization Documentation](https://code.visualstudio.com/docs/copilot/copilot-customization) - Official Microsoft documentation
- [GitHub Copilot Chat Documentation](https://code.visualstudio.com/docs/copilot/chat/copilot-chat) - Complete chat feature guide
- [Custom Chat Modes](https://code.visualstudio.com/docs/copilot/chat/chat-modes) - Advanced chat configuration
- [VS Code Settings](https://code.visualstudio.com/docs/getstarted/settings) - General VS Code configuration guide
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🤝 Code of Conduct
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.`,
};
// Add error handling utility
function safeFileOperation(operation, filePath, defaultValue = null) {
try { try {
return operation();
} catch (error) {
console.error(`Error processing file ${filePath}: ${error.message}`);
return defaultValue;
}
}
function extractTitle(filePath) {
return safeFileOperation(
() => {
const content = fs.readFileSync(filePath, "utf8"); const content = fs.readFileSync(filePath, "utf8");
const lines = content.split("\n"); const lines = content.split("\n");
@ -24,9 +99,14 @@ function extractTitle(filePath) {
if (inFrontmatter && !frontmatterEnded) { if (inFrontmatter && !frontmatterEnded) {
// Look for title field in frontmatter // Look for title field in frontmatter
const titleMatch = line.match(/^title:\s*['"]?(.+?)['"]?$/); if (line.includes("title:")) {
if (titleMatch) { // Extract everything after 'title:'
return titleMatch[1].trim(); const afterTitle = line
.substring(line.indexOf("title:") + 6)
.trim();
// Remove quotes if present
const cleanTitle = afterTitle.replace(/^['"]|['"]$/g, "");
return cleanTitle;
} }
} }
} }
@ -35,8 +115,12 @@ function extractTitle(filePath) {
inFrontmatter = false; inFrontmatter = false;
frontmatterEnded = false; frontmatterEnded = false;
// Step 2: For prompt/chatmode files, look for heading after frontmatter // Step 2: For prompt/chatmode/instructions files, look for heading after frontmatter
if (filePath.includes(".prompt.md") || filePath.includes(".chatmode.md")) { if (
filePath.includes(".prompt.md") ||
filePath.includes(".chatmode.md") ||
filePath.includes(".instructions.md")
) {
for (const line of lines) { for (const line of lines) {
if (line.trim() === "---") { if (line.trim() === "---") {
if (!inFrontmatter) { if (!inFrontmatter) {
@ -52,10 +136,14 @@ function extractTitle(filePath) {
} }
} }
// Step 3: Format filename for prompt/chatmode files if no heading found // Step 3: Format filename for prompt/chatmode/instructions files if no heading found
const basename = path.basename( const basename = path.basename(
filePath, filePath,
filePath.includes(".prompt.md") ? ".prompt.md" : ".chatmode.md" filePath.includes(".prompt.md")
? ".prompt.md"
: filePath.includes(".chatmode.md")
? ".chatmode.md"
: ".instructions.md"
); );
return basename return basename
.replace(/[-_]/g, " ") .replace(/[-_]/g, " ")
@ -74,17 +162,18 @@ function extractTitle(filePath) {
return basename return basename
.replace(/[-_]/g, " ") .replace(/[-_]/g, " ")
.replace(/\b\w/g, (l) => l.toUpperCase()); .replace(/\b\w/g, (l) => l.toUpperCase());
} catch (error) { },
// Fallback to filename filePath,
const basename = path.basename(filePath, path.extname(filePath)); path
return basename .basename(filePath, path.extname(filePath))
.replace(/[-_]/g, " ") .replace(/[-_]/g, " ")
.replace(/\b\w/g, (l) => l.toUpperCase()); .replace(/\b\w/g, (l) => l.toUpperCase())
} );
} }
function extractDescription(filePath) { function extractDescription(filePath) {
try { return safeFileOperation(
() => {
const content = fs.readFileSync(filePath, "utf8"); const content = fs.readFileSync(filePath, "utf8");
// Parse frontmatter for description (for both prompts and instructions) // Parse frontmatter for description (for both prompts and instructions)
@ -147,47 +236,27 @@ function extractDescription(filePath) {
} }
return null; return null;
} catch (error) { },
return null; filePath,
} null
);
} }
function updateInstructionsSection( /**
currentReadme, * Generate the instructions section with an alphabetical list of all instructions
instructionFiles, */
instructionsDir function generateInstructionsSection(instructionsDir) {
) { // Get all instruction files
const instructionsSection = currentReadme.match( const instructionFiles = fs
/## 📋 Custom Instructions\n\nTeam and project-specific instructions.+?(?=\n\n>)/s .readdirSync(instructionsDir)
); .filter((file) => file.endsWith(".md"))
.sort();
if (!instructionsSection) { console.log(`Found ${instructionFiles.length} instruction files`);
return currentReadme;
}
// Extract existing instruction links from README let instructionsContent = "";
const existingInstructionLinks = [];
const instructionLinkRegex = /\[.*?\]\(instructions\/(.+?)\)/g;
let match;
while ((match = instructionLinkRegex.exec(currentReadme)) !== null) { // Generate list items for each instruction file
existingInstructionLinks.push(match[1]);
}
// Find new instructions that aren't already in the README
const newInstructionFiles = instructionFiles.filter(
(file) => !existingInstructionLinks.includes(file)
);
if (newInstructionFiles.length === 0) {
console.log("No new instructions to add.");
} else {
console.log(`Found ${newInstructionFiles.length} new instructions to add.`);
}
let instructionsListContent = "\n\n";
// Generate alphabetically sorted list of instruction links
for (const file of instructionFiles) { for (const file of instructionFiles) {
const filePath = path.join(instructionsDir, file); const filePath = path.join(instructionsDir, file);
const title = extractTitle(filePath); const title = extractTitle(filePath);
@ -196,209 +265,78 @@ function updateInstructionsSection(
// Check if there's a description in the frontmatter // Check if there's a description in the frontmatter
const customDescription = extractDescription(filePath); const customDescription = extractDescription(filePath);
if (customDescription) { if (customDescription && customDescription !== "null") {
// Use the description from frontmatter // Use the description from frontmatter
instructionsListContent += `- [${title}](${link}) - ${customDescription}\n`; instructionsContent += `- [${title}](${link}) - ${customDescription}\n`;
} else { } else {
// Fallback to the default approach - use last word of title for description, removing trailing 's' if present // Fallback to the default approach - use last word of title for description, removing trailing 's' if present
const topic = title.split(" ").pop().replace(/s$/, ""); const topic = title.split(" ").pop().replace(/s$/, "");
instructionsListContent += `- [${title}](${link}) - ${topic} specific coding standards and best practices\n`; instructionsContent += `- [${title}](${link}) - ${topic} specific coding standards and best practices\n`;
} }
} }
// Replace the current instructions section with the updated one return `${TEMPLATES.instructionsSection}\n\n${instructionsContent}\n${TEMPLATES.instructionsUsage}`;
const newInstructionsSection =
"## 📋 Custom Instructions\n\nTeam and project-specific instructions to enhance GitHub Copilot's behavior for specific technologies and coding practices:" +
instructionsListContent;
return currentReadme.replace(instructionsSection[0], newInstructionsSection);
} }
function updatePromptsSection(currentReadme, promptFiles, promptsDir) { /**
// Extract existing prompt links from README * Generate the prompts section with an alphabetical list of all prompts
const existingPromptLinks = []; */
const promptLinkRegex = /\[.*?\]\(prompts\/(.+?)\)/g; function generatePromptsSection(promptsDir) {
let match; // Get all prompt files
const promptFiles = fs
.readdirSync(promptsDir)
.filter((file) => file.endsWith(".prompt.md"))
.sort();
while ((match = promptLinkRegex.exec(currentReadme)) !== null) { console.log(`Found ${promptFiles.length} prompt files`);
existingPromptLinks.push(match[1]);
}
// Find new prompts that aren't already in the README let promptsContent = "";
const newPromptFiles = promptFiles.filter(
(file) => !existingPromptLinks.includes(file)
);
if (newPromptFiles.length === 0) { // Generate list items for each prompt file
console.log("No new prompts to add."); for (const file of promptFiles) {
return currentReadme;
}
console.log(`Found ${newPromptFiles.length} new prompts to add.`);
// Create content for new prompts (in Uncategorised section)
let newPromptsContent = "";
// Check if we already have an Uncategorised section
const uncategorisedSectionRegex = /### Uncategorised\n/;
const hasUncategorisedSection = uncategorisedSectionRegex.test(currentReadme);
// If we need to add the section header
if (!hasUncategorisedSection) {
newPromptsContent += "### Uncategorised\n";
}
// Add each new prompt
for (const file of newPromptFiles) {
const filePath = path.join(promptsDir, file); const filePath = path.join(promptsDir, file);
const title = extractTitle(filePath); const title = extractTitle(filePath);
const description = extractDescription(filePath);
const link = encodeURI(`prompts/${file}`); const link = encodeURI(`prompts/${file}`);
if (description) { // Check if there's a description in the frontmatter
newPromptsContent += `- [${title}](${link}) - ${description}\n`; const customDescription = extractDescription(filePath);
if (customDescription && customDescription !== "null") {
promptsContent += `- [${title}](${link}) - ${customDescription}\n`;
} else { } else {
newPromptsContent += `- [${title}](${link})\n`; promptsContent += `- [${title}](${link})\n`;
} }
} }
// Add a newline if we created a new section return `${TEMPLATES.promptsSection}\n\n${promptsContent}\n${TEMPLATES.promptsUsage}`;
if (!hasUncategorisedSection) {
newPromptsContent += "\n";
}
// Update the README content - insert new content in the right place
if (hasUncategorisedSection) {
// Add to existing Uncategorised section
const uncategorisedSectionPos = currentReadme.match(
uncategorisedSectionRegex
).index;
const sectionEndRegex = /\n\n/;
let sectionEndMatch = sectionEndRegex.exec(
currentReadme.slice(uncategorisedSectionPos + 16)
); // 16 is length of "### Uncategorised\n"
let insertPos;
if (sectionEndMatch) {
insertPos = uncategorisedSectionPos + 16 + sectionEndMatch.index;
} else {
// If we can't find the end of the section, just insert at the end of the section header
insertPos = uncategorisedSectionPos + 16;
}
return (
currentReadme.slice(0, insertPos) +
newPromptsContent +
currentReadme.slice(insertPos)
);
} else {
// No Uncategorised section exists yet - find where to add it
return addNewUncategorisedSection(currentReadme, newPromptsContent);
}
} }
function addNewUncategorisedSection(currentReadme, newPromptsContent) { /**
// Look for the "Ready-to-use prompt templates" section and the next section after it * Generate the chat modes section with an alphabetical list of all chat modes
const promptSectionRegex = */
/## 🎯 Reusable Prompts\n\nReady-to-use prompt templates/; function generateChatModesSection(chatmodesDir) {
const promptSectionMatch = currentReadme.match(promptSectionRegex); // Check if chatmodes directory exists
if (!fs.existsSync(chatmodesDir)) {
if (!promptSectionMatch) { console.log("Chat modes directory does not exist");
console.error("Could not find the Reusable Prompts section in the README."); return "";
return currentReadme;
} }
// Find where to insert the new section - after any existing categories // Get all chat mode files
let insertPos; const chatmodeFiles = fs
// First check if there are any existing categories .readdirSync(chatmodesDir)
const existingCategoriesRegex = /### [^\n]+\n/g; .filter((file) => file.endsWith(".chatmode.md"))
let lastCategoryMatch = null; .sort();
let match;
while ((match = existingCategoriesRegex.exec(currentReadme)) !== null) { console.log(`Found ${chatmodeFiles.length} chat mode files`);
lastCategoryMatch = match;
}
if (lastCategoryMatch) { // If no chat modes, return empty string
// Find the end of the last category section
const afterLastCategory = currentReadme.slice(
lastCategoryMatch.index + lastCategoryMatch[0].length
);
const nextSectionRegex = /\n\n>/;
const nextSectionMatch = afterLastCategory.match(nextSectionRegex);
if (nextSectionMatch) {
insertPos =
lastCategoryMatch.index +
lastCategoryMatch[0].length +
nextSectionMatch.index;
} else {
// If we can't find the next section, add at the end of the prompt section
insertPos = currentReadme.indexOf("> 💡 **Usage**: Use `/prompt-name`");
if (insertPos === -1) {
// Fallback position - before Additional Resources
insertPos = currentReadme.indexOf("## 📚 Additional Resources");
}
}
} else {
// No categories yet, add right after the intro text
const afterIntroRegex = /prompt\` command\.\n\n/;
const afterIntroMatch = currentReadme.match(afterIntroRegex);
if (afterIntroMatch) {
insertPos = afterIntroMatch.index + afterIntroMatch[0].length;
} else {
// Fallback position - before Additional Resources
insertPos = currentReadme.indexOf("## 📚 Additional Resources");
}
}
if (insertPos !== -1) {
return (
currentReadme.slice(0, insertPos) +
newPromptsContent +
currentReadme.slice(insertPos)
);
} else {
console.error("Could not find a suitable place to insert new prompts.");
return currentReadme;
}
}
function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) {
// No chat mode files, nothing to do
if (chatmodeFiles.length === 0) { if (chatmodeFiles.length === 0) {
return currentReadme; return "";
} }
// Extract existing chat mode links from README let chatmodesContent = "";
const existingChatModeLinks = [];
const chatModeLinkRegex = /\[.*?\]\(chatmodes\/(.+?)\)/g;
let match;
while ((match = chatModeLinkRegex.exec(currentReadme)) !== null) { // Generate list items for each chat mode file
existingChatModeLinks.push(match[1]);
}
// Find new chat modes that aren't already in the README
const newChatModeFiles = chatmodeFiles.filter(
(file) => !existingChatModeLinks.includes(file)
);
if (newChatModeFiles.length === 0) {
console.log("No new chat modes to add.");
} else {
console.log(`Found ${newChatModeFiles.length} new chat modes to add.`);
}
const chatmodesSection = currentReadme.match(
/## 🧩 Custom Chat Modes\n\nCustom chat modes define.+?(?=\n\n>)/s
);
if (chatmodesSection) {
let chatmodesListContent = "\n\n";
// Generate list of chat mode links
for (const file of chatmodeFiles) { for (const file of chatmodeFiles) {
const filePath = path.join(chatmodesDir, file); const filePath = path.join(chatmodesDir, file);
const title = extractTitle(filePath); const title = extractTitle(filePath);
@ -407,7 +345,28 @@ function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) {
// Check if there's a description in the frontmatter // Check if there's a description in the frontmatter
const customDescription = extractDescription(filePath); const customDescription = extractDescription(filePath);
if (customDescription) { if (customDescription && customDescription !== "null") {
chatmodesContent += `- [${title}](${link}) - ${customDescription}\n`;
} else {
chatmodesContent += `- [${title}](${link})\n`;
}
}
return `${TEMPLATES.chatmodesSection}\n\n${chatmodesContent}\n${TEMPLATES.chatmodesUsage}`;
if (chatmodesSection) {
let chatmodesListContent = "\n\n";
// Always regenerate the entire list to ensure descriptions are included
for (const file of chatmodeFiles.sort()) {
const filePath = path.join(chatmodesDir, file);
const title = extractTitle(filePath);
const link = encodeURI(`chatmodes/${file}`);
// Check if there's a description in the frontmatter
const customDescription = extractDescription(filePath);
if (customDescription && customDescription !== "null") {
// Use the description from frontmatter // Use the description from frontmatter
chatmodesListContent += `- [${title}](${link}) - ${customDescription}\n`; chatmodesListContent += `- [${title}](${link}) - ${customDescription}\n`;
} else { } else {
@ -419,7 +378,8 @@ function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) {
// Replace the current chat modes section with the updated one // Replace the current chat modes section with the updated one
const newChatmodesSection = const newChatmodesSection =
"## 🧩 Custom Chat Modes\n\nCustom chat modes define specific behaviors and tools for GitHub Copilot Chat, enabling enhanced context-aware assistance for particular tasks or workflows." + "## 🧩 Custom Chat Modes\n\nCustom chat modes define specific behaviors and tools for GitHub Copilot Chat, enabling enhanced context-aware assistance for particular tasks or workflows." +
chatmodesListContent; chatmodesListContent +
"\n> 💡 **Usage**: Create new chat modes using the command `Chat: Configure Chat Modes...`, then switch your chat mode in the Chat input from _Agent_ or _Ask_ to your own mode.";
return currentReadme.replace(chatmodesSection[0], newChatmodesSection); return currentReadme.replace(chatmodesSection[0], newChatmodesSection);
} else { } else {
@ -429,6 +389,7 @@ function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) {
); );
const chatmodesListContent = chatmodeFiles const chatmodesListContent = chatmodeFiles
.sort()
.map((file) => { .map((file) => {
const filePath = path.join(chatmodesDir, file); const filePath = path.join(chatmodesDir, file);
const title = extractTitle(filePath); const title = extractTitle(filePath);
@ -444,7 +405,7 @@ function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) {
.join("\n"); .join("\n");
const newChatmodesSection = const newChatmodesSection =
"## 🎭 Custom Chat Modes\n\n" + "## 🧩 Custom Chat Modes\n\n" +
"Custom chat modes define specific behaviors and tools for GitHub Copilot Chat, enabling enhanced context-aware assistance for particular tasks or workflows.\n\n" + "Custom chat modes define specific behaviors and tools for GitHub Copilot Chat, enabling enhanced context-aware assistance for particular tasks or workflows.\n\n" +
chatmodesListContent + chatmodesListContent +
"\n\n> 💡 **Usage**: Create new chat modes using the command `Chat: Configure Chat Modes...`, then switch your chat mode in the Chat input from _Agent_ or _Ask_ to your own mode.\n"; "\n\n> 💡 **Usage**: Create new chat modes using the command `Chat: Configure Chat Modes...`, then switch your chat mode in the Chat input from _Agent_ or _Ask_ to your own mode.\n";
@ -466,68 +427,57 @@ function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) {
} }
} }
/**
* Generate the complete README.md content from scratch
*/
function generateReadme() { function generateReadme() {
const instructionsDir = path.join(__dirname, "instructions"); const instructionsDir = path.join(__dirname, "instructions");
const promptsDir = path.join(__dirname, "prompts"); const promptsDir = path.join(__dirname, "prompts");
const chatmodesDir = path.join(__dirname, "chatmodes"); const chatmodesDir = path.join(__dirname, "chatmodes");
const readmePath = path.join(__dirname, "README.md");
// Check if README file exists // Generate each section
if (!fs.existsSync(readmePath)) { const instructionsSection = generateInstructionsSection(instructionsDir);
console.error( const promptsSection = generatePromptsSection(promptsDir);
"README.md not found! Please create a base README.md file first." const chatmodesSection = generateChatModesSection(chatmodesDir);
);
process.exit(1); // Build the complete README content with template sections
let readmeContent = [TEMPLATES.header, instructionsSection, promptsSection];
// Only include chat modes section if we have any chat modes
if (chatmodesSection) {
readmeContent.push(chatmodesSection);
} }
// Read the current README content // Add footer
let currentReadme = fs.readFileSync(readmePath, "utf8"); readmeContent.push(TEMPLATES.footer);
// Get all instruction files return readmeContent.join("\n\n");
const instructionFiles = fs
.readdirSync(instructionsDir)
.filter((file) => file.endsWith(".md"))
.sort();
// Get all prompt files - we'll use this to find new prompts
const promptFiles = fs
.readdirSync(promptsDir)
.filter((file) => file.endsWith(".prompt.md"))
.sort();
// Get all chat mode files - we'll use this to update the chat modes section
const chatmodeFiles = fs.existsSync(chatmodesDir)
? fs
.readdirSync(chatmodesDir)
.filter((file) => file.endsWith(".chatmode.md"))
.sort()
: [];
// Update instructions section
currentReadme = updateInstructionsSection(
currentReadme,
instructionFiles,
instructionsDir
);
// Update prompts section
currentReadme = updatePromptsSection(currentReadme, promptFiles, promptsDir);
// Update chat modes section
currentReadme = updateChatModesSection(
currentReadme,
chatmodeFiles,
chatmodesDir
);
return currentReadme;
} }
// Generate and write the README // Main execution
const updatedReadme = generateReadme(); try {
console.log("Generating README.md from scratch...");
// Only write file if we have content to write const readmePath = path.join(__dirname, "README.md");
if (updatedReadme) { const newReadmeContent = generateReadme();
fs.writeFileSync(path.join(__dirname, "README.md"), updatedReadme);
// Check if the README file already exists
if (fs.existsSync(readmePath)) {
const originalContent = fs.readFileSync(readmePath, "utf8");
const hasChanges = originalContent !== newReadmeContent;
if (hasChanges) {
fs.writeFileSync(readmePath, newReadmeContent);
console.log("README.md updated successfully!"); console.log("README.md updated successfully!");
} else {
console.log("README.md is already up to date. No changes needed.");
}
} else {
// Create the README file if it doesn't exist
fs.writeFileSync(readmePath, newReadmeContent);
console.log("README.md created successfully!");
}
} catch (error) {
console.error(`Error generating README.md: ${error.message}`);
process.exit(1);
} }