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:
parent
d1256681e7
commit
6fb794bc79
@ -71,4 +71,4 @@ This Code of Conduct is adapted from the [Contributor Covenant][homepage], versi
|
|||||||
available at [http://contributor-covenant.org/version/1/4][version]
|
available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
[homepage]: http://contributor-covenant.org
|
[homepage]: http://contributor-covenant.org
|
||||||
[version]: http://contributor-covenant.org/version/1/4/
|
[version]: http://contributor-covenant.org/version/1/4/
|
||||||
|
|||||||
@ -82,4 +82,4 @@ Please note that this project is released with a [Contributor Code of Conduct](C
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
By contributing to this repository, you agree that your contributions will be licensed under the MIT License.
|
By contributing to this repository, you agree that your contributions will be licensed under the MIT License.
|
||||||
|
|||||||
67
README.md
67
README.md
@ -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
|
||||||
@ -103,4 +94,4 @@ This project may contain trademarks or logos for projects, products, or services
|
|||||||
trademarks or logos is subject to and must follow
|
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).
|
[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.
|
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.
|
Any use of third-party trademarks or logos are subject to those third-party's policies.
|
||||||
@ -28,4 +28,4 @@ This information will help us triage your report more quickly.
|
|||||||
|
|
||||||
## Policy
|
## Policy
|
||||||
|
|
||||||
See [GitHub's Safe Harbor Policy](https://docs.github.com/en/site-policy/security-policies/github-bug-bounty-program-legal-safe-harbor#1-safe-harbor-terms)
|
See [GitHub's Safe Harbor Policy](https://docs.github.com/en/site-policy/security-policies/github-bug-bounty-program-legal-safe-harbor#1-safe-harbor-terms)
|
||||||
|
|||||||
@ -12,4 +12,4 @@ Please include one of the following statements file:
|
|||||||
-
|
-
|
||||||
## GitHub Support Policy
|
## GitHub Support Policy
|
||||||
|
|
||||||
Support for this project is limited to the resources listed above.
|
Support for this project is limited to the resources listed above.
|
||||||
|
|||||||
@ -133,4 +133,4 @@ I'm now checking to ensure that these changes will correctly update the UI when
|
|||||||
4. Reuse previous context unless something has changed.
|
4. Reuse previous context unless something has changed.
|
||||||
5. If redoing work, explain briefly *why* it’s necessary and proceed.
|
5. If redoing work, explain briefly *why* it’s necessary and proceed.
|
||||||
|
|
||||||
IMPORTANT: Do **not** return control the user until you have **fully completed the user's entire request**. All items in your todo list MUST be checked off. Failure to do so will result in a bad rating for you.
|
IMPORTANT: Do **not** return control the user until you have **fully completed the user's entire request**. All items in your todo list MUST be checked off. Failure to do so will result in a bad rating for you.
|
||||||
|
|||||||
@ -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']
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
@ -11,4 +11,4 @@ The plan consists of a Markdown document that describes the implementation plan,
|
|||||||
* Overview: A brief description of the feature or refactoring task.
|
* Overview: A brief description of the feature or refactoring task.
|
||||||
* Requirements: A list of requirements for the feature or refactoring task.
|
* Requirements: A list of requirements for the feature or refactoring task.
|
||||||
* Implementation Steps: A detailed list of steps to implement the feature or refactoring task.
|
* Implementation Steps: A detailed list of steps to implement the feature or refactoring task.
|
||||||
* Testing: A list of tests that need to be implemented to verify the feature or refactoring task.
|
* Testing: A list of tests that need to be implemented to verify the feature or refactoring task.
|
||||||
|
|||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -10,4 +11,4 @@ description: TypeScript patterns for Azure Functions
|
|||||||
- Ask before adding any extra dependencies to the project
|
- Ask before adding any extra dependencies to the project
|
||||||
- The API is built using Azure Functions using `@azure/functions@4` package.
|
- The API is built using Azure Functions using `@azure/functions@4` package.
|
||||||
- Each endpoint should have its own function file, and use the following naming convention: `src/functions/<resource-name>-<http-verb>.ts`
|
- Each endpoint should have its own function file, and use the following naming convention: `src/functions/<resource-name>-<http-verb>.ts`
|
||||||
- When making changes to the API, make sure to update the OpenAPI schema (if it exists) and `README.md` file accordingly.
|
- When making changes to the API, make sure to update the OpenAPI schema (if it exists) and `README.md` file accordingly.
|
||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: Infrastructure as Code with Bicep
|
description: 'Infrastructure as Code with Bicep'
|
||||||
applyTo: "**/*.bicep"
|
applyTo: '**/*.bicep'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Naming Conventions
|
## Naming Conventions
|
||||||
@ -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
|
||||||
@ -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.
|
||||||
@ -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'
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -60,4 +59,4 @@ description: 'See process Copilot is following where you can edit this to reshap
|
|||||||
- NEVER continue past current phase without user input
|
- NEVER continue past current phase without user input
|
||||||
- If you catch yourself being verbose, STOP and provide only required output
|
- If you catch yourself being verbose, STOP and provide only required output
|
||||||
- If you catch yourself about to skip a phase, STOP and go back to the correct phase
|
- If you catch yourself about to skip a phase, STOP and go back to the correct phase
|
||||||
- If you catch yourself combining phases, STOP and perform only the current phase
|
- If you catch yourself combining phases, STOP and perform only the current phase
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: Guidelines for building C# applications
|
description: 'Guidelines for building C# applications'
|
||||||
|
applyTo: '**/*.cs'
|
||||||
---
|
---
|
||||||
|
|
||||||
# C# Development
|
# C# Development
|
||||||
@ -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.
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
applyTo: "**/*.genai.*"
|
description: 'AI-powered script generation guidelines'
|
||||||
description: AI-powered script generation guidelines
|
applyTo: '**/*.genai.*'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Role
|
## Role
|
||||||
@ -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
|
||||||
@ -79,4 +79,4 @@ Use Terraform modules to group reusable infrastructure components. For any resou
|
|||||||
- **Consider implementing automated checks**:
|
- **Consider implementing automated checks**:
|
||||||
- CI pipeline
|
- CI pipeline
|
||||||
- Pre-commit hooks
|
- Pre-commit hooks
|
||||||
- Enforce formatting, linting, and basic validation
|
- Enforce formatting, linting, and basic validation
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -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
|
||||||
@ -68,4 +69,4 @@ Instructions for high-quality Next.js applications with Tailwind CSS styling and
|
|||||||
5. Add proper error handling
|
5. Add proper error handling
|
||||||
6. Implement responsive styling
|
6. Implement responsive styling
|
||||||
7. Add loading states
|
7. Add loading states
|
||||||
8. Write tests
|
8. Write tests
|
||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: Python coding conventions and guidelines
|
description: 'Python coding conventions and guidelines'
|
||||||
|
applyTo: '**/*.py'
|
||||||
---
|
---
|
||||||
|
|
||||||
# Python Coding Conventions
|
# Python Coding Conventions
|
||||||
@ -52,4 +53,4 @@ def calculate_area(radius: float) -> float:
|
|||||||
"""
|
"""
|
||||||
import math
|
import math
|
||||||
return math.pi * radius ** 2
|
return math.pi * radius ** 2
|
||||||
```
|
```
|
||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
@ -301,4 +302,4 @@ This workflow analyzes Infrastructure-as-Code (IaC) files and Azure resources to
|
|||||||
- ✅ All recommendations include specific, executable Azure CLI commands
|
- ✅ All recommendations include specific, executable Azure CLI commands
|
||||||
- ✅ Priority scoring enables ROI-focused implementation
|
- ✅ Priority scoring enables ROI-focused implementation
|
||||||
- ✅ Architecture diagram accurately represents current state
|
- ✅ Architecture diagram accurately represents current state
|
||||||
- ✅ User confirmation prevents unwanted issue creation
|
- ✅ User confirmation prevents unwanted issue creation
|
||||||
|
|||||||
@ -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**
|
||||||
@ -18,4 +22,4 @@ Transform this Python script into a polished, beginner-friendly project by refac
|
|||||||
- **How It Works:** A breakdown of the code logic based on the comments
|
- **How It Works:** A breakdown of the code logic based on the comments
|
||||||
- **Example Usage:** A code snippet showing how to use it
|
- **Example Usage:** A code snippet showing how to use it
|
||||||
- **Sample Output:** (Optional) Include if the script returns visible results
|
- **Sample Output:** (Optional) Include if the script returns visible results
|
||||||
- Use clear, readable Markdown formatting
|
- Use clear, readable Markdown formatting
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
@ -65,4 +65,4 @@ Your goal is to help me write effective unit tests with MSTest, covering both st
|
|||||||
* Group tests by feature or component
|
* Group tests by feature or component
|
||||||
* Use test categories with `[TestCategory("Category")]`
|
* Use test categories with `[TestCategory("Category")]`
|
||||||
* Use test priorities with `[Priority(1)]` for critical tests
|
* Use test priorities with `[Priority(1)]` for critical tests
|
||||||
* Use `[Owner("DeveloperName")]` to indicate ownership
|
* Use `[Owner("DeveloperName")]` to indicate ownership
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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.
|
||||||
@ -157,4 +161,4 @@ Remember throughout this process:
|
|||||||
- Build a foundation that can be extended later
|
- Build a foundation that can be extended later
|
||||||
- Consider the open-source community and contribution model
|
- Consider the open-source community and contribution model
|
||||||
|
|
||||||
This workflow embodiment of our approach should help maintain consistency in how features are specified and prioritized, ensuring that software projects evolve in a thoughtful, user-centered way.
|
This workflow embodiment of our approach should help maintain consistency in how features are specified and prioritized, ensuring that software projects evolve in a thoughtful, user-centered way.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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.
|
||||||
@ -12,4 +12,4 @@ If a PR is waiting for someone to review, highlight that in the response.
|
|||||||
|
|
||||||
If there were any check failures on the PR, describe them and suggest possible fixes.
|
If there were any check failures on the PR, describe them and suggest possible fixes.
|
||||||
|
|
||||||
If there was no review done by Copilot, offer to request one using #request_copilot_review.
|
If there was no review done by Copilot, offer to request one using #request_copilot_review.
|
||||||
|
|||||||
682
update-readme.js
682
update-readme.js
@ -3,191 +3,260 @@
|
|||||||
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 {
|
||||||
const content = fs.readFileSync(filePath, "utf8");
|
return operation();
|
||||||
const lines = content.split("\n");
|
} catch (error) {
|
||||||
|
console.error(`Error processing file ${filePath}: ${error.message}`);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Step 1: Look for title in frontmatter for all file types
|
function extractTitle(filePath) {
|
||||||
let inFrontmatter = false;
|
return safeFileOperation(
|
||||||
let frontmatterEnded = false;
|
() => {
|
||||||
|
const content = fs.readFileSync(filePath, "utf8");
|
||||||
|
const lines = content.split("\n");
|
||||||
|
|
||||||
for (const line of lines) {
|
// Step 1: Look for title in frontmatter for all file types
|
||||||
if (line.trim() === "---") {
|
let inFrontmatter = false;
|
||||||
if (!inFrontmatter) {
|
let frontmatterEnded = false;
|
||||||
inFrontmatter = true;
|
|
||||||
} else if (!frontmatterEnded) {
|
|
||||||
frontmatterEnded = true;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inFrontmatter && !frontmatterEnded) {
|
|
||||||
// Look for title field in frontmatter
|
|
||||||
const titleMatch = line.match(/^title:\s*['"]?(.+?)['"]?$/);
|
|
||||||
if (titleMatch) {
|
|
||||||
return titleMatch[1].trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset for second pass
|
|
||||||
inFrontmatter = false;
|
|
||||||
frontmatterEnded = false;
|
|
||||||
|
|
||||||
// Step 2: For prompt/chatmode files, look for heading after frontmatter
|
|
||||||
if (filePath.includes(".prompt.md") || filePath.includes(".chatmode.md")) {
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
if (line.trim() === "---") {
|
if (line.trim() === "---") {
|
||||||
if (!inFrontmatter) {
|
if (!inFrontmatter) {
|
||||||
inFrontmatter = true;
|
inFrontmatter = true;
|
||||||
} else if (inFrontmatter && !frontmatterEnded) {
|
} else if (!frontmatterEnded) {
|
||||||
frontmatterEnded = true;
|
frontmatterEnded = true;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frontmatterEnded && line.startsWith("# ")) {
|
if (inFrontmatter && !frontmatterEnded) {
|
||||||
|
// Look for title field in frontmatter
|
||||||
|
if (line.includes("title:")) {
|
||||||
|
// Extract everything after 'title:'
|
||||||
|
const afterTitle = line
|
||||||
|
.substring(line.indexOf("title:") + 6)
|
||||||
|
.trim();
|
||||||
|
// Remove quotes if present
|
||||||
|
const cleanTitle = afterTitle.replace(/^['"]|['"]$/g, "");
|
||||||
|
return cleanTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset for second pass
|
||||||
|
inFrontmatter = false;
|
||||||
|
frontmatterEnded = false;
|
||||||
|
|
||||||
|
// Step 2: For prompt/chatmode/instructions files, look for heading after frontmatter
|
||||||
|
if (
|
||||||
|
filePath.includes(".prompt.md") ||
|
||||||
|
filePath.includes(".chatmode.md") ||
|
||||||
|
filePath.includes(".instructions.md")
|
||||||
|
) {
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.trim() === "---") {
|
||||||
|
if (!inFrontmatter) {
|
||||||
|
inFrontmatter = true;
|
||||||
|
} else if (inFrontmatter && !frontmatterEnded) {
|
||||||
|
frontmatterEnded = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frontmatterEnded && line.startsWith("# ")) {
|
||||||
|
return line.substring(2).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Format filename for prompt/chatmode/instructions files if no heading found
|
||||||
|
const basename = path.basename(
|
||||||
|
filePath,
|
||||||
|
filePath.includes(".prompt.md")
|
||||||
|
? ".prompt.md"
|
||||||
|
: filePath.includes(".chatmode.md")
|
||||||
|
? ".chatmode.md"
|
||||||
|
: ".instructions.md"
|
||||||
|
);
|
||||||
|
return basename
|
||||||
|
.replace(/[-_]/g, " ")
|
||||||
|
.replace(/\b\w/g, (l) => l.toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4: For instruction files, look for the first heading
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.startsWith("# ")) {
|
||||||
return line.substring(2).trim();
|
return line.substring(2).trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Format filename for prompt/chatmode files if no heading found
|
// Step 5: Fallback to filename
|
||||||
const basename = path.basename(
|
const basename = path.basename(filePath, path.extname(filePath));
|
||||||
filePath,
|
|
||||||
filePath.includes(".prompt.md") ? ".prompt.md" : ".chatmode.md"
|
|
||||||
);
|
|
||||||
return basename
|
return basename
|
||||||
.replace(/[-_]/g, " ")
|
.replace(/[-_]/g, " ")
|
||||||
.replace(/\b\w/g, (l) => l.toUpperCase());
|
.replace(/\b\w/g, (l) => l.toUpperCase());
|
||||||
}
|
},
|
||||||
|
filePath,
|
||||||
// Step 4: For instruction files, look for the first heading
|
path
|
||||||
for (const line of lines) {
|
.basename(filePath, path.extname(filePath))
|
||||||
if (line.startsWith("# ")) {
|
|
||||||
return line.substring(2).trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 5: Fallback to filename
|
|
||||||
const basename = path.basename(filePath, path.extname(filePath));
|
|
||||||
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
|
|
||||||
const basename = path.basename(filePath, path.extname(filePath));
|
|
||||||
return basename
|
|
||||||
.replace(/[-_]/g, " ")
|
|
||||||
.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)
|
||||||
const lines = content.split("\n");
|
const lines = content.split("\n");
|
||||||
let inFrontmatter = false;
|
let inFrontmatter = false;
|
||||||
let frontmatterEnded = false;
|
let frontmatterEnded = false;
|
||||||
|
|
||||||
// For multi-line descriptions
|
// For multi-line descriptions
|
||||||
let isMultilineDescription = false;
|
let isMultilineDescription = false;
|
||||||
let multilineDescription = [];
|
let multilineDescription = [];
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
|
|
||||||
if (line.trim() === "---") {
|
if (line.trim() === "---") {
|
||||||
if (!inFrontmatter) {
|
if (!inFrontmatter) {
|
||||||
inFrontmatter = true;
|
inFrontmatter = true;
|
||||||
} else if (inFrontmatter && !frontmatterEnded) {
|
} else if (inFrontmatter && !frontmatterEnded) {
|
||||||
frontmatterEnded = true;
|
frontmatterEnded = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inFrontmatter && !frontmatterEnded) {
|
|
||||||
// Check for multi-line description with pipe syntax (|)
|
|
||||||
const multilineMatch = line.match(/^description:\s*\|(\s*)$/);
|
|
||||||
if (multilineMatch) {
|
|
||||||
isMultilineDescription = true;
|
|
||||||
// Continue to next line to start collecting the multi-line content
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're collecting a multi-line description
|
if (inFrontmatter && !frontmatterEnded) {
|
||||||
if (isMultilineDescription) {
|
// Check for multi-line description with pipe syntax (|)
|
||||||
// If the line has no indentation or has another frontmatter key, stop collecting
|
const multilineMatch = line.match(/^description:\s*\|(\s*)$/);
|
||||||
if (!line.startsWith(" ") || line.match(/^[a-zA-Z0-9_-]+:/)) {
|
if (multilineMatch) {
|
||||||
isMultilineDescription = false;
|
isMultilineDescription = true;
|
||||||
// Join the collected lines and return
|
// Continue to next line to start collecting the multi-line content
|
||||||
return multilineDescription.join(" ").trim();
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the line to our multi-line collection (removing the 2-space indentation)
|
// If we're collecting a multi-line description
|
||||||
multilineDescription.push(line.substring(2));
|
if (isMultilineDescription) {
|
||||||
} else {
|
// If the line has no indentation or has another frontmatter key, stop collecting
|
||||||
// Look for single-line description field in frontmatter
|
if (!line.startsWith(" ") || line.match(/^[a-zA-Z0-9_-]+:/)) {
|
||||||
const descriptionMatch = line.match(
|
isMultilineDescription = false;
|
||||||
/^description:\s*['"]?(.+?)['"]?$/
|
// Join the collected lines and return
|
||||||
);
|
return multilineDescription.join(" ").trim();
|
||||||
if (descriptionMatch) {
|
}
|
||||||
return descriptionMatch[1];
|
|
||||||
|
// Add the line to our multi-line collection (removing the 2-space indentation)
|
||||||
|
multilineDescription.push(line.substring(2));
|
||||||
|
} else {
|
||||||
|
// Look for single-line description field in frontmatter
|
||||||
|
const descriptionMatch = line.match(
|
||||||
|
/^description:\s*['"]?(.+?)['"]?$/
|
||||||
|
);
|
||||||
|
if (descriptionMatch) {
|
||||||
|
return descriptionMatch[1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If we've collected multi-line description but the frontmatter ended
|
// If we've collected multi-line description but the frontmatter ended
|
||||||
if (multilineDescription.length > 0) {
|
if (multilineDescription.length > 0) {
|
||||||
return multilineDescription.join(" ").trim();
|
return multilineDescription.join(" ").trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
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,210 +265,100 @@ 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]);
|
for (const file of chatmodeFiles) {
|
||||||
|
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") {
|
||||||
|
chatmodesContent += `- [${title}](${link}) - ${customDescription}\n`;
|
||||||
|
} else {
|
||||||
|
chatmodesContent += `- [${title}](${link})\n`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find new chat modes that aren't already in the README
|
return `${TEMPLATES.chatmodesSection}\n\n${chatmodesContent}\n${TEMPLATES.chatmodesUsage}`;
|
||||||
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) {
|
if (chatmodesSection) {
|
||||||
let chatmodesListContent = "\n\n";
|
let chatmodesListContent = "\n\n";
|
||||||
|
|
||||||
// Generate list of chat mode links
|
// Always regenerate the entire list to ensure descriptions are included
|
||||||
for (const file of chatmodeFiles) {
|
for (const file of chatmodeFiles.sort()) {
|
||||||
const filePath = path.join(chatmodesDir, file);
|
const filePath = path.join(chatmodesDir, file);
|
||||||
const title = extractTitle(filePath);
|
const title = extractTitle(filePath);
|
||||||
const link = encodeURI(`chatmodes/${file}`);
|
const link = encodeURI(`chatmodes/${file}`);
|
||||||
@ -407,7 +366,7 @@ 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") {
|
||||||
// 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);
|
|
||||||
console.log("README.md updated successfully!");
|
// 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!");
|
||||||
|
} 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);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user