Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 59 additions & 65 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ Major test projects:

Find all tests: `find . -name "*.UnitTests.csproj"`

### CI Pipelines (Azure DevOps)

When referencing or triggering CI pipelines, use these current pipeline names:

| Pipeline | Name | Purpose |
|----------|------|---------|
| Overall CI | `maui-pr` | Full PR validation build |
| Device Tests | `maui-pr-devicetests` | Helix-based device tests |
| UI Tests | `maui-pr-uitests` | Appium-based UI tests |

**⚠️ Old pipeline names** (e.g., `MAUI-UITests-public`, `MAUI-public`) are **outdated** and should NOT be used. Always use the names above.

### Code Formatting

Always format code before committing:
Expand Down Expand Up @@ -126,26 +138,6 @@ When working with public API changes:
- **Use `dotnet format analyzers`** if having trouble
- **If files are incorrect**: Revert all changes, then add only the necessary new API entries

**🚨 CRITICAL: `#nullable enable` must be line 1**

Every `PublicAPI.Unshipped.txt` file starts with `#nullable enable` (often BOM-prefixed: `#nullable enable`) on the **first line**. If this line is moved or removed, the analyzer treats it as a declared API symbol and emits **RS0017** errors.

**Never sort these files with plain `sort`** — the BOM bytes (`0xEF 0xBB 0xBF`) sort after ASCII characters under `LC_ALL=C`, pushing `#nullable enable` to the bottom of the file.

When resolving merge conflicts or adding entries, use this safe pattern that preserves line 1:
```bash
for f in $(git diff --name-only --diff-filter=U | grep "PublicAPI.Unshipped.txt"); do
# Extract and preserve the #nullable enable line (with or without BOM)
HEADER=$(head -1 "$f" | grep -o '.*#nullable enable' || echo '#nullable enable')
# Strip conflict markers, remove all #nullable lines, sort+dedup the API entries
grep -v '^<<<<<<\|^======\|^>>>>>>\|#nullable enable' "$f" | LC_ALL=C sort -u | sed '/^$/d' > /tmp/api_fix.txt
# Reassemble: header first, then sorted entries
printf '%s\n' "$HEADER" > "$f"
cat /tmp/api_fix.txt >> "$f"
git add "$f"
done
```

### Branching
- `main` - For bug fixes without API changes
- `net10.0` - For new features and API changes
Expand Down Expand Up @@ -189,16 +181,23 @@ git commit -m "Fix: Description of the change"
2. Exception: If the user's instructions explicitly include pushing, proceed without asking.

### Documentation

- Update XML documentation for public APIs
- Follow existing code documentation patterns
- Update relevant docs in `docs/` folder when needed

**Platform-Specific Documentation:**
- `.github/instructions/safe-area-ios.instructions.md` - Safe area investigation (iOS/macCatalyst)
- `.github/instructions/uitests.instructions.md` - UI test guidelines (includes safe area testing section)
- `.github/instructions/android.instructions.md` - Android handler implementation
- `.github/instructions/xaml-unittests.instructions.md` - XAML unit test guidelines
### Opening PRs

All PRs are required to have this at the top of the description:

```
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you!
```

Always put that at the top, without the block quotes. Without it, users will NOT be able to try the PR and your work will have been in vain!



## Custom Agents and Skills
Expand All @@ -216,18 +215,24 @@ The repository includes specialized custom agents and reusable skills for specif

### Available Custom Agents

1. **write-tests-agent** - Agent for writing tests. Determines test type (UI vs XAML) and invokes the appropriate skill (`write-ui-tests`, `write-xaml-tests`)
1. **pr** - Sequential 4-phase workflow for reviewing and working on PRs
- **Use when**: A PR already exists and needs review or work, OR an issue needs a fix
- **Capabilities**: PR review, test verification, fix exploration, alternative comparison
- **Trigger phrases**: "review PR #XXXXX", "work on PR #XXXXX", "fix issue #XXXXX", "continue PR #XXXXX"
- **Do NOT use for**: Just running tests manually → Use `sandbox-agent`

2. **write-tests-agent** - Agent for writing tests. Determines test type (UI vs XAML) and invokes the appropriate skill (`write-ui-tests`, `write-xaml-tests`)
- **Use when**: Creating new tests for issues or PRs
- **Capabilities**: Test type determination (UI and XAML), skill invocation, test verification
- **Trigger phrases**: "write tests for #XXXXX", "create tests", "add test coverage"

2. **sandbox-agent** - Specialized agent for working with the Sandbox app for testing, validation, and experimentation
3. **sandbox-agent** - Specialized agent for working with the Sandbox app for testing, validation, and experimentation
- **Use when**: User wants to manually test PR functionality or reproduce issues
- **Capabilities**: Sandbox app setup, Appium-based manual testing, PR functional validation
- **Trigger phrases**: "test this PR", "validate PR #XXXXX in Sandbox", "reproduce issue #XXXXX", "try out in Sandbox"
- **Do NOT use for**: Code review (use `pr-review` skill), writing automated tests (use write-tests-agent)
- **Do NOT use for**: Code review (use pr agent), writing automated tests (use write-tests-agent)

3. **learn-from-pr** - Extracts lessons from PRs and applies improvements to the repository
4. **learn-from-pr** - Extracts lessons from PRs and applies improvements to the repository
- **Use when**: After complex PR, want to improve instruction files/skills based on lessons learned
- **Capabilities**: Analyzes PR, identifies failure modes, applies improvements to instruction files, skills, code comments
- **Trigger phrases**: "learn from PR #XXXXX and apply improvements", "improve repo based on what we learned", "update skills based on PR"
Expand All @@ -240,90 +245,79 @@ Skills are modular capabilities that can be invoked directly or used by agents.

#### User-Facing Skills

1. **pr-review** (`.github/skills/pr-review/SKILL.md`)
- **Purpose**: End-to-end PR review orchestrator — follows phase instructions: pr-preflight, pr-gate, try-fix, pr-report
- **Trigger phrases**: "review PR #XXXXX", "work on PR #XXXXX", "fix issue #XXXXX", "continue PR #XXXXX"
- **Capabilities**: Multi-model fix exploration, test verification, alternative comparison, PR review recommendation
- **Do NOT use for**: Just running tests manually → Use `sandbox-agent`
- **Phase instructions** (in `.github/pr-review/`):
- `pr-preflight.md` — Context gathering from issue/PR
- `pr-gate.md` — Verify tests FAIL without fix, PASS with fix
- `pr-report.md` — Final recommendation
- **Phase skill**: `try-fix` — Multi-model fix exploration

3. **issue-triage** (`.github/skills/issue-triage/SKILL.md`)
1. **issue-triage** (`.github/skills/issue-triage/SKILL.md`)
- **Purpose**: Query and triage open issues that need milestones, labels, or investigation
- **Trigger phrases**: "find issues to triage", "show me old Android issues", "what issues need attention"
- **Scripts**: `init-triage-session.ps1`, `query-issues.ps1`, `record-triage.ps1`

4. **find-reviewable-pr** (`.github/skills/find-reviewable-pr/SKILL.md`)
2. **find-reviewable-pr** (`.github/skills/find-reviewable-pr/SKILL.md`)
- **Purpose**: Finds open PRs in dotnet/maui and dotnet/docs-maui that need review
- **Trigger phrases**: "find PRs to review", "show milestoned PRs", "find partner PRs"
- **Scripts**: `query-reviewable-prs.ps1`
- **Categories**: P/0, milestoned, partner, community, recent, docs-maui

5. **pr-finalize** (`.github/skills/pr-finalize/SKILL.md`)
3. **pr-finalize** (`.github/skills/pr-finalize/SKILL.md`)
- **Purpose**: Verifies PR title and description match actual implementation, AND performs code review for best practices before merge.
- **Trigger phrases**: "finalize PR #XXXXX", "check PR description for #XXXXX", "review commit message"
- **Used by**: Before merging any PR, when description may be stale
- **Note**: Does NOT require agent involvement or session markdown - works on any PR
- **🚨 CRITICAL**: NEVER use `--approve` or `--request-changes` - only post comments. Approval is a human decision.

6. **learn-from-pr** (`.github/skills/learn-from-pr/SKILL.md`)
4. **code-review** (`.github/skills/code-review/SKILL.md`)
- **Purpose**: Reviews PR code changes for correctness, safety, and consistency with MAUI conventions. Walks through a MAUI-specific checklist covering handler lifecycle, platform code, safe area, threading, public API, and test patterns.
- **Trigger phrases**: "review code for PR #XXXXX", "code review PR #XXXXX", "review this PR's code"
- **Note**: Standalone skill — uses independence-first assessment (reads code before PR description to avoid anchoring bias). Can be used by any agent or invoked directly.
- **🚨 CRITICAL**: NEVER use `--approve` or `--request-changes` — only post comments. Approval is a human decision.

5. **learn-from-pr** (`.github/skills/learn-from-pr/SKILL.md`)
- **Purpose**: Analyzes completed PR to identify repository improvements (analysis only, no changes applied)
- **Trigger phrases**: "what can we learn from PR #XXXXX?", "how can we improve agents based on PR #XXXXX?"
- **Used by**: After complex PRs, when agent struggled to find solution
- **Output**: Prioritized recommendations for instruction files, skills, code comments
- **Note**: For applying changes automatically, use the learn-from-pr agent instead

7. **write-ui-tests** (`.github/skills/write-ui-tests/SKILL.md`)
6. **write-ui-tests** (`.github/skills/write-ui-tests/SKILL.md`)
- **Purpose**: Creates UI tests for GitHub issues and verifies they reproduce the bug
- **Trigger phrases**: "write UI tests for #XXXXX", "create UI test for issue", "add UI test coverage"
- **Output**: Test files that fail without fix, pass with fix

8. **write-xaml-tests** (`.github/skills/write-xaml-tests/SKILL.md`)
7. **write-xaml-tests** (`.github/skills/write-xaml-tests/SKILL.md`)
- **Purpose**: Creates XAML unit tests for XAML parsing, compilation, and source generation
- **Trigger phrases**: "write XAML tests for #XXXXX", "test XamlC behavior", "reproduce XAML parsing bug"
- **Output**: Test files for Controls.Xaml.UnitTests

9. **verify-tests-fail-without-fix** (`.github/skills/verify-tests-fail-without-fix/SKILL.md`)
8. **verify-tests-fail-without-fix** (`.github/skills/verify-tests-fail-without-fix/SKILL.md`)
- **Purpose**: Verifies UI tests catch the bug before fix and pass with fix
- **Two modes**: Verify failure only (test creation) or full verification (test + fix)
- **Used by**: After creating tests, before considering PR complete

10. **azdo-build-investigator** (`.github/skills/azdo-build-investigator/SKILL.md`)
- **Purpose**: Investigates CI failures for PRs build errors, Helix test logs, and binlog analysis. Delegates to the `ci-analysis` skill from the dotnet/arcade-skills plugin.
- **Trigger phrases**: "check build for PR #XXXXX", "why did PR build fail", "get build status", "what's failing on PR", "Helix failures"
9. **pr-build-status** (`.github/skills/pr-build-status/SKILL.md`)
- **Purpose**: Retrieves Azure DevOps build information for PRs (build IDs, stage status, failed jobs)
- **Trigger phrases**: "check build for PR #XXXXX", "why did PR build fail", "get build status"
- **Used by**: When investigating CI failures

11. **run-integration-tests** (`.github/skills/run-integration-tests/SKILL.md`)
10. **run-integration-tests** (`.github/skills/run-integration-tests/SKILL.md`)
- **Purpose**: Build, pack, and run .NET MAUI integration tests locally
- **Trigger phrases**: "run integration tests", "test templates locally", "run macOSTemplates tests", "run RunOniOS tests"
- **Categories**: Build, WindowsTemplates, macOSTemplates, Blazor, MultiProject, Samples, AOT, RunOnAndroid, RunOniOS
- **Note**: **ALWAYS use this skill** instead of manual `dotnet test` commands for integration tests

12. **evaluate-pr-tests** (`.github/skills/evaluate-pr-tests/SKILL.md`)
- **Purpose**: Evaluates tests added in a PR for coverage, quality, edge cases, and test type appropriateness
- **Trigger phrases**: "evaluate tests in PR #XXXXX", "review test quality", "are these tests good enough", "check test coverage"
- **Scripts**: `Gather-TestContext.ps1`
- **Checks**: Fix coverage, edge case gaps, test type preference (unit > device > UI), conventions, flakiness risk, duplicate coverage, platform scope, assertion quality

#### Internal Skills (Used by Skills/Agents)
#### Internal Skills (Used by Agents)

12. **try-fix** (`.github/skills/try-fix/SKILL.md`)
11. **try-fix** (`.github/skills/try-fix/SKILL.md`)
- **Purpose**: Proposes ONE independent fix approach, applies it, tests, records result with failure analysis, then reverts
- **Used by**: `pr-review` skill Phase 3 (Try-Fix phase) - rarely invoked directly by users
- **Used by**: pr agent Phase 3 (Fix phase) - rarely invoked directly by users
- **Behavior**: Reads prior attempts to learn from failures. Max 5 attempts per session.
- **Output**: Updates session markdown with attempt results and failure analysis

### Using Custom Agents and Skills
### Using Custom Agents

**Delegation Policy**: When user request matches skill/agent trigger phrases, **ALWAYS invoke the appropriate skill or delegate to the agent immediately**. Do not ask for permission or explain alternatives unless the request is ambiguous.
**Delegation Policy**: When user request matches agent trigger phrases, **ALWAYS delegate to the appropriate agent immediately**. Do not ask for permission or explain alternatives unless the request is ambiguous.

**Examples of correct delegation**:
- User: "Review PR #12345" → Immediately invoke **pr-review** skill
- User: "Review PR #12345" → Immediately invoke **pr** agent
- User: "Test this PR" → Immediately invoke **sandbox-agent**
- User: "Fix issue #67890" → Immediately invoke **pr-review** skill
- User: "Fix issue #67890" (no PR exists) → Suggest using `/delegate` command
- User: "Write tests for issue #12345" → Immediately invoke **write-tests-agent**

**When NOT to delegate**:
Expand Down
Loading
Loading