-
Notifications
You must be signed in to change notification settings - Fork 6
added skills and project.md for better ai support #110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
AlexisChoupault
merged 2 commits into
sncf-connect-tech:main
from
AlexisChoupault:ai-agents
Apr 2, 2026
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,235 @@ | ||
| --- | ||
| name: dart-modern-features | ||
| description: |- | ||
| Guidelines for using modern Dart features (v3.0+) such as Records, | ||
| Pattern Matching, Switch Expressions, Extension Types, Class Modifiers, | ||
| Wildcards, Null-Aware Elements, and Dot Shorthands. | ||
| --- | ||
|
|
||
| # Dart Modern Features | ||
|
|
||
| ## 1. When to use this skill | ||
| Use this skill when: | ||
| - Writing or reviewing Dart code targeting Dart 3.0 or later. | ||
| - Refactoring legacy Dart code to use modern, concise, and safe features. | ||
| - Looking for idiomatic ways to handle multiple return values, deep data | ||
| extraction, or exhaustive checking. | ||
|
|
||
| ## 2. Features | ||
|
|
||
| ### Records | ||
| Use records as anonymous, immutable, aggregate structures to bundle multiple | ||
| objects without defining a custom class. Prefer them for returning multiple | ||
| values from a function or grouping related data temporarily. | ||
|
|
||
| **Avoid:** | ||
| Creating a dedicated class for simple multiple-value returns. | ||
| ```dart | ||
| class UserResult { | ||
| final String name; | ||
| final int age; | ||
| UserResult(this.name, this.age); | ||
| } | ||
|
|
||
| UserResult fetchUser() { | ||
| return UserResult('Alice', 42); | ||
| } | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Using records to bundle types seamlessly on the fly. | ||
| ```dart | ||
| (String, int) fetchUser() { | ||
| return ('Alice', 42); | ||
| } | ||
|
|
||
| void main() { | ||
| var user = fetchUser(); | ||
| print(user.$1); // Alice | ||
| } | ||
| ``` | ||
|
|
||
| ### Patterns and Pattern Matching | ||
| Use patterns to destructure complex data into local variables and match against | ||
| specific shapes or values. Use them in `switch`, `if-case`, or variable | ||
| declarations to unpack data directly. | ||
|
|
||
| **Avoid:** | ||
| Manually checking types, nulls, and keys for data extraction. | ||
| ```dart | ||
| void processJson(Map<String, dynamic> json) { | ||
| if (json.containsKey('name') && json['name'] is String && | ||
| json.containsKey('age') && json['age'] is int) { | ||
| String name = json['name']; | ||
| int age = json['age']; | ||
| print('$name is $age years old.'); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Combining type-checking, validation, and assignment into a single statement. | ||
| ```dart | ||
| void processJson(Map<String, dynamic> json) { | ||
| if (json case {'name': String name, 'age': int age}) { | ||
| print('$name is $age years old.'); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Switch Expressions | ||
| Use switch expressions to return a value directly, eliminating bulky `case` and | ||
| `break` statements. | ||
|
|
||
| **Avoid:** | ||
| Using switch statements where every branch simply returns or assigns a value. | ||
| ```dart | ||
| String describeStatus(int code) { | ||
| switch (code) { | ||
| case 200: | ||
| return 'Success'; | ||
| case 404: | ||
| return 'Not Found'; | ||
| default: | ||
| return 'Unknown'; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Returning the evaluated expression directly using the `=>` syntax. | ||
| ```dart | ||
| String describeStatus(int code) => switch (code) { | ||
| 200 => 'Success', | ||
| 404 => 'Not Found', | ||
| _ => 'Unknown', | ||
| }; | ||
| ``` | ||
|
|
||
| ### Class Modifiers | ||
| Use class modifiers (`sealed`, `final`, `base`, `interface`) to restrict how | ||
| classes can be used outside their defined library. Prefer `sealed` for defining | ||
| closed families of subtypes to enable exhaustive checking. | ||
|
|
||
| **Avoid:** | ||
| Using open `abstract` classes when the set of subclasses is known and fixed. | ||
| ```dart | ||
| abstract class Result {} | ||
|
|
||
| class Success extends Result {} | ||
| class Failure extends Result {} | ||
|
|
||
| String handle(Result r) { | ||
| if (r is Success) return 'OK'; | ||
| if (r is Failure) return 'Error'; | ||
| return 'Unknown'; | ||
| } | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Using `sealed` to guarantee to the compiler that all cases are covered. | ||
| ```dart | ||
| sealed class Result {} | ||
|
|
||
| class Success extends Result {} | ||
| class Failure extends Result {} | ||
|
|
||
| String handle(Result r) => switch(r) { | ||
| Success() => 'OK', | ||
| Failure() => 'Error', | ||
| }; | ||
| ``` | ||
|
|
||
| ### Extension Types | ||
| Use extension types for a zero-cost wrapper around an existing type. Use them to | ||
| restrict operations or add custom behavior without runtime overhead. | ||
|
|
||
| **Avoid:** | ||
| Allocating new wrapper objects just for domain-specific logic or type safety. | ||
| ```dart | ||
| class Id { | ||
| final int value; | ||
| Id(this.value); | ||
| bool get isValid => value > 0; | ||
| } | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Using extension types which compile down to the underlying type at runtime. | ||
| ```dart | ||
| extension type Id(int value) { | ||
| bool get isValid => value > 0; | ||
| } | ||
| ``` | ||
|
|
||
| ### Digit Separators | ||
| Use underscores (`_`) in number literals strictly to improve visual readability | ||
| of large numeric values. | ||
|
|
||
| **Avoid:** | ||
| Long number literals that are difficult to read at a glance. | ||
| ```dart | ||
| const int oneMillion = 1000000; | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Using underscores to separate thousands or other groupings. | ||
| ```dart | ||
| const int oneMillion = 1_000_000; | ||
| ``` | ||
|
|
||
| ### Wildcard Variables | ||
| Use wildcards (`_`) as non-binding variables or parameters to explicitly signal | ||
| that a value is intentionally unused. | ||
|
|
||
| **Avoid:** | ||
| Inventing clunky, distinct variable names to avoid "unused variable" warnings. | ||
| ```dart | ||
| void handleEvent(String ignoredName, int status) { | ||
| print('Status: $status'); | ||
| } | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Explicitly dropping the binding with an underscore. | ||
| ```dart | ||
| void handleEvent(String _, int status) { | ||
| print('Status: $status'); | ||
| } | ||
| ``` | ||
|
|
||
| ### Null-Aware Elements | ||
| Use null-aware elements (`?`) inside collection literals to conditionally | ||
| include items only if they evaluate to a non-null value. | ||
|
|
||
| **Avoid:** | ||
| Using collection `if` statements for simple null checks. | ||
| ```dart | ||
| var names = [ | ||
| 'Alice', | ||
| if (optionalName != null) optionalName, | ||
| 'Charlie' | ||
| ]; | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Using the `?` prefix inline. | ||
| ```dart | ||
| var names = ['Alice', ?optionalName, 'Charlie']; | ||
| ``` | ||
|
|
||
| ### Dot Shorthands | ||
| Use dot shorthands to omit the explicit type name when it can be confidently | ||
| inferred from context, such as with enums or static fields. | ||
|
|
||
| **Avoid:** | ||
| Fully qualifying type names when the type is obvious from the context. | ||
| ```dart | ||
| LogLevel currentLevel = LogLevel.info; | ||
| ``` | ||
|
|
||
| **Prefer:** | ||
| Reducing visual noise with inferred shorthand. | ||
| ```dart | ||
| LogLevel currentLevel = .info; | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| --- | ||
| name: dart-test-fundamentals | ||
| description: |- | ||
| Core concepts and best practices for `package:test`. | ||
| Covers `test`, `group`, lifecycle methods (`setUp`, `tearDown`), and configuration (`dart_test.yaml`). | ||
| license: Apache-2.0 | ||
| --- | ||
|
|
||
| # Dart Test Fundamentals | ||
|
|
||
| ## When to use this skill | ||
| Use this skill when: | ||
| - Writing new test files. | ||
| - structuring test suites with `group`. | ||
| - Configuring test execution via `dart_test.yaml`. | ||
| - Understanding test lifecycle methods. | ||
|
|
||
| ## Core Concepts | ||
|
|
||
| ### 1. Test Structure (`test` and `group`) | ||
|
|
||
| - **`test`**: The fundamental unit of testing. | ||
| ```dart | ||
| test('description', () { | ||
| // assertions | ||
| }); | ||
| ``` | ||
| - **`group`**: Used to organize tests into logical blocks. | ||
| - Groups can be nested. | ||
| - Descriptions are concatenated (e.g., "Group Description Test Description"). | ||
| - Helps scope `setUp` and `tearDown` calls. | ||
| - **Naming**: Use `PascalCase` for groups that correspond to a class name | ||
| (e.g., `group('MyClient', ...)`). | ||
| - **Avoid Single Groups**: Do not wrap all tests in a file with a single | ||
| `group` call if it's the only one. | ||
|
|
||
| - **Naming Tests**: | ||
| - Avoid redundant "test" prefixes. | ||
| - Include the expected behavior or outcome in the description (e.g., | ||
| `'throws StateError'` or `'adds API key to URL'`). | ||
| - Descriptions should read well when concatenated with their group name. | ||
|
|
||
| - **Named Parameters Placement**: | ||
| - For `test` and `group` calls, place named parameters (e.g., `testOn`, | ||
| `timeout`, `skip`) immediately after the description string, before the | ||
| callback closure. This improves readability by keeping the test logic last. | ||
| ```dart | ||
| test('description', testOn: 'vm', () { | ||
| // assertions | ||
| }); | ||
| ``` | ||
|
|
||
| ### 2. Lifecycle Methods (`setUp`, `tearDown`) | ||
|
|
||
| - **`setUp`**: Runs *before* every `test` in the current `group` (and nested | ||
| groups). | ||
| - **`tearDown`**: Runs *after* every `test` in the current `group`. | ||
| - **`setUpAll`**: Runs *once* before any test in the group. | ||
| - **`tearDownAll`**: Runs *once* after all tests in the group. | ||
|
|
||
| **Best Practice:** | ||
| - Use `setUp` for resetting state to ensure test isolation. | ||
| - Avoid sharing mutable state between tests without resetting it. | ||
|
|
||
| ### 3. Configuration (`dart_test.yaml`) | ||
|
|
||
| The `dart_test.yaml` file configures the test runner. Common configurations | ||
| include: | ||
|
|
||
| #### Platforms | ||
| Define where tests run (vm, chrome, node). | ||
|
|
||
| ```yaml | ||
| platforms: | ||
| - vm | ||
| - chrome | ||
| ``` | ||
|
|
||
| #### Tags | ||
| Categorize tests to run specific subsets. | ||
|
|
||
| ```yaml | ||
| tags: | ||
| integration: | ||
| timeout: 2x | ||
| ``` | ||
|
|
||
| Usage in code: | ||
| ```dart | ||
| @Tags(['integration']) | ||
| import 'package:test/test.dart'; | ||
| ``` | ||
|
|
||
| Running tags: | ||
| `dart test --tags integration` | ||
|
|
||
| #### Timeouts | ||
| Set default timeouts for tests. | ||
|
|
||
| ```yaml | ||
| timeouts: | ||
| 2x # Double the default timeout | ||
| ``` | ||
|
|
||
| ### 4. File Naming | ||
| - Test files **must** end in `_test.dart` to be picked up by the test runner. | ||
| - Place tests in the `test/` directory. | ||
|
|
||
| ## Common commands | ||
|
|
||
| - `dart test`: Run all tests. | ||
| - `dart test test/path/to/file_test.dart`: Run a specific file. | ||
| - `dart test --name "substring"`: Run tests matching a description. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.