From 17405dfc54528ddfa94beb70d0d6539a0676bb0d Mon Sep 17 00:00:00 2001 From: James Montemagno Date: Wed, 2 Jul 2025 16:35:24 -0700 Subject: [PATCH] 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. --- CODE_OF_CONDUCT.md | 2 +- CONTRIBUTING.md | 2 +- README.md | 15 +- SECURITY.md | 2 +- SUPPORT.md | 2 +- chatmodes/4.1-Beast.chatmode.md | 2 +- chatmodes/debug.chatmode.md | 2 +- chatmodes/planner.chatmode.md | 4 +- instructions/angular.instructions.md | 4 +- instructions/aspnet-rest-apis.instructions.md | 4 +- ...azure-functions-typescript.instructions.md | 6 +- .../bicep-code-best-practices.instructions.md | 4 +- instructions/blazor.instructions.md | 4 +- instructions/cmake-vcpkg.instructions.md | 4 +- .../copilot-thought-logging.instructions.md | 2 +- instructions/csharp.instructions.md | 4 +- instructions/dotnet-maui.instructions.md | 6 +- instructions/genaiscript.instructions.md | 4 +- ...n-terraform-code-for-azure.instructions.md | 6 +- instructions/localization.instructions.md | 4 +- instructions/markdown.instructions.md | 4 +- instructions/nextjs-tailwind.instructions.md | 6 +- instructions/python.instructions.md | 6 +- prompts/aspnet-minimal-api-openapi.prompt.md | 6 +- prompts/az-cost-optimize.prompt.md | 6 +- ...comment-code-generate-a-tutorial.prompt.md | 2 +- prompts/csharp-async.prompt.md | 6 +- prompts/csharp-docs.prompt.md | 6 +- prompts/csharp-mstest.prompt.md | 8 +- prompts/csharp-nunit.prompt.md | 6 +- prompts/csharp-xunit.prompt.md | 6 +- prompts/ef-core.prompt.md | 6 +- prompts/gen-specs-as-issues.prompt.md | 2 +- prompts/javascript-typescript-jest.prompt.md | 2 +- prompts/multi-stage-dockerfile.prompt.md | 6 +- prompts/my-issues.prompt.md | 4 +- prompts/my-pull-requests.prompt.md | 6 +- standardize-frontmatter.js | 121 +++++++++ update-readme.js | 246 ++++++++++-------- 39 files changed, 337 insertions(+), 201 deletions(-) create mode 100644 standardize-frontmatter.js diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index a1f82f0..6dc4b12 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -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] [homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ \ No newline at end of file +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5c8ac13..3ee9e4f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -82,4 +82,4 @@ Please note that this project is released with a [Contributor Code of Conduct](C ## License -By contributing to this repository, you agree that your contributions will be licensed under the MIT License. \ No newline at end of file +By contributing to this repository, you agree that your contributions will be licensed under the MIT License. diff --git a/README.md b/README.md index 2d6f916..4009fdb 100644 --- a/README.md +++ b/README.md @@ -68,18 +68,15 @@ Ready-to-use prompt templates for specific development scenarios and tasks, defi > πŸ’‘ **Usage**: Use `/prompt-name` in VS Code chat, run `Chat: Run Prompt` command, or hit the run button while you have a prompt open. -## 🧩 Custom Chat Modes +## 🎭 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. -- [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-dba.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 -- [Planning mode instructions](chatmodes/planner.chatmode.md) - Generate an implementation plan for new features or refactoring existing code. -- [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. +- [4.1 Beast Mode](chatmodes/4.1-beast.chatmode.md) +- [Debug Mode Instructions](chatmodes/debug.chatmode.md) +- [Planning mode instructions](chatmodes/planner.chatmode.md) +- [Database Administrator Chat Mode](chatmodes/postgresql-dba.chatmode.md) +- [Refine Requirement or Issue Chat Mode](chatmodes/refine-issue.chatmode.md) ## πŸ“š Additional Resources diff --git a/SECURITY.md b/SECURITY.md index 4279c87..67a9cbf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -28,4 +28,4 @@ This information will help us triage your report more quickly. ## 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) \ No newline at end of file +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) diff --git a/SUPPORT.md b/SUPPORT.md index bf9050b..72edc54 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -12,4 +12,4 @@ Please include one of the following statements file: - ## GitHub Support Policy -Support for this project is limited to the resources listed above. \ No newline at end of file +Support for this project is limited to the resources listed above. diff --git a/chatmodes/4.1-Beast.chatmode.md b/chatmodes/4.1-Beast.chatmode.md index 090466e..3a0c3d4 100644 --- a/chatmodes/4.1-Beast.chatmode.md +++ b/chatmodes/4.1-Beast.chatmode.md @@ -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. 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. \ No newline at end of file +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. diff --git a/chatmodes/debug.chatmode.md b/chatmodes/debug.chatmode.md index 098fa07..199a0c6 100644 --- a/chatmodes/debug.chatmode.md +++ b/chatmodes/debug.chatmode.md @@ -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'] --- diff --git a/chatmodes/planner.chatmode.md b/chatmodes/planner.chatmode.md index eaa1bfb..baf3afb 100644 --- a/chatmodes/planner.chatmode.md +++ b/chatmodes/planner.chatmode.md @@ -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'] --- # 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. * 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. -* Testing: A list of tests that need to be implemented to verify the feature or refactoring task. \ No newline at end of file +* Testing: A list of tests that need to be implemented to verify the feature or refactoring task. diff --git a/instructions/angular.instructions.md b/instructions/angular.instructions.md index 0f5a133..b80f434 100644 --- a/instructions/angular.instructions.md +++ b/instructions/angular.instructions.md @@ -1,6 +1,6 @@ --- -description: Angular-specific coding standards and best practices -applyTo: "**/*.ts, **/*.html, **/*.scss, **/*.css" +description: 'Angular-specific coding standards and best practices' +applyTo: '**/*.ts, **/*.html, **/*.scss, **/*.css' --- # Angular Development Instructions diff --git a/instructions/aspnet-rest-apis.instructions.md b/instructions/aspnet-rest-apis.instructions.md index cc27c77..c550ae3 100644 --- a/instructions/aspnet-rest-apis.instructions.md +++ b/instructions/aspnet-rest-apis.instructions.md @@ -1,6 +1,6 @@ --- -description: Guidelines for building REST APIs with ASP.NET -applyTo: "**/*.cs, **/*.json" +description: 'Guidelines for building REST APIs with ASP.NET' +applyTo: '**/*.cs, **/*.json' --- # ASP.NET REST API Development diff --git a/instructions/azure-functions-typescript.instructions.md b/instructions/azure-functions-typescript.instructions.md index b7941d7..2e5c342 100644 --- a/instructions/azure-functions-typescript.instructions.md +++ b/instructions/azure-functions-typescript.instructions.md @@ -1,6 +1,6 @@ --- -description: TypeScript patterns for Azure Functions -applyTo: "**/*.ts, **/*.js, **/*.json" +description: 'TypeScript patterns for Azure Functions' +applyTo: '**/*.ts, **/*.js, **/*.json' --- ## Guidance for Code Generation @@ -11,4 +11,4 @@ applyTo: "**/*.ts, **/*.js, **/*.json" - Ask before adding any extra dependencies to the project - 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/-.ts` -- When making changes to the API, make sure to update the OpenAPI schema (if it exists) and `README.md` file accordingly. \ No newline at end of file +- When making changes to the API, make sure to update the OpenAPI schema (if it exists) and `README.md` file accordingly. diff --git a/instructions/bicep-code-best-practices.instructions.md b/instructions/bicep-code-best-practices.instructions.md index 32e948f..d6a9a32 100644 --- a/instructions/bicep-code-best-practices.instructions.md +++ b/instructions/bicep-code-best-practices.instructions.md @@ -1,6 +1,6 @@ --- -description: Infrastructure as Code with Bicep -applyTo: "**/*.bicep" +description: 'Infrastructure as Code with Bicep' +applyTo: '**/*.bicep' --- ## Naming Conventions diff --git a/instructions/blazor.instructions.md b/instructions/blazor.instructions.md index 113b924..5113943 100644 --- a/instructions/blazor.instructions.md +++ b/instructions/blazor.instructions.md @@ -1,6 +1,6 @@ --- -description: Blazor component and application patterns -applyTo: "**/*.razor, **/*.razor.cs, **/*.razor.css" +description: 'Blazor component and application patterns' +applyTo: '**/*.razor, **/*.razor.cs, **/*.razor.css' --- ## Blazor Code Style and Structure diff --git a/instructions/cmake-vcpkg.instructions.md b/instructions/cmake-vcpkg.instructions.md index d1e7c23..95b64ae 100644 --- a/instructions/cmake-vcpkg.instructions.md +++ b/instructions/cmake-vcpkg.instructions.md @@ -1,6 +1,6 @@ --- -description: C++ project configuration and package management -applyTo: "**/*.cmake, **/CMakeLists.txt, **/*.cpp, **/*.h, **/*.hpp" +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. diff --git a/instructions/copilot-thought-logging.instructions.md b/instructions/copilot-thought-logging.instructions.md index 15b8f4d..8377784 100644 --- a/instructions/copilot-thought-logging.instructions.md +++ b/instructions/copilot-thought-logging.instructions.md @@ -59,4 +59,4 @@ description: 'See process Copilot is following where you can edit this to reshap - NEVER continue past current phase without user input - 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 combining phases, STOP and perform only the current phase \ No newline at end of file +- If you catch yourself combining phases, STOP and perform only the current phase diff --git a/instructions/csharp.instructions.md b/instructions/csharp.instructions.md index 775f3f6..5ee3b35 100644 --- a/instructions/csharp.instructions.md +++ b/instructions/csharp.instructions.md @@ -1,6 +1,6 @@ --- -description: Guidelines for building C# applications -applyTo: "**/*.cs" +description: 'Guidelines for building C# applications' +applyTo: '**/*.cs' --- # C# Development diff --git a/instructions/dotnet-maui.instructions.md b/instructions/dotnet-maui.instructions.md index 2520b02..c6848f4 100644 --- a/instructions/dotnet-maui.instructions.md +++ b/instructions/dotnet-maui.instructions.md @@ -1,8 +1,10 @@ --- -description: .NET MAUI component and application patterns -applyTo: "**/*.xaml, **/*.cs" +description: '.NET MAUI component and application patterns' +applyTo: '**/*.xaml, **/*.cs' --- +# .NET MAUI + ## .NET MAUI Code Style and Structure - Write idiomatic and efficient .NET MAUI and C# code. diff --git a/instructions/genaiscript.instructions.md b/instructions/genaiscript.instructions.md index a7b4274..fa753c2 100644 --- a/instructions/genaiscript.instructions.md +++ b/instructions/genaiscript.instructions.md @@ -1,6 +1,6 @@ --- -description: AI-powered script generation guidelines -applyTo: "**/*.genai.*" +description: 'AI-powered script generation guidelines' +applyTo: '**/*.genai.*' --- ## Role diff --git a/instructions/generate-modern-terraform-code-for-azure.instructions.md b/instructions/generate-modern-terraform-code-for-azure.instructions.md index 71e1a22..622b47d 100644 --- a/instructions/generate-modern-terraform-code-for-azure.instructions.md +++ b/instructions/generate-modern-terraform-code-for-azure.instructions.md @@ -1,6 +1,6 @@ --- -description: Guidelines for generating modern Terraform code for Azure -applyTo: "**/*.tf" +description: 'Guidelines for generating modern Terraform code for Azure' +applyTo: '**/*.tf' --- ## 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**: - CI pipeline - Pre-commit hooks - - Enforce formatting, linting, and basic validation \ No newline at end of file + - Enforce formatting, linting, and basic validation diff --git a/instructions/localization.instructions.md b/instructions/localization.instructions.md index 0fbac95..e7d3d35 100644 --- a/instructions/localization.instructions.md +++ b/instructions/localization.instructions.md @@ -1,6 +1,6 @@ --- -description: Guidelines for localizing markdown documents -applyTo: "**/*.md" +description: 'Guidelines for localizing markdown documents' +applyTo: '**/*.md' --- # Guidance for Localization diff --git a/instructions/markdown.instructions.md b/instructions/markdown.instructions.md index d11c76b..724815d 100644 --- a/instructions/markdown.instructions.md +++ b/instructions/markdown.instructions.md @@ -1,6 +1,6 @@ --- -description: Documentation and content creation standards -applyTo: "**/*.md" +description: 'Documentation and content creation standards' +applyTo: '**/*.md' --- ## Markdown Content Rules diff --git a/instructions/nextjs-tailwind.instructions.md b/instructions/nextjs-tailwind.instructions.md index 3af8d1a..ffc4378 100644 --- a/instructions/nextjs-tailwind.instructions.md +++ b/instructions/nextjs-tailwind.instructions.md @@ -1,6 +1,6 @@ --- -description: Next.js + Tailwind development standards and instructions -applyTo: "**/*.tsx, **/*.ts, **/*.jsx, **/*.js, **/*.css" +description: 'Next.js + Tailwind development standards and instructions' +applyTo: '**/*.tsx, **/*.ts, **/*.jsx, **/*.js, **/*.css' --- # Next.js + Tailwind Development Instructions @@ -69,4 +69,4 @@ Instructions for high-quality Next.js applications with Tailwind CSS styling and 5. Add proper error handling 6. Implement responsive styling 7. Add loading states -8. Write tests \ No newline at end of file +8. Write tests diff --git a/instructions/python.instructions.md b/instructions/python.instructions.md index 42ae936..a783f42 100644 --- a/instructions/python.instructions.md +++ b/instructions/python.instructions.md @@ -1,6 +1,6 @@ --- -description: Python coding conventions and guidelines -applyTo: "**/*.py" +description: 'Python coding conventions and guidelines' +applyTo: '**/*.py' --- # Python Coding Conventions @@ -53,4 +53,4 @@ def calculate_area(radius: float) -> float: """ import math return math.pi * radius ** 2 -``` \ No newline at end of file +``` diff --git a/prompts/aspnet-minimal-api-openapi.prompt.md b/prompts/aspnet-minimal-api-openapi.prompt.md index 007157d..0f641ac 100644 --- a/prompts/aspnet-minimal-api-openapi.prompt.md +++ b/prompts/aspnet-minimal-api-openapi.prompt.md @@ -1,7 +1,7 @@ --- -mode: "agent" -tools: ["changes", "codebase", "editFiles", "problems"] -description: "Create ASP.NET Minimal API endpoints with proper OpenAPI documentation" +mode: 'agent' +tools: ['changes', 'codebase', 'editFiles', 'problems'] +description: 'Create ASP.NET Minimal API endpoints with proper OpenAPI documentation' --- Your goal is to help me create well-structured ASP.NET Minimal API endpoints with correct types and comprehensive OpenAPI/Swagger documentation. diff --git a/prompts/az-cost-optimize.prompt.md b/prompts/az-cost-optimize.prompt.md index 546bda5..108f15a 100644 --- a/prompts/az-cost-optimize.prompt.md +++ b/prompts/az-cost-optimize.prompt.md @@ -1,6 +1,6 @@ --- -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. +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.' --- ## Overview @@ -301,4 +301,4 @@ This workflow analyzes Infrastructure-as-Code (IaC) files and Azure resources to - βœ… All recommendations include specific, executable Azure CLI commands - βœ… Priority scoring enables ROI-focused implementation - βœ… Architecture diagram accurately represents current state -- βœ… User confirmation prevents unwanted issue creation \ No newline at end of file +- βœ… User confirmation prevents unwanted issue creation diff --git a/prompts/comment-code-generate-a-tutorial.prompt.md b/prompts/comment-code-generate-a-tutorial.prompt.md index 2b590d2..520d584 100644 --- a/prompts/comment-code-generate-a-tutorial.prompt.md +++ b/prompts/comment-code-generate-a-tutorial.prompt.md @@ -18,4 +18,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 - **Example Usage:** A code snippet showing how to use it - **Sample Output:** (Optional) Include if the script returns visible results - - Use clear, readable Markdown formatting \ No newline at end of file + - Use clear, readable Markdown formatting diff --git a/prompts/csharp-async.prompt.md b/prompts/csharp-async.prompt.md index 3c61497..5ce1883 100644 --- a/prompts/csharp-async.prompt.md +++ b/prompts/csharp-async.prompt.md @@ -1,7 +1,7 @@ --- -mode: "agent" -tools: ["changes", "codebase", "editFiles", "problems"] -description: "Get best practices for C# async programming" +mode: 'agent' +tools: ['changes', 'codebase', 'editFiles', 'problems'] +description: 'Get best practices for C# async programming' --- # C# Async Programming Best Practices diff --git a/prompts/csharp-docs.prompt.md b/prompts/csharp-docs.prompt.md index 39b672a..9523cd2 100644 --- a/prompts/csharp-docs.prompt.md +++ b/prompts/csharp-docs.prompt.md @@ -1,7 +1,7 @@ --- -mode: "agent" -tools: ["changes", "codebase", "editFiles", "problems"] -description: "Ensure that C# types are documented with XML comments and follow best practices for documentation." +mode: 'agent' +tools: ['changes', 'codebase', 'editFiles', 'problems'] +description: 'Ensure that C# types are documented with XML comments and follow best practices for documentation.' --- # C# Documentation Best Practices diff --git a/prompts/csharp-mstest.prompt.md b/prompts/csharp-mstest.prompt.md index f4ec8b3..4d096cc 100644 --- a/prompts/csharp-mstest.prompt.md +++ b/prompts/csharp-mstest.prompt.md @@ -1,7 +1,7 @@ --- -mode: "agent" -tools: ["changes", "codebase", "editFiles", "problems", "search"] -description: "Get best practices for MSTest unit testing, including data-driven tests" +mode: 'agent' +tools: ['changes', 'codebase', 'editFiles', 'problems', 'search'] +description: 'Get best practices for MSTest unit testing, including data-driven tests' --- # 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 * Use test categories with `[TestCategory("Category")]` * Use test priorities with `[Priority(1)]` for critical tests -* Use `[Owner("DeveloperName")]` to indicate ownership \ No newline at end of file +* Use `[Owner("DeveloperName")]` to indicate ownership diff --git a/prompts/csharp-nunit.prompt.md b/prompts/csharp-nunit.prompt.md index e266975..cdabee7 100644 --- a/prompts/csharp-nunit.prompt.md +++ b/prompts/csharp-nunit.prompt.md @@ -1,7 +1,7 @@ --- -mode: "agent" -tools: ["changes", "codebase", "editFiles", "problems", "search"] -description: "Get best practices for NUnit unit testing, including data-driven tests" +mode: 'agent' +tools: ['changes', 'codebase', 'editFiles', 'problems', 'search'] +description: 'Get best practices for NUnit unit testing, including data-driven tests' --- # NUnit Best Practices diff --git a/prompts/csharp-xunit.prompt.md b/prompts/csharp-xunit.prompt.md index 50b6409..a5b80ec 100644 --- a/prompts/csharp-xunit.prompt.md +++ b/prompts/csharp-xunit.prompt.md @@ -1,7 +1,7 @@ --- -mode: "agent" -tools: ["changes", "codebase", "editFiles", "problems", "search"] -description: "Get best practices for XUnit unit testing, including data-driven tests" +mode: 'agent' +tools: ['changes', 'codebase', 'editFiles', 'problems', 'search'] +description: 'Get best practices for XUnit unit testing, including data-driven tests' --- # XUnit Best Practices diff --git a/prompts/ef-core.prompt.md b/prompts/ef-core.prompt.md index 3ad6350..5ae7a22 100644 --- a/prompts/ef-core.prompt.md +++ b/prompts/ef-core.prompt.md @@ -1,7 +1,7 @@ --- -mode: "agent" -tools: ["changes", "codebase", "editFiles", "problems", "runCommands"] -description: "Get best practices for Entity Framework Core" +mode: 'agent' +tools: ['changes', 'codebase', 'editFiles', 'problems', 'runCommands'] +description: 'Get best practices for Entity Framework Core' --- # Entity Framework Core Best Practices diff --git a/prompts/gen-specs-as-issues.prompt.md b/prompts/gen-specs-as-issues.prompt.md index ac32f0e..2face3f 100644 --- a/prompts/gen-specs-as-issues.prompt.md +++ b/prompts/gen-specs-as-issues.prompt.md @@ -157,4 +157,4 @@ Remember throughout this process: - Build a foundation that can be extended later - 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. \ No newline at end of file +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. diff --git a/prompts/javascript-typescript-jest.prompt.md b/prompts/javascript-typescript-jest.prompt.md index f158067..5aa8ce1 100644 --- a/prompts/javascript-typescript-jest.prompt.md +++ b/prompts/javascript-typescript-jest.prompt.md @@ -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 diff --git a/prompts/multi-stage-dockerfile.prompt.md b/prompts/multi-stage-dockerfile.prompt.md index 47d988c..0d4a47f 100644 --- a/prompts/multi-stage-dockerfile.prompt.md +++ b/prompts/multi-stage-dockerfile.prompt.md @@ -1,7 +1,7 @@ --- -mode: "agent" -tools: ["codebase"] -description: "Create optimized multi-stage Dockerfiles for any language or framework" +mode: 'agent' +tools: ['codebase'] +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. diff --git a/prompts/my-issues.prompt.md b/prompts/my-issues.prompt.md index 5586077..113c77f 100644 --- a/prompts/my-issues.prompt.md +++ b/prompts/my-issues.prompt.md @@ -1,7 +1,7 @@ --- -mode: agent +mode: 'agent' 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. diff --git a/prompts/my-pull-requests.prompt.md b/prompts/my-pull-requests.prompt.md index 3a83c39..25b8d75 100644 --- a/prompts/my-pull-requests.prompt.md +++ b/prompts/my-pull-requests.prompt.md @@ -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'] -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. @@ -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 was no review done by Copilot, offer to request one using #request_copilot_review. \ No newline at end of file +If there was no review done by Copilot, offer to request one using #request_copilot_review. diff --git a/standardize-frontmatter.js b/standardize-frontmatter.js new file mode 100644 index 0000000..e63c616 --- /dev/null +++ b/standardize-frontmatter.js @@ -0,0 +1,121 @@ +#!/usr/bin/env node + +const fs = require("fs"); +const path = require("path"); + +function standardizeFrontmatter(content) { + const lines = content.split('\n'); + const result = []; + let inFrontmatter = false; + let frontmatterEnded = false; + + for (const line of lines) { + if (line.trim() === '---') { + if (!inFrontmatter) { + inFrontmatter = true; + result.push(line); + } else if (!frontmatterEnded) { + frontmatterEnded = true; + result.push(line); + } else { + result.push(line); + } + continue; + } + + if (inFrontmatter && !frontmatterEnded) { + // Convert frontmatter fields to use single quotes + let modifiedLine = line; + + // Handle fields that should use single quotes for strings + const fieldsToStandardize = ['mode', 'description', 'applyTo', 'title']; + + for (const field of fieldsToStandardize) { + // Pattern 1: Convert double quotes to single quotes + const doubleQuotePattern = new RegExp(`^(${field}:\\s*)"([^"]*)"(\\s*)$`); + const doubleQuoteMatch = modifiedLine.match(doubleQuotePattern); + if (doubleQuoteMatch) { + modifiedLine = `${doubleQuoteMatch[1]}'${doubleQuoteMatch[2]}'${doubleQuoteMatch[3]}`; + continue; // Skip to next field if we found a match + } + + // Pattern 2: Fix double single quotes (''text'') to single quotes + const doubleSingleQuotePattern = new RegExp(`^(${field}:\\s*)''([^']*?)''(\\s*)$`); + const doubleSingleQuoteMatch = modifiedLine.match(doubleSingleQuotePattern); + if (doubleSingleQuoteMatch) { + modifiedLine = `${doubleSingleQuoteMatch[1]}'${doubleSingleQuoteMatch[2]}'${doubleSingleQuoteMatch[3]}`; + continue; + } + + // Pattern 3: Fix missing space after colon (field:value -> field: value) + const noSpacePattern = new RegExp(`^(${field}:)([^\\s])`); + const noSpaceMatch = modifiedLine.match(noSpacePattern); + if (noSpaceMatch) { + modifiedLine = modifiedLine.replace(noSpacePattern, `${noSpaceMatch[1]} ${noSpaceMatch[2]}`); + } + + // Pattern 4: Add single quotes to unquoted values (but not arrays or objects) + const unquotedPattern = new RegExp(`^(${field}:\\s*)([^'\"\\[\\{][^\\n]*?)(\\s*)$`); + const unquotedMatch = modifiedLine.match(unquotedPattern); + if (unquotedMatch) { + const value = unquotedMatch[2].trim(); + // Only quote if it's not already quoted and not empty + if (value && !value.startsWith('[') && !value.startsWith('{')) { + modifiedLine = `${unquotedMatch[1]}'${value}'${unquotedMatch[3]}`; + } + } + } + + // Handle tools array - convert double quotes to single quotes within the array + if (modifiedLine.includes('tools:')) { + modifiedLine = modifiedLine.replace(/"/g, "'"); + } + + result.push(modifiedLine); + } else { + result.push(line); + } + } + + return result.join('\n'); +} + +function processFiles() { + const directories = ['prompts', 'instructions', 'chatmodes']; + let filesProcessed = 0; + + for (const dir of directories) { + const dirPath = path.join(__dirname, dir); + + if (!fs.existsSync(dirPath)) { + console.log(`Directory ${dir} does not exist, skipping...`); + continue; + } + + const files = fs.readdirSync(dirPath); + + for (const file of files) { + if (file.endsWith('.md')) { + const filePath = path.join(dirPath, file); + + try { + const content = fs.readFileSync(filePath, 'utf8'); + const standardizedContent = standardizeFrontmatter(content); + + // Only write if content has changed + if (content !== standardizedContent) { + fs.writeFileSync(filePath, standardizedContent); + console.log(`Standardized frontmatter in: ${filePath}`); + filesProcessed++; + } + } catch (error) { + console.error(`Error processing ${filePath}: ${error.message}`); + } + } + } + } + + console.log(`\nProcessed ${filesProcessed} files.`); +} + +processFiles(); diff --git a/update-readme.js b/update-readme.js index 27c314f..bb47f47 100755 --- a/update-readme.js +++ b/update-readme.js @@ -3,153 +3,168 @@ const fs = require("fs"); const path = require("path"); -function extractTitle(filePath) { +// Add error handling utility +function safeFileOperation(operation, filePath, defaultValue = null) { try { - const content = fs.readFileSync(filePath, "utf8"); - const lines = content.split("\n"); + return operation(); + } catch (error) { + console.error(`Error processing file ${filePath}: ${error.message}`); + return defaultValue; + } +} - // Step 1: Look for title in frontmatter for all file types - let inFrontmatter = false; - let frontmatterEnded = false; +function extractTitle(filePath) { + return safeFileOperation( + () => { + const content = fs.readFileSync(filePath, "utf8"); + const lines = content.split("\n"); - for (const line of lines) { - if (line.trim() === "---") { - if (!inFrontmatter) { - inFrontmatter = true; - } else if (!frontmatterEnded) { - frontmatterEnded = true; - } - continue; - } + // Step 1: Look for title in frontmatter for all file types + let inFrontmatter = false; + let frontmatterEnded = false; - 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) { if (line.trim() === "---") { if (!inFrontmatter) { inFrontmatter = true; - } else if (inFrontmatter && !frontmatterEnded) { + } else if (!frontmatterEnded) { frontmatterEnded = true; } 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 files, look for heading after frontmatter + if (filePath.includes(".prompt.md") || filePath.includes(".chatmode.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 files if no heading found + const basename = path.basename( + filePath, + filePath.includes(".prompt.md") ? ".prompt.md" : ".chatmode.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(); } } - // Step 3: Format filename for prompt/chatmode files if no heading found - const basename = path.basename( - filePath, - filePath.includes(".prompt.md") ? ".prompt.md" : ".chatmode.md" - ); + // Step 5: Fallback to filename + const basename = path.basename(filePath, path.extname(filePath)); 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(); - } - } - - // Step 5: Fallback to filename - const basename = path.basename(filePath, path.extname(filePath)); - return basename + }, + filePath, + path.basename(filePath, path.extname(filePath)) .replace(/[-_]/g, " ") - .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()); - } + .replace(/\b\w/g, (l) => l.toUpperCase()) + ); } function extractDescription(filePath) { - try { - const content = fs.readFileSync(filePath, "utf8"); + return safeFileOperation( + () => { + const content = fs.readFileSync(filePath, "utf8"); - // Parse frontmatter for description (for both prompts and instructions) - const lines = content.split("\n"); - let inFrontmatter = false; - let frontmatterEnded = false; + // Parse frontmatter for description (for both prompts and instructions) + const lines = content.split("\n"); + let inFrontmatter = false; + let frontmatterEnded = false; - // For multi-line descriptions - let isMultilineDescription = false; - let multilineDescription = []; + // For multi-line descriptions + let isMultilineDescription = false; + let multilineDescription = []; - for (let i = 0; i < lines.length; i++) { - const line = lines[i]; + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; - if (line.trim() === "---") { - if (!inFrontmatter) { - inFrontmatter = true; - } else if (inFrontmatter && !frontmatterEnded) { - frontmatterEnded = true; - 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 + if (line.trim() === "---") { + if (!inFrontmatter) { + inFrontmatter = true; + } else if (inFrontmatter && !frontmatterEnded) { + frontmatterEnded = true; + break; + } continue; } - // If we're collecting a multi-line description - if (isMultilineDescription) { - // If the line has no indentation or has another frontmatter key, stop collecting - if (!line.startsWith(" ") || line.match(/^[a-zA-Z0-9_-]+:/)) { - isMultilineDescription = false; - // Join the collected lines and return - return multilineDescription.join(" ").trim(); + 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; } - // 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're collecting a multi-line description + if (isMultilineDescription) { + // If the line has no indentation or has another frontmatter key, stop collecting + if (!line.startsWith(" ") || line.match(/^[a-zA-Z0-9_-]+:/)) { + isMultilineDescription = false; + // Join the collected lines and return + return multilineDescription.join(" ").trim(); + } + + // 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 (multilineDescription.length > 0) { - return multilineDescription.join(" ").trim(); - } + // If we've collected multi-line description but the frontmatter ended + if (multilineDescription.length > 0) { + return multilineDescription.join(" ").trim(); + } - return null; - } catch (error) { - return null; - } + return null; + }, + filePath, + null + ); } function updateInstructionsSection( @@ -391,15 +406,15 @@ function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) { 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 - ); + // Look for ANY existing chat modes section (with any emoji) + const chatmodesSectionRegex = /## [🧩🎭].*Custom Chat Modes[\s\S]*?(?=\n## |\n\n## |$)/; + const chatmodesSection = currentReadme.match(chatmodesSectionRegex); if (chatmodesSection) { let chatmodesListContent = "\n\n"; - // Generate list of chat mode links - for (const file of chatmodeFiles) { + // Generate list of chat mode links (sorted alphabetically) + for (const file of chatmodeFiles.sort()) { const filePath = path.join(chatmodesDir, file); const title = extractTitle(filePath); const link = encodeURI(`chatmodes/${file}`); @@ -418,7 +433,7 @@ function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) { // Replace the current chat modes section with the updated one 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; return currentReadme.replace(chatmodesSection[0], newChatmodesSection); @@ -429,6 +444,7 @@ function updateChatModesSection(currentReadme, chatmodeFiles, chatmodesDir) { ); const chatmodesListContent = chatmodeFiles + .sort() .map((file) => { const filePath = path.join(chatmodesDir, file); const title = extractTitle(filePath);