-
Notifications
You must be signed in to change notification settings - Fork 625
Add GitHub Copilot Agent Skills for .NET IoT repository #2473
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
base: main
Are you sure you want to change the base?
Changes from 5 commits
f589fb2
c18d766
9d5aa7f
28e767b
bebccf0
0723618
c321596
c1ffacf
07b3cb4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| # GitHub Copilot AI Skills for .NET IoT Repository | ||
|
|
||
| This directory contains AI skills that help GitHub Copilot agents perform specialized tasks in the .NET IoT repository. Skills are automatically loaded by Copilot based on context and task requirements. | ||
|
|
||
| ## Available Skills | ||
|
|
||
| ### 1. [add-device-binding](./add-device-binding/SKILL.md) | ||
| **Purpose:** Guide for adding new IoT device bindings following repository conventions. | ||
|
|
||
| **When to use:** | ||
| - Adding a new sensor, display, motor, or other hardware device binding | ||
| - Creating driver code under `src/devices/<DeviceName>` | ||
| - Ensuring device follows .NET IoT patterns | ||
|
|
||
| **Key features:** | ||
| - Device structure setup | ||
| - API design patterns (TryRead* methods, UnitsNet types) | ||
| - Resource management (IDisposable) | ||
| - Documentation requirements | ||
| - Sample application guidelines | ||
|
|
||
| ### 2. [debug-build-issues](./debug-build-issues/SKILL.md) | ||
| **Purpose:** Diagnose and resolve build, compilation, and SDK issues. | ||
|
|
||
| **When to use:** | ||
| - Build fails with SDK resolution errors | ||
| - Package restore failures | ||
| - Long-running build timeouts | ||
| - CI/CD pipeline failures | ||
| - Memory issues during build | ||
|
|
||
| **Key features:** | ||
| - Azure DevOps feeds troubleshooting | ||
| - Common build issues and solutions | ||
| - Alternative build approaches | ||
| - Expected timing reference | ||
| - Log location guidance | ||
|
|
||
| ### 3. [fix-api-conventions](./fix-api-conventions/SKILL.md) | ||
| **Purpose:** Ensure device bindings follow repository API conventions. | ||
|
|
||
| **When to use:** | ||
| - Reviewing device binding code | ||
| - Fixing API design issues | ||
| - Code review identifies convention violations | ||
| - Modernizing older device bindings | ||
|
|
||
| **Key features:** | ||
| - API naming conventions | ||
| - UnitsNet usage patterns | ||
| - Constructor design guidelines | ||
| - Resource management patterns | ||
| - Error handling best practices | ||
|
|
||
| ### 4. [update-device-documentation](./update-device-documentation/SKILL.md) | ||
| **Purpose:** Create and maintain comprehensive device documentation. | ||
|
|
||
| **When to use:** | ||
| - Adding documentation for new device | ||
| - Updating existing device docs | ||
| - Adding wiring diagrams | ||
| - Improving code examples | ||
| - Adding XML documentation | ||
|
|
||
| **Key features:** | ||
| - README structure and content | ||
| - Wiring information templates | ||
| - XML documentation patterns | ||
| - Code example guidelines | ||
| - Markdown linting compliance | ||
|
|
||
| ### 5. [hardware-abstraction-check](./hardware-abstraction-check/SKILL.md) | ||
| **Purpose:** Verify proper hardware abstraction and cross-platform compatibility. | ||
|
|
||
| **When to use:** | ||
| - Reviewing new device binding code | ||
| - Code contains platform-specific APIs | ||
| - Ensuring cross-platform compatibility | ||
| - Validating no OS dependencies introduced | ||
|
|
||
| **Key features:** | ||
| - Anti-pattern detection (P/Invoke, hardcoded paths) | ||
| - System.Device.* abstraction usage | ||
| - Automated compliance checks | ||
| - Cross-platform testing guidance | ||
| - Platform-specific code guidelines | ||
|
|
||
| ## How Skills Work | ||
|
|
||
| GitHub Copilot agents automatically discover and use these skills when: | ||
| 1. Task matches skill description | ||
| 2. Agent needs domain-specific guidance | ||
| 3. Context indicates skill would be helpful | ||
|
|
||
| Skills are defined using the standard GitHub Copilot Agent Skills format: | ||
| - Each skill has its own directory | ||
| - `SKILL.md` file contains metadata (YAML frontmatter) and instructions | ||
| - Skills can include supporting files (scripts, examples, templates) | ||
|
|
||
| ## Skill Format | ||
|
|
||
| Each `SKILL.md` follows this structure: | ||
|
|
||
| ```markdown | ||
| --- | ||
| name: skill-name | ||
| description: Brief description of what the skill does | ||
| license: MIT | ||
| --- | ||
|
|
||
| ## Purpose | ||
| What the skill helps with | ||
|
|
||
| ## When to Use This Skill | ||
| Specific scenarios for using the skill | ||
|
|
||
| ## Instructions | ||
| Detailed step-by-step guidance | ||
|
|
||
| ## Examples | ||
| Code examples and demonstrations | ||
|
|
||
| ## References | ||
| Links to related documentation | ||
| ``` | ||
|
|
||
| ## Creating New Skills | ||
|
|
||
| To add a new skill: | ||
|
|
||
| 1. Create directory: `.github/skills/<skill-name>/` | ||
| 2. Create `SKILL.md` with proper frontmatter | ||
| 3. Include clear instructions and examples | ||
| 4. Add references to relevant documentation | ||
| 5. Test skill with Copilot agent | ||
|
|
||
| ## Skill Development Guidelines | ||
|
|
||
| When creating or updating skills: | ||
|
|
||
| - **Be specific:** Provide concrete, actionable instructions | ||
| - **Include examples:** Show code examples and commands | ||
| - **Reference documentation:** Link to relevant docs and conventions | ||
| - **Keep focused:** Each skill should address one specific domain | ||
| - **Test thoroughly:** Ensure instructions work as documented | ||
|
|
||
| ## Relationship to Copilot Instructions | ||
|
|
||
| These skills complement the main [copilot-instructions.md](../copilot-instructions.md): | ||
|
|
||
| - **Copilot Instructions:** General guidance loaded for all tasks | ||
| - **Skills:** Specialized, task-specific guidance loaded on-demand | ||
|
|
||
| Skills should reference and build upon copilot instructions, not duplicate them. | ||
|
|
||
| ## Contributing | ||
|
|
||
| When adding new skills, consider: | ||
| - Common issues encountered in the repository | ||
| - Repetitive tasks that need guidance | ||
| - Complex procedures that benefit from step-by-step instructions | ||
| - Platform-specific knowledge (build system, conventions, etc.) | ||
|
|
||
| ## References | ||
|
|
||
| - [GitHub Copilot Agent Skills Documentation](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills) | ||
| - [.NET IoT Copilot Instructions](../copilot-instructions.md) | ||
| - [.NET IoT Contributing Guide](../../Documentation/CONTRIBUTING.md) | ||
| - [Device Conventions](../../Documentation/Devices-conventions.md) |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,226 @@ | ||||||
| --- | ||||||
| name: add-device-binding | ||||||
| description: Guide for adding new IoT device bindings to the repository following .NET IoT conventions | ||||||
| license: MIT | ||||||
| --- | ||||||
|
|
||||||
| ## Purpose | ||||||
|
|
||||||
| This skill helps Copilot agents create new IoT device bindings (sensors, displays, motors, etc.) that follow the repository's established patterns and conventions for System.Device.Gpio and Iot.Device.Bindings. | ||||||
|
|
||||||
| ## When to Use This Skill | ||||||
|
|
||||||
| - Developer requests adding a new device binding for a sensor, display, motor, or other hardware component | ||||||
| - Creating a new driver under `src/devices/<DeviceName>` | ||||||
| - Need to ensure the device follows .NET IoT conventions and patterns | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated all skill files to use full GitHub URLs instead of relative paths. This makes the references more portable and clear. Changed in commit 28e767b. Files updated:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @copilot I didn't mean to change relative links to absolute but rather to link this specific "Device Convention" reference. relative paths are better
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reverted to relative paths in all References sections. The Device Conventions and other internal documentation links now use relative paths for better in-repository navigation. Changed in commit 0723618. |
||||||
|
|
||||||
| ## Instructions | ||||||
|
|
||||||
| ### 1. Device Structure Setup | ||||||
|
|
||||||
| Create the following directory structure under `src/devices/<DeviceName>`: | ||||||
|
|
||||||
| ```text | ||||||
| src/devices/<DeviceName>/ | ||||||
| ├── <DeviceName>.csproj | ||||||
| ├── <DeviceName>.cs (main class) | ||||||
| ├── samples/ | ||||||
| │ ├── <DeviceName>.Samples.csproj | ||||||
| │ └── Program.cs | ||||||
| ├── tests/ (if applicable) | ||||||
| │ └── <DeviceName>.Tests.csproj | ||||||
| └── README.md | ||||||
| ``` | ||||||
|
|
||||||
| ### 2. Constructor & Dependencies | ||||||
|
|
||||||
| - Accept hardware transports from the caller: `I2cDevice`, `SpiDevice`, `GpioController`, pin numbers, bus addresses | ||||||
| - Provide sensible defaults (e.g., common I²C addresses like 0x48) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed "I²C" to "I2C" for consistency. Updated in commit c321596. |
||||||
| - **Never hardcode board-specific details** | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @copilot what does this mean
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarified with examples: "Never hardcode board-specific details (e.g., GPIO pin numbers, bus IDs, or hardware paths like |
||||||
| - Avoid singletons and global state | ||||||
|
|
||||||
| **Example Constructor:** | ||||||
|
|
||||||
| ```csharp | ||||||
| public Bmp280(I2cDevice i2cDevice, I2cAddress address = I2cAddress.Primary) | ||||||
| { | ||||||
| _i2cDevice = i2cDevice ?? throw new ArgumentNullException(nameof(i2cDevice)); | ||||||
| _address = address; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ### 3. API Design Patterns | ||||||
|
|
||||||
| - Use **`TryRead*` methods** that return `bool` and set `out` parameters for sensor readings | ||||||
|
|
||||||
| ```csharp | ||||||
| public bool TryReadTemperature(out Temperature temperature) | ||||||
| ``` | ||||||
|
|
||||||
|
|
||||||
| - Use **UnitsNet** types for physical quantities (Temperature, Pressure, Length, etc.) | ||||||
| - Properties for values that don't change between calls | ||||||
| - Methods for values that may change | ||||||
| - Use enums/flags for registers, modes, scales | ||||||
| - Keep synchronous APIs predictable; only use `async` if genuine I/O concurrency needed | ||||||
|
|
||||||
| ### 4. Resource Management (CRITICAL) | ||||||
|
|
||||||
| - **MUST implement `IDisposable`** | ||||||
| - Dispose hardware resources (I2C/SPI devices, GPIO pins) in the Dispose method | ||||||
| - If transport is passed by caller, dispose it unless `shouldDispose` flag says otherwise | ||||||
| - Design for failure: ensure exceptions leave device in consistent state | ||||||
|
|
||||||
| **Example Disposal:** | ||||||
|
|
||||||
| ```csharp | ||||||
| protected virtual void Dispose(bool disposing) | ||||||
| { | ||||||
| if (_disposed) | ||||||
| return; | ||||||
|
|
||||||
| if (disposing) | ||||||
| { | ||||||
| _i2cDevice?.Dispose(); | ||||||
| _i2cDevice = null; | ||||||
| } | ||||||
|
|
||||||
| _disposed = true; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ### 5. Error Handling | ||||||
|
|
||||||
| - Guard against misuse with `ArgumentException`/`ArgumentNullException` | ||||||
| - For transient hardware issues, throw or return `false` in `Try*` patterns | ||||||
| - **Never return bogus data silently** | ||||||
| - Validate checksums/status bits where appropriate | ||||||
|
|
||||||
| ### 6. Documentation Requirements | ||||||
|
|
||||||
| - XML documentation comments on all public APIs | ||||||
| - **Include units** in comments (°C, Pa, %RH, lux, etc.) | ||||||
| - Document parameter ownership (does caller own the transport?) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @copilot clarify: there should always be a way for device to not own the transport
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarified that devices MUST provide a way for caller to retain ownership of transports via |
||||||
| - README.md with: | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
read several READMEs in this repo and try to figure out and document conventions here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documented README conventions based on analysis of existing device bindings (BMP180, HMC5883L, Bmxx80, LM75, ADS1115, Ahtxx): Title format: Documentation section: Must be Required sections: Updated in commit c1ffacf. |
||||||
| - Device description and capabilities | ||||||
| - Wiring diagram or connection instructions | ||||||
| - Required pull-ups/pull-downs | ||||||
| - Expected ranges and units | ||||||
| - Code example demonstrating usage | ||||||
|
|
||||||
| ### 7. Sample Application | ||||||
|
|
||||||
| Create a runnable sample in `samples/Program.cs`: | ||||||
|
|
||||||
| - Keep it simple and readable | ||||||
| - Demonstrate typical usage patterns | ||||||
| - Show proper disposal (using statements) | ||||||
| - Handle exceptions gracefully | ||||||
| - Don't hardcode board-specific paths | ||||||
|
|
||||||
| **Example Sample:** | ||||||
|
|
||||||
| ```csharp | ||||||
| using System; | ||||||
| using System.Device.I2c; | ||||||
| using Iot.Device.Bmp280; | ||||||
|
|
||||||
| using I2cDevice i2cDevice = I2cDevice.Create(new I2cConnectionSettings(1, Bmp280.DefaultI2cAddress)); | ||||||
| using Bmp280 sensor = new(i2cDevice); | ||||||
|
|
||||||
| while (true) | ||||||
| { | ||||||
| if (sensor.TryReadTemperature(out Temperature temp)) | ||||||
| { | ||||||
| Console.WriteLine($"Temperature: {temp.DegreesCelsius:F2} °C"); | ||||||
| } | ||||||
| Thread.Sleep(1000); | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ### 8. Cross-Platform Considerations | ||||||
|
|
||||||
| - Use **System.Device.*** abstractions exclusively | ||||||
| - No P/Invoke or OS-specific syscalls | ||||||
| - No hardcoded paths to `/sys` or `/proc` | ||||||
| - If a feature is platform-only, guard it and fail gracefully | ||||||
|
|
||||||
| ### 9. Testing | ||||||
|
|
||||||
| - Add unit tests for logic that can be isolated from hardware | ||||||
| - Focus on: framing/parsing functions, calculations, protocol logic | ||||||
| - Hardware-dependent tests should be clearly marked | ||||||
| - Ensure samples compile even without hardware | ||||||
|
|
||||||
| ### 10. Build Validation | ||||||
|
|
||||||
| After creating the device: | ||||||
|
|
||||||
| ```bash | ||||||
| cd src/devices/<DeviceName> | ||||||
| ../../../dotnet.sh build | ||||||
|
|
||||||
| cd samples | ||||||
| ../../../../dotnet.sh build | ||||||
|
|
||||||
| # Check for hardware abstraction violations | ||||||
| grep -r "Environment.OSVersion\|DllImport\|P/Invoke" . | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @copilot this seem like some bogus step, no one has any clue what this means
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed the confusing grep command. Hardware abstraction checking is already covered by the dedicated |
||||||
| ``` | ||||||
|
|
||||||
| ## Review Checklist | ||||||
|
|
||||||
| Before completing: | ||||||
|
|
||||||
| - [ ] Public API follows repo naming/style | ||||||
| - [ ] Members are XML-documented with units (°C, Pa, %RH, lux, etc.) | ||||||
| - [ ] Constructor accepts caller-provided transports | ||||||
| - [ ] Implements `IDisposable`; all hardware resources released | ||||||
| - [ ] Uses enums/consts for registers/addresses | ||||||
| - [ ] Validates timing and checksums | ||||||
| - [ ] `Try*` methods return accurate success/failure | ||||||
| - [ ] Adds sample application | ||||||
| - [ ] Adds device README with wiring info | ||||||
| - [ ] Adds tests for hardware-independent logic | ||||||
| - [ ] Builds successfully without errors | ||||||
| - [ ] No platform-specific code or P/Invoke | ||||||
|
|
||||||
| ## Examples | ||||||
|
|
||||||
| ### Good Device Binding Example | ||||||
|
|
||||||
| ```csharp | ||||||
| public class Dht22 : IDisposable | ||||||
| { | ||||||
| private GpioController? _controller; | ||||||
| private readonly int _pin; | ||||||
| private readonly bool _shouldDispose; | ||||||
|
|
||||||
| public Dht22(int pin, GpioController? controller = null, bool shouldDispose = true) | ||||||
| { | ||||||
| _pin = pin; | ||||||
| _shouldDispose = shouldDispose || controller is null; | ||||||
| _controller = controller ?? new GpioController(); | ||||||
| } | ||||||
|
|
||||||
| public bool TryReadTemperature(out Temperature temperature) | ||||||
| { | ||||||
| // Implementation that validates data and checksums | ||||||
| } | ||||||
|
|
||||||
| public void Dispose() | ||||||
| { | ||||||
| if (_shouldDispose) | ||||||
| { | ||||||
| _controller?.Dispose(); | ||||||
| } | ||||||
| _controller = null; | ||||||
| } | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ## References | ||||||
|
|
||||||
| - [Device Conventions](https://github.com/dotnet/iot/blob/main/Documentation/Devices-conventions.md) | ||||||
| - [Contributing Guidelines](https://github.com/dotnet/iot/blob/main/Documentation/CONTRIBUTING.md) | ||||||
| - [Copilot Instructions](https://github.com/dotnet/iot/blob/main/.github/copilot-instructions.md) | ||||||
| - [UnitsNet Library](https://github.com/angularsen/UnitsNet) | ||||||
Uh oh!
There was an error while loading. Please reload this page.