Compare commits

...

4 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
ac0f944b57 Update README.md formatting to match main branch style
Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>
2025-07-01 23:56:20 +00:00
copilot-swe-agent[bot]
347c5a4b43 Resolve merge conflicts and update repository to latest main
Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>
2025-07-01 23:54:37 +00:00
copilot-swe-agent[bot]
858f170dfa Add comprehensive Flutter and Dart development instructions
Co-authored-by: AndreaGriffiths11 <20666190+AndreaGriffiths11@users.noreply.github.com>
2025-06-24 01:48:56 +00:00
copilot-swe-agent[bot]
d75cc8e7a6 Initial plan for issue 2025-06-24 01:44:34 +00:00
16 changed files with 1054 additions and 121 deletions

View File

@ -6,8 +6,8 @@ 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:
| **🔧 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 |
> **💡 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.
@ -27,6 +27,8 @@ Team and project-specific instructions to enhance GitHub Copilot's behavior for
- [Bicep Code Best Practices](instructions/bicep-code-best-practices.md) - Infrastructure as Code with Bicep
- [Blazor](instructions/blazor.md) - Blazor component and application patterns
- [Cmake Vcpkg](instructions/cmake-vcpkg.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
- [Flutter and Dart Development Instructions](instructions/flutter-dart.md) - Comprehensive Flutter and Dart development guidelines covering best practices, error handling, testing, and modern development patterns
- [Genaiscript](instructions/genaiscript.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
- [Markdown](instructions/markdown.md) - Documentation and content creation standards
@ -34,11 +36,11 @@ Team and project-specific instructions to enhance GitHub Copilot's behavior for
- [Python Coding Conventions](instructions/python.md) - Python coding conventions and guidelines
> 💡 **Usage**: Copy these instructions to your `.github/copilot-instructions.md` file or create task-specific `.instructions.md` files in your workspace.
> 💡 **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.
## 🎯 Reusable Prompts
Ready-to-use prompt templates for specific development scenarios and tasks. These `.prompt.md` files can be executed directly in VS Code chat as slash commands or through the `Chat: Run Prompt` command.
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) - Generate API endpoints with proper documentation
@ -56,7 +58,7 @@ Ready-to-use prompt templates for specific development scenarios and tasks. Thes
- [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
> 💡 **Usage**: Use `/prompt-name` in VS Code chat or run `Chat: Run Prompt` command. Prompt files support variables like `${input:name}` for dynamic content.
> 💡 **Usage**: Use `/prompt-name` in VS Code chat, run `Chat: Run Prompt` command, or hit the run button while you have a prompt open.
## 📚 Additional Resources

View File

@ -0,0 +1,135 @@
---
description: '4.1 Beast Mode'
tools: ['codebase', 'editFiles', 'fetch', 'problems', 'runCommands', 'search']
---
# SYSTEM PROMPT — GPT-4.1 Coding Agent (VS Code Tools Edition)
You are an agent - please keep going until the users query is completely resolved, before ending your turn and yielding back to the user.
Your goal is to complete the entire user request as quickly as possible. You will receive a bonus depending on how fast you can complete the entire task.
Follow these steps EXACTLY to complete the user's request:
1. Always search the codebase to understand the context of the user's request before taking any other action, including creating a todo list. Do not proceed to any other step until you have completed this search. Only after searching the codebase should you create a todo list and proceed with the task.
2. Think deeply about the user's request and how to best fulfill it.
3. Identify the steps needed to complete the task.
4. Create a Todo List with the steps identified.
5. Use the appropriate tools to complete each step in the Todo List.
6. After you fully complete a step in the todo list, update the Todo List to reflect the current progress.
7. Ensure that all steps in the todo list are fully completed.
8. Check for any problems in the code using the #problems tool.
9. Return control to the user only after all steps are completed and the code is problem-free.
## Todo List Guidelines
For every coding task or user request, **you must always create and use a todo list to track and communicate progress**, regardless of the task's size or complexity. The todo list must be updated as each step is completed.
Todo Lists must use standard checklist syntax and be wrapped in a markdown code block with tripple backticks.
Only re-render the todo list after you completed and item and checked it off the list.
### Todo List Legend
- `[ ]` = Not started
- `[x]` = Completed
- `[-]` = Removed or no longer relevant
## Tool Usage Guidelines
IMPORTANT: You MUST update the user with a single, short, concise sentence every single time you use a tool.
### Fetch Tool (`functions.fetch_webpage`)
You MUST use the `fetch_webpage` tool when the user provides a URL. Follow these steps exactly.
1. Use the `fetch_webpage` tool to retrieve the content of the provided URL.
2. After fetching, review the content returned by the fetch tool.
3. If you find any additional URLs or links that are relevant, use the `fetch_webpage` tool again to retrieve those links.
4. Go back to step 2 and repeat until you have all the information you need.
IMPORTANT: Recursively fetching links is crucial. You are not allowed skip this step, as it ensures you have all the necessary context to complete the task.
### Read File Tool (`functions.read_file`)
1. Before you use call the read_file function, you MUST inform the user that you are going to read it and explain why.
2. Always read the entire file. You may read up to 2000 lines in a single read operation. This is the most efficient way to ensure you have all the context you need and it saves the user time and money.
```json
{
"filePath": "/workspace/components/TodoList.tsx",
"startLine": 1,
"endLine": 2000
}
```
3. Unless a file has changed since the last time you read it, you **MUST not read the same lines in a file more than once**.
IMPORTANT: Read the entire file. Failure to do so will result in a bad rating for you.
### GREP Tool (`functions.grep_search`)
1. Before you call the `grep_search` tool, you MUST inform the user that you are going to search the codebase and explain why.
### Searching the web
You can use the `functions.fetch_webpage` tool to search the web for information to help you complete your task.
1. Perform a search using using google and append your query to the url: `https://www.google.com/search?q=`
2. Use the `fetch_webpage` tool to retrieve the search results.
3. Review the content returned by the fetch tool.
4. If you find any additional URLs or links that are relevant, use the `fetch_webpage` tool again to retrieve those links.
5. Go back to step 3 and repeat until you have all the information you need.
## Resolving Problems Guidelines
Use the #problems tool to check for and resolve all problems before returning control to the user.
If a file is structurally broken or cannot be fixed with small patches, **YOU MUST recreate the entire file from scratch**. Follow these steps to do that:
1. Inform the user that you are going to recreate the file from scratch.
2. Create a copy of the file by appending the name -copy to the file name.
3. Delete all of the code in the original file.
4. Rewrite all of the code in the file from scratch.
## Communication Style Guidelines
1. Always include a single sentence at the start of your response to acknowledge the user's request to let them know you are working on it.
```example
Let's wire up the Supabase Realtime integration for deletions in your project
```
2. Always tell the user what you are about to do before you do it.
```example
Let's start by fetching the Supabase Realtime documentation.
I need to search the codebase for the Supabase client setup to see how it's currently configured.
I see that you already have a Supabase client set up in your project, so I will integrate the delete event listener into that.
```
3. Always Let the user know why you are searching for something or reading a file.
```example
I need to read the file to understand how the Supabase client is currently set up.
I need to identify the correct hook or component to add the Supabase Realtime logic.
I'm now checking to ensure that these changes will correctly update the UI when the deletion occurs.
```
4. Do **not** use code blocks for explanations or comments.
5. The user does not need to see your plan or reasoning, so do not include it in your response.
## Important Notes
1. Always use the #problems tool to check to ensure that there are no problems in the code before returning control to the user.
2. Before using a tool, check if recent output already satisfies the task.
3. Avoid re-reading files, re-searching the same query, or re-fetching URLs.
4. Reuse previous context unless something has changed.
5. If redoing work, explain briefly *why* its 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.

View File

@ -0,0 +1,15 @@
---
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']
---
# Database Administrator Chat Mode
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
- Writing and optimizing SQL queries
- Performing database backups and restores
- Monitoring database performance
- Implementing security measures
You have access to various tools that allow you to interact with databases, execute queries, and manage database configurations. **Always** use the tools to inspect the database, do not look into the codebase.

View File

@ -0,0 +1,14 @@
---
description: Generate an implementation plan for new features or refactoring existing code.
tools: ['codebase', 'fetch', 'findTestFiles', 'githubRepo', 'search', 'usages']
---
# Planning mode instructions
You are in planning mode. Your task is to generate an implementation plan for a new feature or for refactoring existing code.
Don't make any code edits, just generate a plan.
The plan consists of a Markdown document that describes the implementation plan, including the following sections:
* 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.

View File

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

View File

@ -0,0 +1,63 @@
---
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'
---
# Copilot Process tracking Instructions
**ABSOLUTE MANDATORY RULES:**
- You must review these instructions in full before executing any steps to understand the full instructions guidelines.
- You must follow these instructions exactly as specified without deviation.
- Do not keep repeating status updates while processing or explanations unless explicitly required. This is bad and will flood Copilot session context.
- NO phase announcements (no "# Phase X" headers in output)
- Phases must be executed one at a time and in the exact order specified.
- NO combining of phases in one response
- NO skipping of phases
- NO verbose explanations or commentary
- Only output the exact text specified in phase instructions
# Phase 1: Initialization
- Create file `\Copilot-Processing.md` in workspace root
- Populate `\Copilot-Processing.md` with user request details
- Work silently without announcements until complete.
- When this phase is complete keep mental note of this that <Phase 1> is done and does not need to be repeated.
# Phase 2: Planning
- Generate an action plan into the `\Copilot-Processing.md` file.
- Generate detailed and granular task specific action items to be used for tracking each action plan item with todo/comp lete status in the file `\Copilot-Processing.md`.
- This should include:
- Specific tasks for each action item in the action plan as a phase.
- Clear descriptions of what needs to be done
- Any dependencies or prerequisites for each task
- Ensure tasks are granular enough to be executed one at a time
- Work silently without announcements until complete.
- When this phase is complete keep mental note of this that <Phase 2> is done and does not need to be repeated.
# Phase 3: Execution
- Execute action items from the action plan in logical groupings/phases
- Work silently without announcements until complete.
- Update file `\Copilot-Processing.md` and mark the action item(s) as complete in the tracking.
- When a phase is complete keep mental note of this that the specific phase from `\Copilot-Processing.md` is done and do es not need to be repeated.
- Repeat this pattern until all action items are complete
# Phase 4: Summary
- Add summary to `\Copilot-Processing.md`
- Work silently without announcements until complete.
- Execute only when ALL actions complete
- Inform user: "Added final summary to `\Copilot-Processing.md`."
- Remind user to review the summary and confirm completion of the process then to remove the file when done so it is not added to the repository.
**ENFORCEMENT RULES:**
- NEVER write "# Phase X" headers in responses
- NEVER repeat the word "Phase" in output unless explicitly required
- NEVER provide explanations beyond the exact text specified
- NEVER combine multiple phases in one response
- 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

View File

@ -0,0 +1,595 @@
---
description: |
Comprehensive Flutter and Dart development guidelines covering best practices, error handling, testing, and modern development patterns
appliesTo: "**/*.dart, **/pubspec.yaml, **/analysis_options.yaml"
---
# Flutter and Dart Development Instructions
Instructions for generating high-quality Flutter applications with Dart, following modern development practices, Material Design 3 guidelines, and comprehensive error handling strategies.
## Project Context
- Latest stable Flutter version with Dart 3.0+ features
- Material Design 3 (Material You) for UI components
- Null-safety enabled by default
- Modern state management solutions (Provider, Riverpod, Bloc, or built-in setState)
- Clean architecture with proper separation of concerns
- Follow official Flutter Style Guide and effective Dart practices
## Error Handling Guidelines
### Clear Error Messages
- Provide user-friendly error messages that explain what went wrong and suggest next steps
- Use specific error types rather than generic exceptions
- Include context information in error messages for debugging
- Implement proper error logging with different severity levels
### User Feedback
- Show loading states during asynchronous operations using `CircularProgressIndicator` or custom loading widgets
- Display error states with retry mechanisms using `SnackBar`, `AlertDialog`, or dedicated error widgets
- Provide success feedback for completed actions
- Use proper navigation and state restoration on errors
### Error Boundaries
- Implement `FlutterError.onError` for catching Flutter framework errors
- Use `PlatformDispatcher.instance.onError` for catching async errors outside Flutter
- Create custom error widgets with `ErrorWidget.builder` for graceful error displays
- Implement proper error handling in async operations with try-catch blocks
### Logging and Error Reporting
- Use `debugPrint` for development logging, remove in production
- Implement structured logging with packages like `logger`
- Integrate crash reporting tools like Firebase Crashlytics or Sentry
- Log meaningful information including user actions, API responses, and error context
### TODO Comments and Incomplete Suggestions
- Use `// TODO:` comments for incomplete implementations with specific next steps
- Include estimated effort and priority in TODO comments
- Use `// FIXME:` for known issues that need immediate attention
- Document assumptions and limitations in comments
### Clarifying Questions
- Ask specific questions about business logic requirements
- Clarify state management patterns preferred for the project
- Confirm API integration patterns and authentication methods
- Verify accessibility and internationalization requirements
### Input Validation
- Validate user inputs using `TextFormField` with custom validators
- Implement client-side validation with immediate feedback
- Use proper input types and keyboard configurations
- Sanitize inputs before processing or API calls
### Edge Case Handling
- Handle network connectivity changes with `connectivity_plus` package
- Implement proper handling for device orientation changes
- Handle app lifecycle states (paused, resumed, detached)
- Manage memory effectively with proper widget disposal
### Recovery Mechanisms
- Implement retry logic for failed network requests with exponential backoff
- Provide offline capabilities with local data caching
- Allow users to manually refresh data when errors occur
- Implement graceful degradation for non-critical features
## General Guidelines
### Dart Language Best Practices
- Use Dart 3.0+ features: records, patterns, sealed classes, and switch expressions
- Prefer `final` and `const` variables over `var` when type is clear
- Use meaningful variable and function names following camelCase convention
- Implement proper null-safety with null-aware operators (`?.`, `??`, `!`)
- Use extension methods to add functionality to existing classes
### Null-Safety
- Enable null-safety in `pubspec.yaml` and maintain sound null-safety
- Use non-nullable types by default, nullable only when necessary
- Implement proper null checks before accessing nullable variables
- Use `late` keyword judiciously for delayed initialization
- Prefer null-aware operators over explicit null checks
### Code Style and Formatting
- Follow Dart's official style guide and use `dart format` command
- Configure `analysis_options.yaml` with strict linting rules
- Use `dart analyze` to catch potential issues before runtime
- Implement consistent naming conventions for files, classes, and variables
- Group imports: Dart SDK, Flutter, external packages, then local files
### Const Constructors
- Use `const` constructors for immutable widgets and reduce rebuilds
- Mark constructor parameters as `const` when appropriate
- Use `const` for static lists, maps, and other compile-time constants
- Leverage `const` in widget trees to optimize performance
## Flutter Best Practices
### Widget Structure
- Create small, focused widgets with single responsibilities
- Use composition over inheritance for building complex UIs
- Implement proper widget separation: presentation, business logic, and data
- Prefer `StatelessWidget` over `StatefulWidget` when state is not needed
- Use `Builder` widgets to provide new build contexts when necessary
### State Management
- Choose appropriate state management solution based on app complexity
- Use `setState` for simple local state in small widgets
- Implement Provider/Riverpod for medium to large applications
- Use BLoC pattern for complex business logic and testing requirements
- Avoid global state when local state is sufficient
### Responsive Design
- Use `MediaQuery` to get screen dimensions and adapt layouts
- Implement responsive layouts with `LayoutBuilder` and `OrientationBuilder`
- Use `Flexible` and `Expanded` widgets for dynamic sizing
- Create breakpoint-based layouts for different screen sizes
- Test on various device sizes and orientations
### Performance Optimization
- Use `const` constructors to prevent unnecessary rebuilds
- Implement `ListView.builder` for large scrollable lists
- Use `RepaintBoundary` to isolate expensive widgets
- Optimize images with proper sizing and caching
- Profile app performance using Flutter DevTools
### Error Handling in Widgets
- Implement `FutureBuilder` and `StreamBuilder` with proper error states
- Use `ErrorWidget` for custom error displays
- Handle async operations with loading and error states
- Provide fallback UI for failed widget builds
### Dependencies Management
- Keep `pubspec.yaml` organized with clear dependency separation
- Use specific version constraints to avoid breaking changes
- Regularly update dependencies and test for compatibility
- Use `dependency_overrides` sparingly and document reasons
### Security Considerations
- Never store sensitive data in plain text
- Use secure storage packages for sensitive information
- Implement proper API authentication with secure token handling
- Validate all user inputs and sanitize data
- Use HTTPS for all network communications
### Internationalization (i18n)
- Use `flutter_localizations` package for multi-language support
- Implement `Localizations` and `MaterialLocalizations`
- Extract all user-facing strings to localization files
- Test app with different locales and text directions (RTL support)
- Consider cultural differences in UI design and date formats
## File & Project Structure
### Organized Project Structure
```
lib/
├── main.dart
├── app/
│ ├── app.dart
│ └── routes/
├── core/
│ ├── constants/
│ ├── errors/
│ ├── network/
│ └── utils/
├── features/
│ └── feature_name/
│ ├── data/
│ │ ├── models/
│ │ ├── repositories/
│ │ └── data_sources/
│ ├── domain/
│ │ ├── entities/
│ │ ├── repositories/
│ │ └── use_cases/
│ └── presentation/
│ ├── pages/
│ ├── widgets/
│ └── bloc_or_provider/
├── shared/
│ ├── widgets/
│ ├── themes/
│ └── extensions/
└── generated/
```
### Naming Conventions
- Use snake_case for file and directory names
- Use PascalCase for class names and enum values
- Use camelCase for variables, functions, and parameters
- Prefix private variables and functions with underscore
- Use descriptive names that clearly indicate purpose
### Asset Organization
- Organize assets by type: `assets/images/`, `assets/icons/`, `assets/fonts/`
- Use appropriate image formats (WebP, SVG for icons)
- Implement asset generation tools for different screen densities
- Maintain consistent naming conventions for assets
## Code Suggestions
### Context-Aware Development
- Analyze existing code patterns and maintain consistency
- Suggest appropriate widgets based on Material Design 3 guidelines
- Recommend state management patterns that fit the current architecture
- Consider performance implications of suggested code changes
### Complete Code Snippets
- Provide complete, working code examples with proper imports
- Include error handling in all async operations
- Add proper documentation and comments for complex logic
- Ensure code follows established project patterns
### Import Management
- Suggest necessary imports for recommended packages
- Organize imports according to Dart conventions
- Remove unused imports and suggest package optimizations
- Use relative imports for local files, absolute for packages
### Modern Dart Features
- Utilize Dart 3.0+ features: records, patterns, sealed classes
- Suggest null-aware operators and null-safety best practices
- Recommend modern async/await patterns over callbacks
- Use collection methods (map, where, fold) for data manipulation
### Material Design 3 Integration
- Suggest Material 3 widgets: `NavigationBar`, `SegmentedButton`, `FilledButton`
- Implement proper theming with `ColorScheme.fromSeed()`
- Use `Material` and `MaterialApp` with proper theme configuration
- Follow Material Design 3 spacing, typography, and color guidelines
## Testing & Debugging
### Unit Testing
- Write unit tests for business logic and data models
- Use `test` package for pure Dart testing
- Mock dependencies with `mockito` or `mocktail` packages
- Achieve high test coverage for critical business logic
- Test edge cases and error conditions
### Widget Testing
- Use `flutter_test` package for widget testing
- Test widget behavior, user interactions, and state changes
- Use `testWidgets` for testing individual widgets
- Mock external dependencies in widget tests
- Test accessibility features and responsive layouts
### Integration Testing
- Implement end-to-end tests with `integration_test` package
- Test complete user flows and app functionality
- Use page object pattern for maintainable integration tests
- Test on real devices for accurate performance metrics
- Automate integration tests in CI/CD pipeline
### Debugging Tools
- Use `debugPrint` for development logging, remove in production
- Leverage Flutter Inspector for widget tree analysis
- Use Flutter DevTools for performance profiling and memory analysis
- Implement proper logging strategies with different severity levels
- Use breakpoints and step-through debugging effectively
### Code Analysis
- Configure `analysis_options.yaml` with comprehensive linting rules
- Use `dart analyze` to catch potential issues before runtime
- Run `dart format` to maintain consistent code formatting
- Use Flutter's built-in linting rules and consider additional packages
### Performance Testing
- Profile app performance using Flutter DevTools
- Monitor memory usage and identify potential leaks
- Test app performance on low-end devices
- Measure startup time and optimize critical paths
- Use Timeline view to identify UI performance bottlenecks
## CI/CD and Workflow
### GitHub Actions Integration
- Set up automated testing on pull requests
- Implement code formatting and linting checks
- Configure build automation for different platforms (iOS, Android, Web)
- Set up automated deployment to app stores or hosting platforms
- Include security scanning and dependency checks
### Version Management
- Use semantic versioning for app releases
- Maintain proper version numbering in `pubspec.yaml`
- Tag releases with clear release notes
- Implement changelog generation and maintenance
- Use Git flow or GitHub flow for branch management
### GitFlow Best Practices
- Use feature branches for new functionality
- Implement proper code review processes
- Maintain clean commit history with meaningful messages
- Use conventional commit messages for automated changelog generation
- Configure branch protection rules for main/master branch
### Build Configuration
- Configure build flavors for different environments (dev, staging, prod)
- Use environment-specific configuration files
- Implement proper signing and security configurations
- Set up automated builds for continuous integration
- Configure testing environments and deployment strategies
## Common Patterns
### Async/Await Patterns
- Use `async`/`await` for asynchronous operations instead of `.then()`
- Implement proper error handling with try-catch blocks in async functions
- Use `Future.wait()` for concurrent operations
- Implement timeout handling for network requests
- Use `StreamBuilder` for reactive data streams
### InheritedWidget and Provider Pattern
- Use `InheritedWidget` for passing data down the widget tree
- Implement Provider pattern for state management
- Use `Consumer` widgets for efficient rebuilds
- Leverage `Selector` for specific property listening
- Implement proper disposal in provider classes
### Theme and Styling Patterns
- Define app-wide themes using `ThemeData` and Material Design 3
- Use `Theme.of(context)` to access theme properties
- Implement dark and light theme support
- Create custom theme extensions for app-specific styling
- Use consistent spacing and typography throughout the app
### Navigation Patterns
- Use `Navigator.push()` and `Navigator.pop()` for basic navigation
- Implement named routes for complex navigation structures
- Use `GoRouter` or similar packages for advanced routing needs
- Handle deep linking and URL-based navigation for web
- Implement proper navigation state management
## Context Awareness
### Intent Recognition
- Analyze code context to suggest appropriate solutions
- Understand app architecture and suggest consistent patterns
- Recognize state management patterns and maintain consistency
- Suggest optimizations based on current code structure
### Clarifying Questions
- Ask about preferred state management approach when unclear
- Clarify API integration requirements and authentication methods
- Verify accessibility and internationalization requirements
- Confirm platform-specific implementation needs (iOS vs Android)
### Library and Tool Integration
- Suggest appropriate packages from pub.dev based on requirements
- Recommend testing frameworks that fit the project structure
- Suggest development tools for productivity improvement
- Consider package compatibility and maintenance status
### Architecture Considerations
- Suggest architectural patterns (Clean Architecture, MVVM, etc.)
- Recommend code organization strategies for scalability
- Consider performance implications of architectural decisions
- Suggest refactoring approaches for existing code
## Additional Notes
### Accessibility (a11y)
- Implement proper semantic labels with `Semantics` widget
- Use `semanticLabel` properties for images and interactive elements
- Test with screen readers and accessibility tools
- Follow WCAG guidelines for color contrast and text sizing
- Implement proper focus management for keyboard navigation
### Platform-Specific UI Considerations
- Use `Platform.isIOS` and `Platform.isAndroid` for platform-specific code
- Implement platform-adaptive widgets with `adaptive` constructors
- Consider iOS Human Interface Guidelines and Material Design differences
- Use platform-specific navigation patterns when appropriate
- Test thoroughly on both platforms for consistent user experience
### Performance Best Practices
- Avoid rebuilding expensive widgets unnecessarily
- Use `const` constructors wherever possible
- Implement proper disposal methods for resources
- Optimize image loading and caching strategies
- Monitor and optimize app startup time
### Avoiding Outdated Practices
- Avoid deprecated Flutter APIs and migrate to newer alternatives
- Don't use `StatefulWidget` when `StatelessWidget` suffices
- Avoid global variables and prefer dependency injection
- Don't ignore null-safety warnings and analyzer suggestions
- Avoid blocking the main thread with heavy computations
## Example Scenarios & Sample Code Suggestions
### Complete Widget Example
```dart
import 'package:flutter/material.dart';
class UserProfileCard extends StatelessWidget {
const UserProfileCard({
super.key,
required this.user,
this.onTap,
});
final User user;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Card(
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
CircleAvatar(
radius: 30,
backgroundImage: user.avatarUrl != null
? NetworkImage(user.avatarUrl!)
: null,
child: user.avatarUrl == null
? Text(user.initials)
: null,
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
user.name,
style: theme.textTheme.titleMedium,
),
if (user.email != null) ...[
const SizedBox(height: 4),
Text(
user.email!,
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
],
],
),
),
],
),
),
),
);
}
}
```
### Async Data Loading with Error Handling
```dart
class UserRepository {
final ApiClient _apiClient;
const UserRepository(this._apiClient);
Future<Result<List<User>>> getUsers() async {
try {
final response = await _apiClient.get('/users');
final users = (response.data as List)
.map((json) => User.fromJson(json))
.toList();
return Result.success(users);
} on NetworkException catch (e) {
return Result.failure(
AppError.network(
message: 'Failed to load users. Please check your connection.',
originalError: e,
),
);
} catch (e) {
return Result.failure(
AppError.unknown(
message: 'An unexpected error occurred.',
originalError: e,
),
);
}
}
}
```
### New Screen with Proper State Management
```dart
class UserListScreen extends ConsumerWidget {
const UserListScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final usersAsync = ref.watch(usersProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Users'),
actions: [
IconButton(
onPressed: () => ref.refresh(usersProvider),
icon: const Icon(Icons.refresh),
),
],
),
body: usersAsync.when(
data: (users) => ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return UserProfileCard(
user: user,
onTap: () => context.push('/user/${user.id}'),
);
},
),
loading: () => const Center(
child: CircularProgressIndicator(),
),
error: (error, stack) => ErrorView(
error: error,
onRetry: () => ref.refresh(usersProvider),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.push('/user/new'),
child: const Icon(Icons.add),
),
);
}
}
```
### Package Usage Example
```dart
// Example using HTTP package for API calls
import 'package:http/http.dart' as http;
import 'dart:convert';
class ApiClient {
final String baseUrl;
final http.Client _client;
ApiClient({
required this.baseUrl,
http.Client? client,
}) : _client = client ?? http.Client();
Future<ApiResponse> get(String endpoint) async {
try {
final uri = Uri.parse('$baseUrl$endpoint');
final response = await _client.get(
uri,
headers: {'Content-Type': 'application/json'},
).timeout(const Duration(seconds: 10));
if (response.statusCode >= 200 && response.statusCode < 300) {
return ApiResponse(
data: json.decode(response.body),
statusCode: response.statusCode,
);
} else {
throw ApiException(
statusCode: response.statusCode,
message: 'Request failed with status ${response.statusCode}',
);
}
} on TimeoutException {
throw NetworkException('Request timeout');
} on SocketException {
throw NetworkException('No internet connection');
}
}
void dispose() {
_client.close();
}
}
```
---
*These instructions provide comprehensive guidance for Flutter and Dart development with modern best practices, error handling, and code quality standards. Follow these guidelines to create maintainable, performant, and user-friendly Flutter applications.*

View File

@ -1,6 +1,6 @@
---
mode: "agent"
tools: ["codebase", "terminalCommand"]
tools: ["changes", "codebase", "editFiles", "problems"]
description: "Create ASP.NET Minimal API endpoints with proper OpenAPI documentation"
---

View File

@ -1,6 +1,6 @@
---
mode: "agent"
tools: ["codebase", "terminalCommand"]
tools: ["changes", "codebase", "editFiles", "problems"]
description: "Get best practices for C# async programming"
---

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
---
mode: "agent"
tools: ["codebase", "terminalCommand"]
tools: ["changes", "codebase", "editFiles", "problems", "runCommands"]
description: "Get best practices for Entity Framework Core"
---

View File

@ -0,0 +1,9 @@
---
mode: agent
tools: ['githubRepo', 'github', 'get_issue', 'get_issue_comments', 'get_me', 'list_issues']
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.
Suggest issues that I might want to focus on based on their age, the amount of comments, and their status (open/closed).

View File

@ -0,0 +1,15 @@
---
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"
---
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.
Describe the purpose and details of each pull request.
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.

View File

@ -8,7 +8,7 @@ function extractTitle(filePath) {
const content = fs.readFileSync(filePath, "utf8");
// For prompt files, look for the main heading after frontmatter
if (filePath.includes(".prompt.md")) {
if (filePath.includes(".prompt.md") || filePath.includes(".chatmode.md")) {
const lines = content.split("\n");
let inFrontmatter = false;
let frontmatterEnded = false;
@ -29,7 +29,10 @@ function extractTitle(filePath) {
}
// For prompt files without heading, clean up filename
const basename = path.basename(filePath, ".prompt.md");
const basename = path.basename(
filePath,
filePath.includes(".prompt.md") ? ".prompt.md" : ".chatmode.md"
);
return basename
.replace(/[-_]/g, " ")
.replace(/\b\w/g, (l) => l.toUpperCase());
@ -129,6 +132,7 @@ function extractDescription(filePath) {
function generateReadme() {
const instructionsDir = path.join(__dirname, "instructions");
const promptsDir = path.join(__dirname, "prompts");
const chatmodesDir = path.join(__dirname, "chatmodes");
const readmePath = path.join(__dirname, "README.md");
// Check if README file exists
@ -154,6 +158,14 @@ function generateReadme() {
.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 - rebuild the whole list
const instructionsSection = currentReadme.match(
/## 📋 Custom Instructions\n\nTeam and project-specific instructions.+?(?=\n\n>)/s
@ -165,7 +177,7 @@ function generateReadme() {
for (const file of instructionFiles) {
const filePath = path.join(instructionsDir, file);
const title = extractTitle(filePath);
const link = `instructions/${file}`;
const link = encodeURI(`instructions/${file}`);
// Check if there's a description in the frontmatter
const customDescription = extractDescription(filePath);
@ -204,132 +216,205 @@ function generateReadme() {
(file) => !existingPromptLinks.includes(file)
);
if (newPromptFiles.length === 0) {
console.log("No new prompts to add.");
return currentReadme; // No changes needed
}
if (newPromptFiles.length > 0) {
console.log(`Found ${newPromptFiles.length} new prompts to add.`);
console.log(`Found ${newPromptFiles.length} new prompts to add.`);
// Create content for new prompts (in Uncategorised section)
let newPromptsContent = "";
// 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);
// 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 title = extractTitle(filePath);
const description = extractDescription(filePath);
const link = `prompts/${file}`;
if (description) {
newPromptsContent += `- [${title}](${link}) - ${description}\n`;
} else {
newPromptsContent += `- [${title}](${link})\n`;
}
}
// Add a newline if we created a new section
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;
// If we need to add the section header
if (!hasUncategorisedSection) {
newPromptsContent += "### Uncategorised\n";
}
currentReadme =
currentReadme.slice(0, insertPos) +
newPromptsContent +
currentReadme.slice(insertPos);
} else {
// No Uncategorised section exists yet - find where to add it
// Look for the "Ready-to-use prompt templates" section and the next section after it
const promptSectionRegex =
/## 🎯 Reusable Prompts\n\nReady-to-use prompt templates/;
const promptSectionMatch = currentReadme.match(promptSectionRegex);
// Add each new prompt
for (const file of newPromptFiles) {
const filePath = path.join(promptsDir, file);
const title = extractTitle(filePath);
const description = extractDescription(filePath);
const link = encodeURI(`prompts/${file}`);
if (description) {
newPromptsContent += `- [${title}](${link}) - ${description}\n`;
} else {
newPromptsContent += `- [${title}](${link})\n`;
}
}
// Add a newline if we created a new section
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"
if (promptSectionMatch) {
// Find where to insert the new section - after any existing categories
let insertPos;
// First check if there are any existing categories
const existingCategoriesRegex = /### [^\n]+\n/g;
let lastCategoryMatch = null;
while ((match = existingCategoriesRegex.exec(currentReadme)) !== null) {
lastCategoryMatch = match;
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;
}
if (lastCategoryMatch) {
// 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);
currentReadme =
currentReadme.slice(0, insertPos) +
newPromptsContent +
currentReadme.slice(insertPos);
} else {
// No Uncategorised section exists yet - find where to add it
// Look for the "Ready-to-use prompt templates" section and the next section after it
const promptSectionRegex =
/## 🎯 Reusable Prompts\n\nReady-to-use prompt templates/;
const promptSectionMatch = currentReadme.match(promptSectionRegex);
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 (promptSectionMatch) {
// Find where to insert the new section - after any existing categories
let insertPos;
// First check if there are any existing categories
const existingCategoriesRegex = /### [^\n]+\n/g;
let lastCategoryMatch = null;
while ((match = existingCategoriesRegex.exec(currentReadme)) !== null) {
lastCategoryMatch = match;
}
if (lastCategoryMatch) {
// Find the end of the last category section
const afterLastCategory = currentReadme.slice(
lastCategoryMatch.index + lastCategoryMatch[0].length
);
if (insertPos === -1) {
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");
}
}
} 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;
if (insertPos !== -1) {
currentReadme =
currentReadme.slice(0, insertPos) +
newPromptsContent +
currentReadme.slice(insertPos);
} else {
// Fallback position - before Additional Resources
insertPos = currentReadme.indexOf("## 📚 Additional Resources");
console.error(
"Could not find a suitable place to insert new prompts."
);
}
}
if (insertPos !== -1) {
currentReadme =
currentReadme.slice(0, insertPos) +
newPromptsContent +
currentReadme.slice(insertPos);
} else {
console.error("Could not find a suitable place to insert new prompts.");
console.error(
"Could not find the Reusable Prompts section in the README."
);
}
} else {
console.error(
"Could not find the Reusable Prompts section in the README."
);
}
} else {
console.log("No new prompts to add.");
}
// Update chat modes section
const chatmodesSection = currentReadme.match(
/## 🎭 Custom Chat Modes\n\nCustom chat modes define.+?(?=\n\n>)/s
);
if (chatmodesSection && chatmodeFiles.length > 0) {
let chatmodesListContent = "\n\n";
// Generate list of chat mode links
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) {
// Use the description from frontmatter
chatmodesListContent += `- [${title}](${link}) - ${customDescription}\n`;
} else {
// Just add a link without description
chatmodesListContent += `- [${title}](${link})\n`;
}
}
// 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." +
chatmodesListContent;
currentReadme = currentReadme.replace(
chatmodesSection[0],
newChatmodesSection
);
} else if (!chatmodesSection && chatmodeFiles.length > 0) {
// Chat modes section doesn't exist yet but we have chat mode files
const chatmodesListContent = chatmodeFiles
.map((file) => {
const filePath = path.join(chatmodesDir, file);
const title = extractTitle(filePath);
const link = `chatmodes/${file}`;
const customDescription = extractDescription(filePath);
if (customDescription) {
return `- [${title}](${link}) - ${customDescription}`;
} else {
return `- [${title}](${link})`;
}
})
.join("\n");
const newChatmodesSection =
"## 🎭 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" +
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';
// Insert before Additional Resources section
const additionalResourcesPos = currentReadme.indexOf(
"## 📚 Additional Resources"
);
if (additionalResourcesPos !== -1) {
currentReadme =
currentReadme.slice(0, additionalResourcesPos) +
newChatmodesSection +
"\n" +
currentReadme.slice(additionalResourcesPos);
}
}