diff --git a/.github/skills/add-api/SKILL.md b/.claude/skills/add-api/SKILL.md similarity index 100% rename from .github/skills/add-api/SKILL.md rename to .claude/skills/add-api/SKILL.md diff --git a/.github/skills/add-api/references/checklists.md b/.claude/skills/add-api/references/checklists.md similarity index 100% rename from .github/skills/add-api/references/checklists.md rename to .claude/skills/add-api/references/checklists.md diff --git a/.github/skills/add-api/references/troubleshooting.md b/.claude/skills/add-api/references/troubleshooting.md similarity index 100% rename from .github/skills/add-api/references/troubleshooting.md rename to .claude/skills/add-api/references/troubleshooting.md diff --git a/.github/skills/api-docs/SKILL.md b/.claude/skills/api-docs/SKILL.md similarity index 100% rename from .github/skills/api-docs/SKILL.md rename to .claude/skills/api-docs/SKILL.md diff --git a/.github/skills/api-docs/references/checklist.md b/.claude/skills/api-docs/references/checklist.md similarity index 100% rename from .github/skills/api-docs/references/checklist.md rename to .claude/skills/api-docs/references/checklist.md diff --git a/.github/skills/api-docs/references/patterns.md b/.claude/skills/api-docs/references/patterns.md similarity index 100% rename from .github/skills/api-docs/references/patterns.md rename to .claude/skills/api-docs/references/patterns.md diff --git a/.github/skills/issue-bulk-process/SKILL.md b/.claude/skills/issue-bulk-process/SKILL.md similarity index 100% rename from .github/skills/issue-bulk-process/SKILL.md rename to .claude/skills/issue-bulk-process/SKILL.md diff --git a/.github/skills/issue-fix/SKILL.md b/.claude/skills/issue-fix/SKILL.md similarity index 99% rename from .github/skills/issue-fix/SKILL.md rename to .claude/skills/issue-fix/SKILL.md index c66f6e12491..a4604f3dd23 100644 --- a/.github/skills/issue-fix/SKILL.md +++ b/.claude/skills/issue-fix/SKILL.md @@ -462,8 +462,8 @@ If the fix discovered that triage or repro got something wrong, record it: ```bash # Try pwsh first, fall back to python3 -pwsh .github/skills/issue-fix/scripts/validate-fix.ps1 /tmp/skiasharp/fix/{timestamp}/{number}.json \ - || python3 .github/skills/issue-fix/scripts/validate-fix.py /tmp/skiasharp/fix/{timestamp}/{number}.json +pwsh .claude/skills/issue-fix/scripts/validate-fix.ps1 /tmp/skiasharp/fix/{timestamp}/{number}.json \ + || python3 .claude/skills/issue-fix/scripts/validate-fix.py /tmp/skiasharp/fix/{timestamp}/{number}.json ``` > **⚠️ NEVER use hand-rolled validation.** Always use the scripts above. @@ -473,7 +473,7 @@ pwsh .github/skills/issue-fix/scripts/validate-fix.ps1 /tmp/skiasharp/fix/{times Copy the validated JSON to `output/ai/` for collection. ```bash -pwsh .github/skills/issue-fix/scripts/persist-fix.ps1 /tmp/skiasharp/fix/{timestamp}/{number}.json +pwsh .claude/skills/issue-fix/scripts/persist-fix.ps1 /tmp/skiasharp/fix/{timestamp}/{number}.json ``` This copies the JSON to `output/ai/` mirroring the data-cache structure. diff --git a/.github/skills/issue-fix/references/docker-testing.md b/.claude/skills/issue-fix/references/docker-testing.md similarity index 100% rename from .github/skills/issue-fix/references/docker-testing.md rename to .claude/skills/issue-fix/references/docker-testing.md diff --git a/.github/skills/issue-fix/references/fix-examples.md b/.claude/skills/issue-fix/references/fix-examples.md similarity index 100% rename from .github/skills/issue-fix/references/fix-examples.md rename to .claude/skills/issue-fix/references/fix-examples.md diff --git a/.github/skills/issue-fix/references/fix-schema.json b/.claude/skills/issue-fix/references/fix-schema.json similarity index 100% rename from .github/skills/issue-fix/references/fix-schema.json rename to .claude/skills/issue-fix/references/fix-schema.json diff --git a/.github/skills/issue-fix/references/pr-templates.md b/.claude/skills/issue-fix/references/pr-templates.md similarity index 100% rename from .github/skills/issue-fix/references/pr-templates.md rename to .claude/skills/issue-fix/references/pr-templates.md diff --git a/.github/skills/issue-fix/scripts/persist-fix.ps1 b/.claude/skills/issue-fix/scripts/persist-fix.ps1 similarity index 100% rename from .github/skills/issue-fix/scripts/persist-fix.ps1 rename to .claude/skills/issue-fix/scripts/persist-fix.ps1 diff --git a/.github/skills/issue-fix/scripts/validate-fix.ps1 b/.claude/skills/issue-fix/scripts/validate-fix.ps1 similarity index 100% rename from .github/skills/issue-fix/scripts/validate-fix.ps1 rename to .claude/skills/issue-fix/scripts/validate-fix.ps1 diff --git a/.github/skills/issue-fix/scripts/validate-fix.py b/.claude/skills/issue-fix/scripts/validate-fix.py similarity index 100% rename from .github/skills/issue-fix/scripts/validate-fix.py rename to .claude/skills/issue-fix/scripts/validate-fix.py diff --git a/.github/skills/issue-repro/SKILL.md b/.claude/skills/issue-repro/SKILL.md similarity index 98% rename from .github/skills/issue-repro/SKILL.md rename to .claude/skills/issue-repro/SKILL.md index f10d8d946b6..62e4c1106ec 100644 --- a/.github/skills/issue-repro/SKILL.md +++ b/.claude/skills/issue-repro/SKILL.md @@ -297,8 +297,8 @@ Use the same action types as triage. Common repro actions: ```bash # Try pwsh first, fall back to python3 -pwsh .github/skills/issue-repro/scripts/validate-repro.ps1 /tmp/skiasharp/repro/{timestamp}/{number}.json \ - || python3 .github/skills/issue-repro/scripts/validate-repro.py /tmp/skiasharp/repro/{timestamp}/{number}.json +pwsh .claude/skills/issue-repro/scripts/validate-repro.ps1 /tmp/skiasharp/repro/{timestamp}/{number}.json \ + || python3 .claude/skills/issue-repro/scripts/validate-repro.py /tmp/skiasharp/repro/{timestamp}/{number}.json ``` - **Exit 0** = ✅ valid → proceed to Phase 6 @@ -317,7 +317,7 @@ pwsh .github/skills/issue-repro/scripts/validate-repro.ps1 /tmp/skiasharp/repro/ Copy the validated JSON to `output/ai/` for collection. ```bash -pwsh .github/skills/issue-repro/scripts/persist-repro.ps1 /tmp/skiasharp/repro/{timestamp}/{number}.json +pwsh .claude/skills/issue-repro/scripts/persist-repro.ps1 /tmp/skiasharp/repro/{timestamp}/{number}.json ``` This copies the JSON to `output/ai/` mirroring the data-cache structure. diff --git a/.github/skills/issue-repro/references/anti-patterns.md b/.claude/skills/issue-repro/references/anti-patterns.md similarity index 100% rename from .github/skills/issue-repro/references/anti-patterns.md rename to .claude/skills/issue-repro/references/anti-patterns.md diff --git a/.github/skills/issue-repro/references/bug-categories.md b/.claude/skills/issue-repro/references/bug-categories.md similarity index 100% rename from .github/skills/issue-repro/references/bug-categories.md rename to .claude/skills/issue-repro/references/bug-categories.md diff --git a/.github/skills/issue-repro/references/conclusion-guide.md b/.claude/skills/issue-repro/references/conclusion-guide.md similarity index 100% rename from .github/skills/issue-repro/references/conclusion-guide.md rename to .claude/skills/issue-repro/references/conclusion-guide.md diff --git a/.github/skills/issue-repro/references/platform-console.md b/.claude/skills/issue-repro/references/platform-console.md similarity index 100% rename from .github/skills/issue-repro/references/platform-console.md rename to .claude/skills/issue-repro/references/platform-console.md diff --git a/.github/skills/issue-repro/references/platform-docker-linux.md b/.claude/skills/issue-repro/references/platform-docker-linux.md similarity index 100% rename from .github/skills/issue-repro/references/platform-docker-linux.md rename to .claude/skills/issue-repro/references/platform-docker-linux.md diff --git a/.github/skills/issue-repro/references/platform-mobile.md b/.claude/skills/issue-repro/references/platform-mobile.md similarity index 100% rename from .github/skills/issue-repro/references/platform-mobile.md rename to .claude/skills/issue-repro/references/platform-mobile.md diff --git a/.github/skills/issue-repro/references/platform-wasm-blazor.md b/.claude/skills/issue-repro/references/platform-wasm-blazor.md similarity index 100% rename from .github/skills/issue-repro/references/platform-wasm-blazor.md rename to .claude/skills/issue-repro/references/platform-wasm-blazor.md diff --git a/.github/skills/issue-repro/references/platform-windows-desktop.md b/.claude/skills/issue-repro/references/platform-windows-desktop.md similarity index 100% rename from .github/skills/issue-repro/references/platform-windows-desktop.md rename to .claude/skills/issue-repro/references/platform-windows-desktop.md diff --git a/.github/skills/issue-repro/references/repro-examples.md b/.claude/skills/issue-repro/references/repro-examples.md similarity index 100% rename from .github/skills/issue-repro/references/repro-examples.md rename to .claude/skills/issue-repro/references/repro-examples.md diff --git a/.github/skills/issue-repro/references/repro-schema.json b/.claude/skills/issue-repro/references/repro-schema.json similarity index 100% rename from .github/skills/issue-repro/references/repro-schema.json rename to .claude/skills/issue-repro/references/repro-schema.json diff --git a/.github/skills/issue-repro/references/response-guidelines.md b/.claude/skills/issue-repro/references/response-guidelines.md similarity index 100% rename from .github/skills/issue-repro/references/response-guidelines.md rename to .claude/skills/issue-repro/references/response-guidelines.md diff --git a/.github/skills/issue-repro/references/schema-cheatsheet.md b/.claude/skills/issue-repro/references/schema-cheatsheet.md similarity index 100% rename from .github/skills/issue-repro/references/schema-cheatsheet.md rename to .claude/skills/issue-repro/references/schema-cheatsheet.md diff --git a/.github/skills/issue-repro/scripts/persist-repro.ps1 b/.claude/skills/issue-repro/scripts/persist-repro.ps1 similarity index 100% rename from .github/skills/issue-repro/scripts/persist-repro.ps1 rename to .claude/skills/issue-repro/scripts/persist-repro.ps1 diff --git a/.github/skills/issue-repro/scripts/validate-repro.ps1 b/.claude/skills/issue-repro/scripts/validate-repro.ps1 similarity index 100% rename from .github/skills/issue-repro/scripts/validate-repro.ps1 rename to .claude/skills/issue-repro/scripts/validate-repro.ps1 diff --git a/.github/skills/issue-repro/scripts/validate-repro.py b/.claude/skills/issue-repro/scripts/validate-repro.py similarity index 100% rename from .github/skills/issue-repro/scripts/validate-repro.py rename to .claude/skills/issue-repro/scripts/validate-repro.py diff --git a/.github/skills/issue-triage/SKILL.md b/.claude/skills/issue-triage/SKILL.md similarity index 98% rename from .github/skills/issue-triage/SKILL.md rename to .claude/skills/issue-triage/SKILL.md index 97780ac8d34..ad8b5fe6d68 100644 --- a/.github/skills/issue-triage/SKILL.md +++ b/.claude/skills/issue-triage/SKILL.md @@ -84,7 +84,7 @@ If using cached JSON: ```bash mkdir -p /tmp/skiasharp/triage/{timestamp} -pwsh .github/skills/issue-triage/scripts/issue-to-markdown.ps1 $CACHE/github/items/{number}.json > /tmp/skiasharp/triage/{timestamp}/{number}.md +pwsh .claude/skills/issue-triage/scripts/issue-to-markdown.ps1 $CACHE/github/items/{number}.json > /tmp/skiasharp/triage/{timestamp}/{number}.md ``` If fetched via API, work directly from the `gh` output (skip the script). @@ -208,8 +208,8 @@ If any proposal `description`, `codeSnippet`, or `add-comment` `comment` contain ```bash # Try pwsh first, fall back to python3 -pwsh .github/skills/issue-triage/scripts/validate-triage.ps1 /tmp/skiasharp/triage/{timestamp}/{number}.json \ - || python3 .github/skills/issue-triage/scripts/validate-triage.py /tmp/skiasharp/triage/{timestamp}/{number}.json +pwsh .claude/skills/issue-triage/scripts/validate-triage.ps1 /tmp/skiasharp/triage/{timestamp}/{number}.json \ + || python3 .claude/skills/issue-triage/scripts/validate-triage.py /tmp/skiasharp/triage/{timestamp}/{number}.json ``` - **Exit 0** = ✅ valid → proceed to Phase 5 @@ -230,7 +230,7 @@ pwsh .github/skills/issue-triage/scripts/validate-triage.ps1 /tmp/skiasharp/tria Copy the validated JSON to `output/ai/` for collection. ```bash -pwsh .github/skills/issue-triage/scripts/persist-triage.ps1 /tmp/skiasharp/triage/{timestamp}/{number}.json +pwsh .claude/skills/issue-triage/scripts/persist-triage.ps1 /tmp/skiasharp/triage/{timestamp}/{number}.json ``` This copies the JSON to `output/ai/` mirroring the data-cache structure. diff --git a/.github/skills/issue-triage/references/anti-patterns.md b/.claude/skills/issue-triage/references/anti-patterns.md similarity index 100% rename from .github/skills/issue-triage/references/anti-patterns.md rename to .claude/skills/issue-triage/references/anti-patterns.md diff --git a/.github/skills/issue-triage/references/labels.md b/.claude/skills/issue-triage/references/labels.md similarity index 100% rename from .github/skills/issue-triage/references/labels.md rename to .claude/skills/issue-triage/references/labels.md diff --git a/.github/skills/issue-triage/references/research-by-type.md b/.claude/skills/issue-triage/references/research-by-type.md similarity index 100% rename from .github/skills/issue-triage/references/research-by-type.md rename to .claude/skills/issue-triage/references/research-by-type.md diff --git a/.github/skills/issue-triage/references/response-guidelines.md b/.claude/skills/issue-triage/references/response-guidelines.md similarity index 100% rename from .github/skills/issue-triage/references/response-guidelines.md rename to .claude/skills/issue-triage/references/response-guidelines.md diff --git a/.github/skills/issue-triage/references/schema-cheatsheet.md b/.claude/skills/issue-triage/references/schema-cheatsheet.md similarity index 100% rename from .github/skills/issue-triage/references/schema-cheatsheet.md rename to .claude/skills/issue-triage/references/schema-cheatsheet.md diff --git a/.github/skills/issue-triage/references/skia-patterns.md b/.claude/skills/issue-triage/references/skia-patterns.md similarity index 100% rename from .github/skills/issue-triage/references/skia-patterns.md rename to .claude/skills/issue-triage/references/skia-patterns.md diff --git a/.github/skills/issue-triage/references/triage-examples.md b/.claude/skills/issue-triage/references/triage-examples.md similarity index 100% rename from .github/skills/issue-triage/references/triage-examples.md rename to .claude/skills/issue-triage/references/triage-examples.md diff --git a/.github/skills/issue-triage/references/triage-schema.json b/.claude/skills/issue-triage/references/triage-schema.json similarity index 100% rename from .github/skills/issue-triage/references/triage-schema.json rename to .claude/skills/issue-triage/references/triage-schema.json diff --git a/.github/skills/issue-triage/references/workaround-search.md b/.claude/skills/issue-triage/references/workaround-search.md similarity index 99% rename from .github/skills/issue-triage/references/workaround-search.md rename to .claude/skills/issue-triage/references/workaround-search.md index bbec422ffcc..2da7abb8fa0 100644 --- a/.github/skills/issue-triage/references/workaround-search.md +++ b/.claude/skills/issue-triage/references/workaround-search.md @@ -117,7 +117,7 @@ gh issue view {N} --repo mono/SkiaSharp --json comments \ ```bash grep -n "DllNotFound\|NoDependencies\|container\|Docker\|Alpine\|ARM64" documentation/dev/packages.md -grep -n "KEYWORD" .github/skills/issue-triage/references/skia-patterns.md +grep -n "KEYWORD" .claude/skills/issue-triage/references/skia-patterns.md ``` **Common instant workarounds:** diff --git a/.github/skills/issue-triage/references/workaround-validation.md b/.claude/skills/issue-triage/references/workaround-validation.md similarity index 100% rename from .github/skills/issue-triage/references/workaround-validation.md rename to .claude/skills/issue-triage/references/workaround-validation.md diff --git a/.github/skills/issue-triage/scripts/issue-to-markdown.ps1 b/.claude/skills/issue-triage/scripts/issue-to-markdown.ps1 similarity index 100% rename from .github/skills/issue-triage/scripts/issue-to-markdown.ps1 rename to .claude/skills/issue-triage/scripts/issue-to-markdown.ps1 diff --git a/.github/skills/issue-triage/scripts/persist-triage.ps1 b/.claude/skills/issue-triage/scripts/persist-triage.ps1 similarity index 100% rename from .github/skills/issue-triage/scripts/persist-triage.ps1 rename to .claude/skills/issue-triage/scripts/persist-triage.ps1 diff --git a/.github/skills/issue-triage/scripts/validate-triage.ps1 b/.claude/skills/issue-triage/scripts/validate-triage.ps1 similarity index 100% rename from .github/skills/issue-triage/scripts/validate-triage.ps1 rename to .claude/skills/issue-triage/scripts/validate-triage.ps1 diff --git a/.github/skills/issue-triage/scripts/validate-triage.py b/.claude/skills/issue-triage/scripts/validate-triage.py similarity index 100% rename from .github/skills/issue-triage/scripts/validate-triage.py rename to .claude/skills/issue-triage/scripts/validate-triage.py diff --git a/.github/skills/native-dependency-update/SKILL.md b/.claude/skills/native-dependency-update/SKILL.md similarity index 100% rename from .github/skills/native-dependency-update/SKILL.md rename to .claude/skills/native-dependency-update/SKILL.md diff --git a/.github/skills/native-dependency-update/references/breaking-changes.md b/.claude/skills/native-dependency-update/references/breaking-changes.md similarity index 100% rename from .github/skills/native-dependency-update/references/breaking-changes.md rename to .claude/skills/native-dependency-update/references/breaking-changes.md diff --git a/.github/skills/pr-commit-message/SKILL.md b/.claude/skills/pr-commit-message/SKILL.md similarity index 100% rename from .github/skills/pr-commit-message/SKILL.md rename to .claude/skills/pr-commit-message/SKILL.md diff --git a/.github/skills/pr-commit-message/evals/evals.json b/.claude/skills/pr-commit-message/evals/evals.json similarity index 100% rename from .github/skills/pr-commit-message/evals/evals.json rename to .claude/skills/pr-commit-message/evals/evals.json diff --git a/.github/skills/pr-commit-message/references/pryor-style-guide.md b/.claude/skills/pr-commit-message/references/pryor-style-guide.md similarity index 100% rename from .github/skills/pr-commit-message/references/pryor-style-guide.md rename to .claude/skills/pr-commit-message/references/pryor-style-guide.md diff --git a/.github/skills/release-branch/SKILL.md b/.claude/skills/release-branch/SKILL.md similarity index 100% rename from .github/skills/release-branch/SKILL.md rename to .claude/skills/release-branch/SKILL.md diff --git a/.github/skills/release-notes-audit/SKILL.md b/.claude/skills/release-notes-audit/SKILL.md similarity index 99% rename from .github/skills/release-notes-audit/SKILL.md rename to .claude/skills/release-notes-audit/SKILL.md index 96c7b64419a..d2a81e3f198 100644 --- a/.github/skills/release-notes-audit/SKILL.md +++ b/.claude/skills/release-notes-audit/SKILL.md @@ -142,7 +142,7 @@ Save as `output/ai/release-notes-audit-{date}.json` in the repo. > 🛑 **MANDATORY:** Always generate the HTML report. ```bash -python3 .github/skills/release-notes-audit/scripts/render-release-notes-audit.py \ +python3 .claude/skills/release-notes-audit/scripts/render-release-notes-audit.py \ output/ai/release-notes-audit-{date}.json ``` diff --git a/.github/skills/release-notes-audit/references/report-schema.md b/.claude/skills/release-notes-audit/references/report-schema.md similarity index 100% rename from .github/skills/release-notes-audit/references/report-schema.md rename to .claude/skills/release-notes-audit/references/report-schema.md diff --git a/.github/skills/release-notes-audit/scripts/render-release-notes-audit.py b/.claude/skills/release-notes-audit/scripts/render-release-notes-audit.py similarity index 100% rename from .github/skills/release-notes-audit/scripts/render-release-notes-audit.py rename to .claude/skills/release-notes-audit/scripts/render-release-notes-audit.py diff --git a/.github/skills/release-notes-audit/scripts/viewer.html b/.claude/skills/release-notes-audit/scripts/viewer.html similarity index 100% rename from .github/skills/release-notes-audit/scripts/viewer.html rename to .claude/skills/release-notes-audit/scripts/viewer.html diff --git a/.github/skills/release-publish/SKILL.md b/.claude/skills/release-publish/SKILL.md similarity index 100% rename from .github/skills/release-publish/SKILL.md rename to .claude/skills/release-publish/SKILL.md diff --git a/.github/skills/release-publish/references/release-notes.md b/.claude/skills/release-publish/references/release-notes.md similarity index 100% rename from .github/skills/release-publish/references/release-notes.md rename to .claude/skills/release-publish/references/release-notes.md diff --git a/.github/skills/release-testing/SKILL.md b/.claude/skills/release-testing/SKILL.md similarity index 100% rename from .github/skills/release-testing/SKILL.md rename to .claude/skills/release-testing/SKILL.md diff --git a/.github/skills/release-testing/references/monitoring.md b/.claude/skills/release-testing/references/monitoring.md similarity index 100% rename from .github/skills/release-testing/references/monitoring.md rename to .claude/skills/release-testing/references/monitoring.md diff --git a/.github/skills/release-testing/references/setup.md b/.claude/skills/release-testing/references/setup.md similarity index 100% rename from .github/skills/release-testing/references/setup.md rename to .claude/skills/release-testing/references/setup.md diff --git a/.github/skills/release-testing/references/troubleshooting.md b/.claude/skills/release-testing/references/troubleshooting.md similarity index 100% rename from .github/skills/release-testing/references/troubleshooting.md rename to .claude/skills/release-testing/references/troubleshooting.md diff --git a/.github/skills/review-skia-update/SKILL.md b/.claude/skills/review-skia-update/SKILL.md similarity index 95% rename from .github/skills/review-skia-update/SKILL.md rename to .claude/skills/review-skia-update/SKILL.md index 53d3c41cbc6..09414dc50ab 100644 --- a/.github/skills/review-skia-update/SKILL.md +++ b/.claude/skills/review-skia-update/SKILL.md @@ -37,7 +37,7 @@ A single script handles all mechanical work: fetching PR metadata, checking out running the generator, checking source integrity, auditing DEPS, and analyzing companion PR files. ```bash -python3 .github/skills/review-skia-update/scripts/run_review.py \ +python3 .claude/skills/review-skia-update/scripts/run_review.py \ --skia-pr {skia_pr_number} \ --skiasharp-pr {skiasharp_pr_number} ``` @@ -99,8 +99,8 @@ The working tree is checked out to the companion PR, so you can read files direc ```bash # Try pwsh first, fall back to python3 -pwsh .github/skills/review-skia-update/scripts/validate-skia-review.ps1 {output_dir}/{pr_number}.json \ - || python3 .github/skills/review-skia-update/scripts/validate-skia-review.py {output_dir}/{pr_number}.json +pwsh .claude/skills/review-skia-update/scripts/validate-skia-review.ps1 {output_dir}/{pr_number}.json \ + || python3 .claude/skills/review-skia-update/scripts/validate-skia-review.py {output_dir}/{pr_number}.json ``` - **Exit 0** = ✅ valid → proceed to persist @@ -117,7 +117,7 @@ pwsh .github/skills/review-skia-update/scripts/validate-skia-review.ps1 {output_ Copy the validated JSON to `output/ai/` for collection. ```bash -pwsh .github/skills/review-skia-update/scripts/persist-skia-review.ps1 {output_dir}/{pr_number}.json +pwsh .claude/skills/review-skia-update/scripts/persist-skia-review.ps1 {output_dir}/{pr_number}.json ``` This copies the JSON to `output/ai/repos/mono-skia/ai-review/` and generates an HTML report diff --git a/.github/skills/review-skia-update/references/csharp-review.md b/.claude/skills/review-skia-update/references/csharp-review.md similarity index 100% rename from .github/skills/review-skia-update/references/csharp-review.md rename to .claude/skills/review-skia-update/references/csharp-review.md diff --git a/.github/skills/review-skia-update/references/schema-cheatsheet.md b/.claude/skills/review-skia-update/references/schema-cheatsheet.md similarity index 100% rename from .github/skills/review-skia-update/references/schema-cheatsheet.md rename to .claude/skills/review-skia-update/references/schema-cheatsheet.md diff --git a/.github/skills/review-skia-update/references/skia-review-schema.json b/.claude/skills/review-skia-update/references/skia-review-schema.json similarity index 100% rename from .github/skills/review-skia-update/references/skia-review-schema.json rename to .claude/skills/review-skia-update/references/skia-review-schema.json diff --git a/.github/skills/review-skia-update/references/writing-summaries.md b/.claude/skills/review-skia-update/references/writing-summaries.md similarity index 100% rename from .github/skills/review-skia-update/references/writing-summaries.md rename to .claude/skills/review-skia-update/references/writing-summaries.md diff --git a/.github/skills/review-skia-update/scripts/.gitignore b/.claude/skills/review-skia-update/scripts/.gitignore similarity index 100% rename from .github/skills/review-skia-update/scripts/.gitignore rename to .claude/skills/review-skia-update/scripts/.gitignore diff --git a/.github/skills/review-skia-update/scripts/check_companion.py b/.claude/skills/review-skia-update/scripts/check_companion.py similarity index 100% rename from .github/skills/review-skia-update/scripts/check_companion.py rename to .claude/skills/review-skia-update/scripts/check_companion.py diff --git a/.github/skills/review-skia-update/scripts/check_deps.py b/.claude/skills/review-skia-update/scripts/check_deps.py similarity index 100% rename from .github/skills/review-skia-update/scripts/check_deps.py rename to .claude/skills/review-skia-update/scripts/check_deps.py diff --git a/.github/skills/review-skia-update/scripts/check_generated_files.py b/.claude/skills/review-skia-update/scripts/check_generated_files.py similarity index 100% rename from .github/skills/review-skia-update/scripts/check_generated_files.py rename to .claude/skills/review-skia-update/scripts/check_generated_files.py diff --git a/.github/skills/review-skia-update/scripts/check_source.py b/.claude/skills/review-skia-update/scripts/check_source.py similarity index 100% rename from .github/skills/review-skia-update/scripts/check_source.py rename to .claude/skills/review-skia-update/scripts/check_source.py diff --git a/.github/skills/review-skia-update/scripts/persist-skia-review.ps1 b/.claude/skills/review-skia-update/scripts/persist-skia-review.ps1 similarity index 100% rename from .github/skills/review-skia-update/scripts/persist-skia-review.ps1 rename to .claude/skills/review-skia-update/scripts/persist-skia-review.ps1 diff --git a/.github/skills/review-skia-update/scripts/render-skia-review.py b/.claude/skills/review-skia-update/scripts/render-skia-review.py similarity index 100% rename from .github/skills/review-skia-update/scripts/render-skia-review.py rename to .claude/skills/review-skia-update/scripts/render-skia-review.py diff --git a/.github/skills/review-skia-update/scripts/run_review.py b/.claude/skills/review-skia-update/scripts/run_review.py similarity index 100% rename from .github/skills/review-skia-update/scripts/run_review.py rename to .claude/skills/review-skia-update/scripts/run_review.py diff --git a/.github/skills/review-skia-update/scripts/validate-skia-review.ps1 b/.claude/skills/review-skia-update/scripts/validate-skia-review.ps1 similarity index 100% rename from .github/skills/review-skia-update/scripts/validate-skia-review.ps1 rename to .claude/skills/review-skia-update/scripts/validate-skia-review.ps1 diff --git a/.github/skills/review-skia-update/scripts/validate-skia-review.py b/.claude/skills/review-skia-update/scripts/validate-skia-review.py similarity index 100% rename from .github/skills/review-skia-update/scripts/validate-skia-review.py rename to .claude/skills/review-skia-update/scripts/validate-skia-review.py diff --git a/.github/skills/review-skia-update/scripts/viewer.html b/.claude/skills/review-skia-update/scripts/viewer.html similarity index 100% rename from .github/skills/review-skia-update/scripts/viewer.html rename to .claude/skills/review-skia-update/scripts/viewer.html diff --git a/.github/skills/security-audit/SKILL.md b/.claude/skills/security-audit/SKILL.md similarity index 99% rename from .github/skills/security-audit/SKILL.md rename to .claude/skills/security-audit/SKILL.md index 9ded1f2885e..e880c247937 100644 --- a/.github/skills/security-audit/SKILL.md +++ b/.claude/skills/security-audit/SKILL.md @@ -294,7 +294,7 @@ Save as `output/ai/security-audit-{date}.json` in the repo (same pattern as othe > 🛑 **MANDATORY:** Always generate the HTML report. The human needs a readable dashboard. ```bash -python3 .github/skills/security-audit/scripts/render-security-audit.py \ +python3 .claude/skills/security-audit/scripts/render-security-audit.py \ output/ai/security-audit-{date}.json ``` diff --git a/.github/skills/security-audit/evals/evals.json b/.claude/skills/security-audit/evals/evals.json similarity index 100% rename from .github/skills/security-audit/evals/evals.json rename to .claude/skills/security-audit/evals/evals.json diff --git a/.github/skills/security-audit/references/report-schema.md b/.claude/skills/security-audit/references/report-schema.md similarity index 100% rename from .github/skills/security-audit/references/report-schema.md rename to .claude/skills/security-audit/references/report-schema.md diff --git a/.github/skills/security-audit/references/report-template.md b/.claude/skills/security-audit/references/report-template.md similarity index 100% rename from .github/skills/security-audit/references/report-template.md rename to .claude/skills/security-audit/references/report-template.md diff --git a/.github/skills/security-audit/scripts/render-security-audit.py b/.claude/skills/security-audit/scripts/render-security-audit.py similarity index 100% rename from .github/skills/security-audit/scripts/render-security-audit.py rename to .claude/skills/security-audit/scripts/render-security-audit.py diff --git a/.github/skills/security-audit/scripts/viewer.html b/.claude/skills/security-audit/scripts/viewer.html similarity index 100% rename from .github/skills/security-audit/scripts/viewer.html rename to .claude/skills/security-audit/scripts/viewer.html diff --git a/.github/skills/skill-creator/LICENSE.txt b/.claude/skills/skill-creator/LICENSE.txt similarity index 100% rename from .github/skills/skill-creator/LICENSE.txt rename to .claude/skills/skill-creator/LICENSE.txt diff --git a/.github/skills/skill-creator/SKILL.md b/.claude/skills/skill-creator/SKILL.md similarity index 100% rename from .github/skills/skill-creator/SKILL.md rename to .claude/skills/skill-creator/SKILL.md diff --git a/.github/skills/skill-creator/agents/analyzer.md b/.claude/skills/skill-creator/agents/analyzer.md similarity index 100% rename from .github/skills/skill-creator/agents/analyzer.md rename to .claude/skills/skill-creator/agents/analyzer.md diff --git a/.github/skills/skill-creator/agents/comparator.md b/.claude/skills/skill-creator/agents/comparator.md similarity index 100% rename from .github/skills/skill-creator/agents/comparator.md rename to .claude/skills/skill-creator/agents/comparator.md diff --git a/.github/skills/skill-creator/agents/grader.md b/.claude/skills/skill-creator/agents/grader.md similarity index 100% rename from .github/skills/skill-creator/agents/grader.md rename to .claude/skills/skill-creator/agents/grader.md diff --git a/.github/skills/skill-creator/assets/eval_review.html b/.claude/skills/skill-creator/assets/eval_review.html similarity index 100% rename from .github/skills/skill-creator/assets/eval_review.html rename to .claude/skills/skill-creator/assets/eval_review.html diff --git a/.github/skills/skill-creator/eval-viewer/generate_review.py b/.claude/skills/skill-creator/eval-viewer/generate_review.py similarity index 100% rename from .github/skills/skill-creator/eval-viewer/generate_review.py rename to .claude/skills/skill-creator/eval-viewer/generate_review.py diff --git a/.github/skills/skill-creator/eval-viewer/viewer.html b/.claude/skills/skill-creator/eval-viewer/viewer.html similarity index 100% rename from .github/skills/skill-creator/eval-viewer/viewer.html rename to .claude/skills/skill-creator/eval-viewer/viewer.html diff --git a/.github/skills/skill-creator/references/schemas.md b/.claude/skills/skill-creator/references/schemas.md similarity index 100% rename from .github/skills/skill-creator/references/schemas.md rename to .claude/skills/skill-creator/references/schemas.md diff --git a/.github/skills/skill-creator/scripts/__init__.py b/.claude/skills/skill-creator/scripts/__init__.py similarity index 100% rename from .github/skills/skill-creator/scripts/__init__.py rename to .claude/skills/skill-creator/scripts/__init__.py diff --git a/.github/skills/skill-creator/scripts/aggregate_benchmark.py b/.claude/skills/skill-creator/scripts/aggregate_benchmark.py similarity index 100% rename from .github/skills/skill-creator/scripts/aggregate_benchmark.py rename to .claude/skills/skill-creator/scripts/aggregate_benchmark.py diff --git a/.github/skills/skill-creator/scripts/generate_report.py b/.claude/skills/skill-creator/scripts/generate_report.py similarity index 100% rename from .github/skills/skill-creator/scripts/generate_report.py rename to .claude/skills/skill-creator/scripts/generate_report.py diff --git a/.github/skills/skill-creator/scripts/improve_description.py b/.claude/skills/skill-creator/scripts/improve_description.py similarity index 100% rename from .github/skills/skill-creator/scripts/improve_description.py rename to .claude/skills/skill-creator/scripts/improve_description.py diff --git a/.github/skills/skill-creator/scripts/package_skill.py b/.claude/skills/skill-creator/scripts/package_skill.py similarity index 100% rename from .github/skills/skill-creator/scripts/package_skill.py rename to .claude/skills/skill-creator/scripts/package_skill.py diff --git a/.github/skills/skill-creator/scripts/quick_validate.py b/.claude/skills/skill-creator/scripts/quick_validate.py similarity index 100% rename from .github/skills/skill-creator/scripts/quick_validate.py rename to .claude/skills/skill-creator/scripts/quick_validate.py diff --git a/.github/skills/skill-creator/scripts/run_eval.py b/.claude/skills/skill-creator/scripts/run_eval.py similarity index 100% rename from .github/skills/skill-creator/scripts/run_eval.py rename to .claude/skills/skill-creator/scripts/run_eval.py diff --git a/.github/skills/skill-creator/scripts/run_loop.py b/.claude/skills/skill-creator/scripts/run_loop.py similarity index 100% rename from .github/skills/skill-creator/scripts/run_loop.py rename to .claude/skills/skill-creator/scripts/run_loop.py diff --git a/.github/skills/skill-creator/scripts/utils.py b/.claude/skills/skill-creator/scripts/utils.py similarity index 100% rename from .github/skills/skill-creator/scripts/utils.py rename to .claude/skills/skill-creator/scripts/utils.py diff --git a/.github/skills/update-skia/SKILL.md b/.claude/skills/update-skia/SKILL.md similarity index 99% rename from .github/skills/update-skia/SKILL.md rename to .claude/skills/update-skia/SKILL.md index 41794de4a04..7cce6f43af6 100644 --- a/.github/skills/update-skia/SKILL.md +++ b/.claude/skills/update-skia/SKILL.md @@ -256,7 +256,7 @@ must be updated when the underlying C++ APIs change. In the **SkiaSharp parent repo**, run: ```bash -pwsh .github/skills/update-skia/scripts/update-versions.ps1 -Current {CURRENT} -Target {TARGET} +pwsh .claude/skills/update-skia/scripts/update-versions.ps1 -Current {CURRENT} -Target {TARGET} ``` The script handles all of these (so you don't have to do them manually): @@ -276,7 +276,7 @@ The script handles all of these (so you don't have to do them manually): > and lists any new functions that may need C# wrappers. ```bash -pwsh .github/skills/update-skia/scripts/regenerate-bindings.ps1 +pwsh .claude/skills/update-skia/scripts/regenerate-bindings.ps1 ``` The script handles all of these (so you don't forget any): diff --git a/.github/skills/update-skia/references/breaking-changes-checklist.md b/.claude/skills/update-skia/references/breaking-changes-checklist.md similarity index 100% rename from .github/skills/update-skia/references/breaking-changes-checklist.md rename to .claude/skills/update-skia/references/breaking-changes-checklist.md diff --git a/.github/skills/update-skia/references/known-gotchas.md b/.claude/skills/update-skia/references/known-gotchas.md similarity index 100% rename from .github/skills/update-skia/references/known-gotchas.md rename to .claude/skills/update-skia/references/known-gotchas.md diff --git a/.github/skills/update-skia/references/typical-changes.md b/.claude/skills/update-skia/references/typical-changes.md similarity index 100% rename from .github/skills/update-skia/references/typical-changes.md rename to .claude/skills/update-skia/references/typical-changes.md diff --git a/.github/skills/update-skia/references/validation-prompt.md b/.claude/skills/update-skia/references/validation-prompt.md similarity index 100% rename from .github/skills/update-skia/references/validation-prompt.md rename to .claude/skills/update-skia/references/validation-prompt.md diff --git a/.github/skills/update-skia/scripts/regenerate-bindings.ps1 b/.claude/skills/update-skia/scripts/regenerate-bindings.ps1 similarity index 97% rename from .github/skills/update-skia/scripts/regenerate-bindings.ps1 rename to .claude/skills/update-skia/scripts/regenerate-bindings.ps1 index 01df44bfff6..729f1008882 100644 --- a/.github/skills/update-skia/scripts/regenerate-bindings.ps1 +++ b/.claude/skills/update-skia/scripts/regenerate-bindings.ps1 @@ -11,7 +11,7 @@ 4. Lists any NEW functions that may need C# wrappers .EXAMPLE - pwsh .github/skills/update-skia/scripts/regenerate-bindings.ps1 + pwsh .claude/skills/update-skia/scripts/regenerate-bindings.ps1 #> $ErrorActionPreference = 'Stop' diff --git a/.github/skills/update-skia/scripts/update-versions.ps1 b/.claude/skills/update-skia/scripts/update-versions.ps1 similarity index 98% rename from .github/skills/update-skia/scripts/update-versions.ps1 rename to .claude/skills/update-skia/scripts/update-versions.ps1 index bcba7e01bc1..997865cd767 100644 --- a/.github/skills/update-skia/scripts/update-versions.ps1 +++ b/.claude/skills/update-skia/scripts/update-versions.ps1 @@ -19,7 +19,7 @@ The target Skia milestone number (e.g., 120) .EXAMPLE - pwsh .github/skills/update-skia/scripts/update-versions.ps1 -Current 119 -Target 120 + pwsh .claude/skills/update-skia/scripts/update-versions.ps1 -Current 119 -Target 120 #> param( diff --git a/.github/skills/validate-samples/SKILL.md b/.claude/skills/validate-samples/SKILL.md similarity index 98% rename from .github/skills/validate-samples/SKILL.md rename to .claude/skills/validate-samples/SKILL.md index 7db21e4f871..96584d9316a 100644 --- a/.github/skills/validate-samples/SKILL.md +++ b/.claude/skills/validate-samples/SKILL.md @@ -66,7 +66,7 @@ Run the detection script — it prints the preview label and build number extracted from the downloaded nupkg filenames: ```powershell -pwsh .github/skills/validate-samples/scripts/detect-preview-version.ps1 +pwsh .claude/skills/validate-samples/scripts/detect-preview-version.ps1 ``` Output: diff --git a/.github/skills/validate-samples/scripts/detect-preview-version.ps1 b/.claude/skills/validate-samples/scripts/detect-preview-version.ps1 similarity index 94% rename from .github/skills/validate-samples/scripts/detect-preview-version.ps1 rename to .claude/skills/validate-samples/scripts/detect-preview-version.ps1 index dc32af5c022..1e44bcd8c49 100644 --- a/.github/skills/validate-samples/scripts/detect-preview-version.ps1 +++ b/.claude/skills/validate-samples/scripts/detect-preview-version.ps1 @@ -1,6 +1,6 @@ # detect-preview-version.ps1 # Detects the preview label and build number from downloaded nupkg files in output/nugets/ -# Usage: pwsh .github/skills/validate-samples/scripts/detect-preview-version.ps1 +# Usage: pwsh .claude/skills/validate-samples/scripts/detect-preview-version.ps1 # Prints: Preview label, Build number, Full suffix param( diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 42314856a4f..43c994c2d36 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,422 +1 @@ -# SkiaSharp AI Instructions - -SkiaSharp is a cross-platform 2D graphics API for .NET wrapping Google's Skia library. - -**Architecture:** `C# Wrapper` → `P/Invoke` → `C API` → `C++ Skia` -**Principle:** C# validates parameters, C API trusts and passes through. - ---- - -## Table of Contents - -1. [Critical Rules](#️-critical-rules-read-first) — Non-negotiable constraints -2. [Commands](#commands) — Build, test, regenerate -3. [Architecture & Directories](#architecture--directories) — What's where, what's editable -4. [Writing Code](#writing-code) — Memory, patterns, error handling (merged) -5. [Testing & Debugging](#testing--debugging) — Verification and troubleshooting -6. [Skills & Routing](#skills--routing) — When to delegate to specialized workflows - ---- - -## ⚠️ Critical Rules (Read First) - -These rules are **non-negotiable**. Violating them causes broken builds, crashes, or downstream breakage. - -### 1. Bootstrap First - -Before any other command works, ensure native binaries exist: - -```bash -# Run if output/native/ is empty -dotnet cake --target=externals-download -``` - -### 2. Never Edit Generated Files - -Files matching `*.generated.cs` and `docs/` are auto-generated. - -- **❌ NEVER** manually edit these files -- **✅ ALWAYS** regenerate after C API changes (see [Commands](#commands)) - -### 3. ABI Stability - -SkiaSharp maintains stable ABI. Breaking changes break downstream apps. - -| ✅ Allowed | ❌ Never | -|-----------|---------| -| Add new overloads | Modify existing signatures | -| Add new methods | Remove public APIs | -| Add new classes | Change return types | - -### 4. Tests Are Mandatory - -**Building alone is NOT sufficient.** Run tests before claiming completion (see [Commands](#commands)). - -### 5. Branch Protection (COMPLIANCE REQUIRED) - -**Direct commits to protected branches are a policy violation.** - -| Repository | Protected Branches | -|------------|-------------------| -| SkiaSharp (parent) | `main` | -| externals/skia (submodule) | `main`, `skiasharp` | - -**Required workflow:** - -1. **Create a feature branch FIRST** — Use naming convention: `dev/issue-NNNN-description` -2. **Make all commits on the feature branch** — Never commit directly to protected branches -3. **Submit a Pull Request** — Changes must be reviewed before merging - -```bash -# ✅ CORRECT — Always create a feature branch first -git checkout -b dev/issue-1234-fix-description - -# For submodule changes: -cd externals/skia -git checkout -b dev/issue-1234-add-c-api - -# ❌ NEVER DO THIS — Policy violation -git checkout main && git commit # FORBIDDEN -git checkout skiasharp && git commit # FORBIDDEN (in skia submodule) -``` - -**This applies to BOTH repositories.** The skia submodule has its own protected branches that must be respected. - ---- - -## Commands - -Single source of truth for all commands: - -| Task | Command | -|------|---------| -| **Bootstrap (C#-only work)** | `dotnet cake --target=externals-download` | -| **Build Native (macOS ARM64)** | `dotnet cake --target=externals-macos --arch=arm64` | -| **Build Native (macOS Intel)** | `dotnet cake --target=externals-macos --arch=x64` | -| **Build Native (Windows x64)** | `dotnet cake --target=externals-windows --arch=x64` | -| **Build Native (Linux x64)** | `dotnet cake --target=externals-linux --arch=x64` | -| **Build Native (Linux ARM64)** | `dotnet cake --target=externals-linux --arch=arm64` | -| **Build C#** | `dotnet build binding/SkiaSharp/SkiaSharp.csproj` | -| **Test** | `dotnet test tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj` | -| **Regenerate** | `pwsh ./utils/generate.ps1` | - -### ⚠️ When to Use Which Bootstrap - -| What You Changed | Command Required | -|------------------|------------------| -| C# code only (`binding/SkiaSharp/*.cs`) | `externals-download` (pre-built natives) | -| C API (`externals/skia/src/c/`, `externals/skia/include/c/`) | **`externals-{platform}` (MUST rebuild natives)** | -| Dependencies (`externals/skia/DEPS`) | **`externals-{platform}` (MUST rebuild natives)** | - -> **🛑 CRITICAL:** If you modify ANY native code (C API headers/implementations), you MUST rebuild -> the native library with `dotnet cake --target=externals-{platform}`. Using `externals-download` -> after native changes will cause `EntryPointNotFoundException` at runtime because the downloaded -> binaries don't contain your new functions. - -> **Note:** For release verification, see `release-testing` skill for the full platform matrix (iOS, Android, Mac Catalyst, Blazor). - -**Recovery Commands:** - -| Problem | Command | -|---------|---------| -| Clean rebuild | `dotnet cake --target=clean && dotnet cake --target=externals-download` | -| Reset submodule | `git submodule update --init --recursive` | - ---- - -## Architecture & Directories - -### Layer Overview - -``` -C# Wrapper (binding/SkiaSharp/) → P/Invoke → C API (externals/skia/src/c/) → C++ Skia -``` - -### Directory Guide - -| Directory | Editable? | Notes | -|-----------|-----------|-------| -| `binding/SkiaSharp/` | ✅ Yes | C# wrappers | -| `externals/skia/src/c/` | ✅ Yes | C API implementation (our shim) | -| `externals/skia/include/c/` | ✅ Yes | C API headers (our shim) | -| `externals/skia/**` (other) | ❌ No | Upstream Skia — never modify | -| `*.generated.cs` | ❌ No | Run `pwsh ./utils/generate.ps1` | -| `docs/` | ❌ No | Auto-generated | -| `documentation/dev/` | ✅ Yes | Architecture guides | - ---- - -## Writing Code - -This section covers memory management, code patterns, and error handling together — they're tightly coupled when writing wrappers. - -### Step 1: Identify Pointer Type - -``` -Is it wrapped in sk_sp? -├─ Yes → SkRefCnt? → ISKReferenceCounted -│ SkNVRefCnt? → ISKNonVirtualReferenceCounted -└─ No → Parameter? → owns: false - Otherwise → DisposeNative() -``` - -| Type | C++ | C# | Examples | -|------|-----|-----|----------| -| Raw | `T*` param | `owns: false` | Temporary refs | -| Owned | Manual delete | `DisposeNative()` | Canvas, Paint, Path | -| Ref-counted | `sk_sp` | `ISKReferenceCounted` | Image, Shader, Surface | - -### Step 2: Choose Pattern - -**Factory method** — return null on failure, validate inputs: - -```csharp -public static SKImage FromPixels(SKImageInfo info, SKData data, int rowBytes) -{ - if (data == null) - throw new ArgumentNullException(nameof(data)); - var cinfo = SKImageInfoNative.FromManaged(ref info); - return GetObject(SkiaApi.sk_image_new_raster_data(&cinfo, data.Handle, (IntPtr)rowBytes)); -} -``` - -**Instance method** — validate then call: - -```csharp -public void DrawRect(SKRect rect, SKPaint paint) -{ - if (paint == null) - throw new ArgumentNullException(nameof(paint)); - SkiaApi.sk_canvas_draw_rect(Handle, &rect, paint.Handle); -} -``` - -**C API** — naming convention `sk__`: - -```cpp -sk_image_t* sk_image_new_from_encoded(const sk_data_t* cdata) { - return ToImage(SkImages::DeferredFromEncodedData(sk_ref_sp(AsData(cdata))).release()); -} -``` - -### Step 3: Error Handling - -| Layer | On Failure | -|-------|------------| -| C API | Return `nullptr` or `false` | -| C# Factory | Return `null` | -| C# Constructor | Throw | - -### Step 4: Same-Instance Returns - -Some methods return the **same instance**. Always check before disposing: - -```csharp -// ✅ CORRECT — always use this pattern -var source = GetImage(); -var result = source.Subset(bounds); -if (result != source) - source.Dispose(); -return result; -``` - -**Methods that may return same instance:** `Subset()`, `ToRasterImage()`, `ToRasterImage(false)` - -### API Design Rules - -- **Overloads, not defaults** — Default parameters break ABI -- **Deprecate, don't remove** — Use `[Obsolete]` with migration guidance -- **Naming:** `SK` prefix, PascalCase methods, camelCase parameters - -**Adding overloads (ABI-safe):** - -```csharp -// ✅ Existing method (don't modify) -public void DrawText(string text, float x, float y, SKPaint paint) - -// ✅ New overload (safe to add) -public void DrawText(string text, SKPoint point, SKPaint paint) - => DrawText(text, point.X, point.Y, paint); -``` - -### Threading Rules - -Skia is **NOT thread-safe**. - -| ❌ Never share between threads | ✅ Safe to share (immutable) | -|-------------------------------|------------------------------| -| `SKCanvas`, `SKPaint`, `SKPath` | `SKImage`, `SKShader`, `SKData` | - -```csharp -// ✅ Thread-safe pattern — each thread gets own Paint -ThreadLocal paint = new(() => new SKPaint()); -``` - -### Anti-Patterns (Never Do This) - -| ❌ Anti-Pattern | Why | -|----------------|-----| -| `canvas.Dispose()` while using derived objects | Crashes | -| Sharing `SKPaint` between threads | Race conditions | -| Modifying method signatures | ABI breaking | -| Manual edits to `*.generated.cs` | Overwritten on regenerate | -| Using default parameters in public APIs | ABI breaking | -| **Skipping failing tests** | **Unacceptable — tests must pass** | -| **Using `externals-download` after C API changes** | **Causes `EntryPointNotFoundException`** | -| Passing `fixed` pointers to native objects that outlive the block | GC moves memory → corruption. Use `GCHandle.Alloc(Pinned)` or `Marshal.AllocCoTaskMem` | -| Testing WASM version changes without cleaning `bin/obj/_framework` | Stale cached native `.wasm` files produce false results | - ---- - -## Testing & Debugging - -### Running Tests - -```bash -dotnet test tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj -``` - -### ⚠️ Tests MUST Pass - -> **🛑 NON-NEGOTIABLE:** Tests must PASS before claiming completion. -> -> - Do NOT skip failing tests -> - Do NOT claim completion if tests fail -> - Do NOT use `SkipException` to work around failures -> -> **Skipping is ONLY acceptable for hardware limitations:** -> - No GPU drivers available -> - No display attached -> - Platform doesn't support the feature (e.g., Metal on Windows) - -### Writing Tests - -```csharp -[SkippableFact] -public void FeatureWorks() -{ - using var data = SKData.Create(Path.Combine(PathToImages, "baboon.jpg")); - using var image = SKImage.FromEncodedData(data); - Assert.NotNull(image); -} -``` - -**BaseTest helpers:** `PathToImages`, `PathToFonts`, `IsWindows/Mac/Linux` - -**Philosophy:** Tests FAIL when wrong, never skip (except missing hardware). - -### Debugging Methodology - -1. **Establish baseline** — What's the known-good state? -2. **One change at a time** — Verify each change before proceeding -3. **Track changes in a table** — Log what you changed and the result -4. **Platform differences are signals** — If X works and Y fails, the difference IS the answer -5. **Revert if worse** — Don't pile fixes on top of failures - -### Failure Recognition - -| Error | Likely Cause | Fix | -|-------|--------------|-----| -| `error CS0246` (missing type) | Missing binding | Run `pwsh ./utils/generate.ps1` | -| `LNK2001 unresolved external` | C API signature mismatch | Check C function names match | -| `AccessViolationException` | Memory management bug | Check disposal patterns | -| `NullReferenceException` | Factory returned null | Check C API return value | -| Random crashes | Threading violation | Check Canvas/Paint thread scope | -| **`EntryPointNotFoundException`** | **Native library not rebuilt after C API change** | **Run `dotnet cake --target=externals-{platform}`** | - -See [documentation/dev/debugging-methodology.md](../documentation/dev/debugging-methodology.md). - ---- - -## Skills & Routing - -Skills are specialized workflows for complex tasks. **Your job is classification and routing** — skills handle the detailed implementation. - -### ⚠️ Skill Invocation Process - -When the user mentions a GitHub issue number OR describes a bug/crash/problem: - -1. **Fetch issue details** — Get the issue title, body, and labels from GitHub -2. **Classify** — Based on **ISSUE CONTENT**, not user's words (see table below) -3. **Invoke skill** — Call the skill tool to load the skill context -4. **READ SKILL.md FIRST** — **MANDATORY BLOCKING STEP:** Immediately read `.github/skills/{skill-name}/SKILL.md` before ANY other action. Do NOT proceed based on assumptions or general knowledge. - -> **🛑 NEVER SKIP READING SKILL.md:** Skills exist because project-specific procedures differ from general patterns. Your assumptions about how to perform a task are likely WRONG. The skill file is the source of truth — read it, follow it exactly. - -> **CRITICAL:** Classify based on what the ISSUE describes, not what the USER says. -> - User says "investigate" but issue says "crash" → It's a bug → invoke `issue-fix` -> - User says "look at" but issue says "add support for" → It's new API → invoke `add-api` -> -> **What's NOT allowed:** Investigating (running Docker, searching code, downloading -> attachments) before invoking the skill. The skill handles all of that. - -### When to Use Skills - -| Task | Skill | Triggers | -|------|-------|----------| -| Triage issue | `issue-triage` | "triage #NNNN", "triage issue", "classify issue", "analyze issue" | -| Reproduce bug | `issue-repro` | "repro #NNNN", "reproduce #NNNN", "reproduce issue", "try to reproduce", "can you reproduce", "create reproduction" | -| Fix bug | `issue-fix` | "investigate #NNNN", "fix issue", crash, exception, hard crash, segfault, "undefined symbol", AccessViolationException, incorrect output, wrong behavior, memory leak, disposal issues, "fails", "broken", "doesn't work" | -| Add new API | `add-api` | "expose", "wrap method", issue requests new functionality | -| Update dependency | `native-dependency-update` | "bump libpng", "fix CVE in zlib" | -| Write XML docs | `api-docs` | "document", "fill in missing docs" | -| Security check | `security-audit` | "audit CVEs", "security overview" (read-only) | -| Start release | `release-branch` | "release now", "start release X" | -| Test release | `release-testing` | "test the release", "verify packages" | -| Publish release | `release-publish` | "push to nuget", "tag release" | - -### Issue Pipeline (3 steps) - -The first three skills form a pipeline. Each can run standalone, but they work best in sequence: - -| Step | Skill | Produces | Schema | -|------|-------|----------|--------| -| 1 | `issue-triage` | `ai-triage/{n}.json` | Triage | -| 2 | `issue-repro` | `ai-repro/{n}.json` | Repro | -| 3 | `issue-fix` | `ai-fix/{n}.json` + PR | Fix | - -See [documentation/dev/issue-pipeline.md](../documentation/dev/issue-pipeline.md) for handoff contracts and feedback loop. - -### When NOT to Use Skills - -Work directly for: -- Trivial fixes (typos, whitespace, obvious one-liners) -- Changes only to `documentation/dev/` (non-generated docs) -- Build/test-only tasks (no reported bug) -- Questions about code or architecture -- Refactoring without a reported problem -- Performance optimization (unless there's a "slow" bug report) - -### Issue Classification (#NNNN) - -| If Issue Contains... | Type | Skill | -|---------------------|------|-------| -| "triage", "classify", "analyze issue" | Triage | `issue-triage` | -| "repro", "reproduce", "reproduction", "try to reproduce" | Reproduction | `issue-repro` | -| "crash", "exception", "wrong", "fails", "broken", "hard crash", "segfault", "undefined symbol", "AccessViolation" | Bug | `issue-fix` | -| "add", "expose", "missing API", "missing method", "support", "new method", "feature request" | New API | `add-api` | -| "docs", "documentation", "XML", "comments" | Docs | `api-docs` | -| CVE, security, vulnerability | Security | `security-audit` then `native-dependency-update` | - -**Ambiguous cases:** If unclear, ask: "Does the user report something that doesn't match expected behavior?" If yes → `issue-fix`. If no → work directly or ask for clarification. - -### If a Skill Fails - -1. Note the error and what step failed -2. Try the skill again with more specific context -3. If repeated failure, attempt manual resolution using this document -4. Report the issue to the user - ---- - -## Further Reading - -| Topic | Document | -|-------|----------| -| Architecture | `documentation/dev/architecture.md` | -| Memory Management | `documentation/dev/memory-management.md` | -| Adding APIs | `documentation/dev/adding-apis.md` | -| API Design | `documentation/dev/api-design.md` | -| Error Handling | `documentation/dev/error-handling.md` | -| Debugging | `documentation/dev/debugging-methodology.md` | -| NuGet Packages | `documentation/dev/packages.md` | +@AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..815706760b5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,391 @@ +# SkiaSharp + +SkiaSharp is a cross-platform 2D graphics API for .NET wrapping Google's Skia library. + +**Architecture:** `C# Wrapper` -> `P/Invoke` -> `C API` -> `C++ Skia` +**Principle:** C# validates parameters, C API trusts and passes through. + +--- + +## Critical Rules (Read First) + +These rules are **non-negotiable**. Violating them causes broken builds, crashes, or downstream breakage. + +### 1. Bootstrap First + +Before any other command works, ensure native binaries exist: + +```bash +# Run if output/native/ is empty +dotnet cake --target=externals-download +``` + +### 2. Never Edit Generated Files + +Files matching `*.generated.cs` and `docs/` are auto-generated. + +- **NEVER** manually edit these files +- **ALWAYS** regenerate after C API changes (see [Commands](#commands)) + +### 3. ABI Stability + +SkiaSharp maintains stable ABI. Breaking changes break downstream apps. + +| Allowed | Never | +|---------|-------| +| Add new overloads | Modify existing signatures | +| Add new methods | Remove public APIs | +| Add new classes | Change return types | + +### 4. Tests Are Mandatory + +**Building alone is NOT sufficient.** Run tests before claiming completion (see [Commands](#commands)). + +### 5. Branch Protection (COMPLIANCE REQUIRED) + +**Direct commits to protected branches are a policy violation.** + +| Repository | Protected Branches | +|------------|-------------------| +| SkiaSharp (parent) | `main` | +| externals/skia (submodule) | `main`, `skiasharp` | + +**Required workflow:** + +1. **Create a feature branch FIRST** — Use naming convention: `dev/issue-NNNN-description` +2. **Make all commits on the feature branch** — Never commit directly to protected branches +3. **Submit a Pull Request** — Changes must be reviewed before merging + +```bash +# CORRECT — Always create a feature branch first +git checkout -b dev/issue-1234-fix-description + +# For submodule changes: +cd externals/skia +git checkout -b dev/issue-1234-add-c-api + +# NEVER DO THIS — Policy violation +git checkout main && git commit # FORBIDDEN +git checkout skiasharp && git commit # FORBIDDEN (in skia submodule) +``` + +**This applies to BOTH repositories.** The skia submodule has its own protected branches that must be respected. + +--- + +## Commands + +Single source of truth for all commands: + +| Task | Command | +|------|---------| +| **Bootstrap (C#-only work)** | `dotnet cake --target=externals-download` | +| **Build Native (macOS ARM64)** | `dotnet cake --target=externals-macos --arch=arm64` | +| **Build Native (macOS Intel)** | `dotnet cake --target=externals-macos --arch=x64` | +| **Build Native (Windows x64)** | `dotnet cake --target=externals-windows --arch=x64` | +| **Build Native (Linux x64)** | `dotnet cake --target=externals-linux --arch=x64` | +| **Build Native (Linux ARM64)** | `dotnet cake --target=externals-linux --arch=arm64` | +| **Build C#** | `dotnet build binding/SkiaSharp/SkiaSharp.csproj` | +| **Test** | `dotnet test tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj` | +| **Regenerate** | `pwsh ./utils/generate.ps1` | + +### When to Use Which Bootstrap + +| What You Changed | Command Required | +|------------------|------------------| +| C# code only (`binding/SkiaSharp/*.cs`) | `externals-download` (pre-built natives) | +| C API (`externals/skia/src/c/`, `externals/skia/include/c/`) | **`externals-{platform}` (MUST rebuild natives)** | +| Dependencies (`externals/skia/DEPS`) | **`externals-{platform}` (MUST rebuild natives)** | + +> **CRITICAL:** If you modify ANY native code (C API headers/implementations), you MUST rebuild +> the native library with `dotnet cake --target=externals-{platform}`. Using `externals-download` +> after native changes will cause `EntryPointNotFoundException` at runtime because the downloaded +> binaries don't contain your new functions. + +> **Note:** For release verification, see `/release-testing` command for the full platform matrix. + +**Recovery Commands:** + +| Problem | Command | +|---------|---------| +| Clean rebuild | `dotnet cake --target=clean && dotnet cake --target=externals-download` | +| Reset submodule | `git submodule update --init --recursive` | + +--- + +## Architecture & Directories + +### Layer Overview + +``` +C# Wrapper (binding/SkiaSharp/) -> P/Invoke -> C API (externals/skia/src/c/) -> C++ Skia +``` + +### Directory Guide + +| Directory | Editable? | Notes | +|-----------|-----------|-------| +| `binding/SkiaSharp/` | Yes | C# wrappers | +| `externals/skia/src/c/` | Yes | C API implementation (our shim) | +| `externals/skia/include/c/` | Yes | C API headers (our shim) | +| `externals/skia/**` (other) | No | Upstream Skia — never modify | +| `*.generated.cs` | No | Run `pwsh ./utils/generate.ps1` | +| `docs/` | No | Auto-generated | +| `documentation/dev/` | Yes | Architecture guides | + +--- + +## Writing Code + +This section covers memory management, code patterns, and error handling together — they're tightly coupled when writing wrappers. + +### Step 1: Identify Pointer Type + +``` +Is it wrapped in sk_sp? ++- Yes -> SkRefCnt? -> ISKReferenceCounted +| SkNVRefCnt? -> ISKNonVirtualReferenceCounted ++- No -> Parameter? -> owns: false + Otherwise -> DisposeNative() +``` + +| Type | C++ | C# | Examples | +|------|-----|-----|----------| +| Raw | `T*` param | `owns: false` | Temporary refs | +| Owned | Manual delete | `DisposeNative()` | Canvas, Paint, Path | +| Ref-counted | `sk_sp` | `ISKReferenceCounted` | Image, Shader, Surface | + +### Step 2: Choose Pattern + +**Factory method** — return null on failure, validate inputs: + +```csharp +public static SKImage FromPixels(SKImageInfo info, SKData data, int rowBytes) +{ + if (data == null) + throw new ArgumentNullException(nameof(data)); + var cinfo = SKImageInfoNative.FromManaged(ref info); + return GetObject(SkiaApi.sk_image_new_raster_data(&cinfo, data.Handle, (IntPtr)rowBytes)); +} +``` + +**Instance method** — validate then call: + +```csharp +public void DrawRect(SKRect rect, SKPaint paint) +{ + if (paint == null) + throw new ArgumentNullException(nameof(paint)); + SkiaApi.sk_canvas_draw_rect(Handle, &rect, paint.Handle); +} +``` + +**C API** — naming convention `sk__`: + +```cpp +sk_image_t* sk_image_new_from_encoded(const sk_data_t* cdata) { + return ToImage(SkImages::DeferredFromEncodedData(sk_ref_sp(AsData(cdata))).release()); +} +``` + +### Step 3: Error Handling + +| Layer | On Failure | +|-------|------------| +| C API | Return `nullptr` or `false` | +| C# Factory | Return `null` | +| C# Constructor | Throw | + +### Step 4: Same-Instance Returns + +Some methods return the **same instance**. Always check before disposing: + +```csharp +// CORRECT — always use this pattern +var source = GetImage(); +var result = source.Subset(bounds); +if (result != source) + source.Dispose(); +return result; +``` + +**Methods that may return same instance:** `Subset()`, `ToRasterImage()`, `ToRasterImage(false)` + +### API Design Rules + +- **Overloads, not defaults** — Default parameters break ABI +- **Deprecate, don't remove** — Use `[Obsolete]` with migration guidance +- **Naming:** `SK` prefix, PascalCase methods, camelCase parameters + +**Adding overloads (ABI-safe):** + +```csharp +// Existing method (don't modify) +public void DrawText(string text, float x, float y, SKPaint paint) + +// New overload (safe to add) +public void DrawText(string text, SKPoint point, SKPaint paint) + => DrawText(text, point.X, point.Y, paint); +``` + +### Threading Rules + +Skia is **NOT thread-safe**. + +| Never share between threads | Safe to share (immutable) | +|-----------------------------|---------------------------| +| `SKCanvas`, `SKPaint`, `SKPath` | `SKImage`, `SKShader`, `SKData` | + +```csharp +// Thread-safe pattern — each thread gets own Paint +ThreadLocal paint = new(() => new SKPaint()); +``` + +### Anti-Patterns (Never Do This) + +| Anti-Pattern | Why | +|-------------|-----| +| `canvas.Dispose()` while using derived objects | Crashes | +| Sharing `SKPaint` between threads | Race conditions | +| Modifying method signatures | ABI breaking | +| Manual edits to `*.generated.cs` | Overwritten on regenerate | +| Using default parameters in public APIs | ABI breaking | +| **Skipping failing tests** | **Unacceptable — tests must pass** | +| **Using `externals-download` after C API changes** | **Causes `EntryPointNotFoundException`** | +| Passing `fixed` pointers to native objects that outlive the block | GC moves memory -> corruption. Use `GCHandle.Alloc(Pinned)` or `Marshal.AllocCoTaskMem` | +| Testing WASM version changes without cleaning `bin/obj/_framework` | Stale cached native `.wasm` files produce false results | + +--- + +## Testing & Debugging + +### Running Tests + +```bash +dotnet test tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj +``` + +### Tests MUST Pass + +> **NON-NEGOTIABLE:** Tests must PASS before claiming completion. +> +> - Do NOT skip failing tests +> - Do NOT claim completion if tests fail +> - Do NOT use `SkipException` to work around failures +> +> **Skipping is ONLY acceptable for hardware limitations:** +> - No GPU drivers available +> - No display attached +> - Platform doesn't support the feature (e.g., Metal on Windows) + +### Writing Tests + +```csharp +[SkippableFact] +public void FeatureWorks() +{ + using var data = SKData.Create(Path.Combine(PathToImages, "baboon.jpg")); + using var image = SKImage.FromEncodedData(data); + Assert.NotNull(image); +} +``` + +**BaseTest helpers:** `PathToImages`, `PathToFonts`, `IsWindows/Mac/Linux` + +**Philosophy:** Tests FAIL when wrong, never skip (except missing hardware). + +### Debugging Methodology + +1. **Establish baseline** — What's the known-good state? +2. **One change at a time** — Verify each change before proceeding +3. **Track changes in a table** — Log what you changed and the result +4. **Platform differences are signals** — If X works and Y fails, the difference IS the answer +5. **Revert if worse** — Don't pile fixes on top of failures + +### Failure Recognition + +| Error | Likely Cause | Fix | +|-------|--------------|-----| +| `error CS0246` (missing type) | Missing binding | Run `pwsh ./utils/generate.ps1` | +| `LNK2001 unresolved external` | C API signature mismatch | Check C function names match | +| `AccessViolationException` | Memory management bug | Check disposal patterns | +| `NullReferenceException` | Factory returned null | Check C API return value | +| Random crashes | Threading violation | Check Canvas/Paint thread scope | +| **`EntryPointNotFoundException`** | **Native library not rebuilt after C API change** | **Run `dotnet cake --target=externals-{platform}`** | + +See [documentation/dev/debugging-methodology.md](documentation/dev/debugging-methodology.md). + +--- + +## Slash Commands + +Custom slash commands are available for specialized workflows. Use these for complex tasks that benefit from structured processes. + +### When to Use Commands + +| Task | Command | Triggers | +|------|---------|----------| +| Triage issue | `/issue-triage` | "triage #NNNN", "classify issue", "analyze issue" | +| Reproduce bug | `/issue-repro` | "repro #NNNN", "reproduce issue", "create reproduction" | +| Fix bug | `/issue-fix` | "investigate #NNNN", "fix issue", crash, exception, segfault, "doesn't work" | +| Bulk process issues | `/issue-bulk-process` | "triage these issues", "process issues #1 #2 #3" | +| Add new API | `/add-api` | "expose", "wrap method", issue requests new functionality | +| Update dependency | `/native-dependency-update` | "bump libpng", "fix CVE in zlib" | +| Write XML docs | `/api-docs` | "document", "fill in missing docs" | +| Security check | `/security-audit` | "audit CVEs", "security overview" (read-only) | +| Start release | `/release-branch` | "release now", "start release X" | +| Test release | `/release-testing` | "test the release", "verify packages" | +| Publish release | `/release-publish` | "push to nuget", "tag release" | +| Audit release notes | `/release-notes-audit` | "compare Skia changes", "API gap analysis" | +| Update Skia | `/update-skia` | "update to milestone NNN", "bump Skia" | +| Review Skia update | `/review-skia-update` | "review the Skia merge PR" | +| PR commit message | `/pr-commit-message` | "write commit message for PR" | +| Validate samples | `/validate-samples` | "build samples", "test sample projects" | +| Create/improve skill | `/skill-creator` | "create a new skill", "improve skill X" | + +### Issue Pipeline (3 steps) + +The first three commands form a pipeline. Each can run standalone, but they work best in sequence: + +| Step | Command | Produces | +|------|---------|----------| +| 1 | `/issue-triage` | `ai-triage/{n}.json` | +| 2 | `/issue-repro` | `ai-repro/{n}.json` | +| 3 | `/issue-fix` | `ai-fix/{n}.json` + PR | + +See [documentation/dev/issue-pipeline.md](documentation/dev/issue-pipeline.md) for handoff contracts and feedback loop. + +### Issue Classification (#NNNN) + +| If Issue Contains... | Type | Command | +|---------------------|------|---------| +| "triage", "classify", "analyze issue" | Triage | `/issue-triage` | +| "repro", "reproduce", "reproduction" | Reproduction | `/issue-repro` | +| "crash", "exception", "wrong", "fails", "broken", "segfault" | Bug | `/issue-fix` | +| "add", "expose", "missing API", "feature request" | New API | `/add-api` | +| "docs", "documentation", "XML", "comments" | Docs | `/api-docs` | +| CVE, security, vulnerability | Security | `/security-audit` then `/native-dependency-update` | + +### When NOT to Use Commands + +Work directly for: +- Trivial fixes (typos, whitespace, obvious one-liners) +- Changes only to `documentation/dev/` (non-generated docs) +- Build/test-only tasks (no reported bug) +- Questions about code or architecture +- Refactoring without a reported problem +- Performance optimization (unless there's a "slow" bug report) + +--- + +## Further Reading + +| Topic | Document | +|-------|----------| +| Architecture | `documentation/dev/architecture.md` | +| Memory Management | `documentation/dev/memory-management.md` | +| Adding APIs | `documentation/dev/adding-apis.md` | +| API Design | `documentation/dev/api-design.md` | +| Error Handling | `documentation/dev/error-handling.md` | +| Debugging | `documentation/dev/debugging-methodology.md` | +| NuGet Packages | `documentation/dev/packages.md` | diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..43c994c2d36 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/documentation/dev/building-samples.md b/documentation/dev/building-samples.md index 746db17de9e..f9f3c51b2e2 100644 --- a/documentation/dev/building-samples.md +++ b/documentation/dev/building-samples.md @@ -125,7 +125,7 @@ Example prompts: The skill follows the workflow described in the reference sections above: clear cache → download CI packages → detect preview version → build with `dotnet cake --target=samples`. -See [`.github/skills/validate-samples/SKILL.md`](../../.github/skills/validate-samples/SKILL.md) +See [`.claude/skills/validate-samples/SKILL.md`](../../.claude/skills/validate-samples/SKILL.md) for the full step-by-step workflow if you need to run it manually. ## How `samples-generate` Works diff --git a/documentation/dev/dependencies.md b/documentation/dev/dependencies.md index 42574e9998c..49f3cd13a66 100644 --- a/documentation/dev/dependencies.md +++ b/documentation/dev/dependencies.md @@ -180,5 +180,5 @@ FreeType has its own zlib copy at `freetype/src/gzip/`. When checking zlib CVEs: ## Related Skills -- **[security-audit](../../.github/skills/security-audit/SKILL.md)** — Find CVEs, verify fixes, generate reports -- **[native-dependency-update](../../.github/skills/native-dependency-update/SKILL.md)** — Update dependencies, create PRs +- **[security-audit](../../.claude/skills/security-audit/SKILL.md)** — Find CVEs, verify fixes, generate reports +- **[native-dependency-update](../../.claude/skills/native-dependency-update/SKILL.md)** — Update dependencies, create PRs diff --git a/documentation/dev/releasing.md b/documentation/dev/releasing.md index 27ddaa32565..9e378381897 100644 --- a/documentation/dev/releasing.md +++ b/documentation/dev/releasing.md @@ -16,9 +16,9 @@ The release process is handled by three skills in order: | Step | Skill | Purpose | Trigger | |------|-------|---------|---------| -| 1 | [release-branch](../../.github/skills/release-branch/SKILL.md) | Create release branch, trigger CI | "release now", "release X.Y.Z" | -| 2 | [release-testing](../../.github/skills/release-testing/SKILL.md) | Test packages before publishing | "test the release", "continue" | -| 3 | [release-publish](../../.github/skills/release-publish/SKILL.md) | Publish to NuGet.org, tag, finalize | "publish X.Y.Z", "finalize" | +| 1 | [release-branch](../../.claude/skills/release-branch/SKILL.md) | Create release branch, trigger CI | "release now", "release X.Y.Z" | +| 2 | [release-testing](../../.claude/skills/release-testing/SKILL.md) | Test packages before publishing | "test the release", "continue" | +| 3 | [release-publish](../../.claude/skills/release-publish/SKILL.md) | Publish to NuGet.org, tag, finalize | "publish X.Y.Z", "finalize" | Each skill confirms with `ask_user` before executing destructive operations. diff --git a/documentation/dev/writing-docs.md b/documentation/dev/writing-docs.md index 6dd60e16e62..2732e14e99f 100644 --- a/documentation/dev/writing-docs.md +++ b/documentation/dev/writing-docs.md @@ -107,8 +107,8 @@ Once you are happy with your changes, push them to your fork of [`mono/SkiaSharp For detailed XML documentation patterns and review criteria, see: -- [`.github/skills/api-docs/references/patterns.md`](../../.github/skills/api-docs/references/patterns.md) — XML syntax and examples -- [`.github/skills/api-docs/references/checklist.md`](../../.github/skills/api-docs/references/checklist.md) — Review severity criteria +- [`.claude/skills/api-docs/references/patterns.md`](../../.claude/skills/api-docs/references/patterns.md) — XML syntax and examples +- [`.claude/skills/api-docs/references/checklist.md`](../../.claude/skills/api-docs/references/checklist.md) — Review severity criteria ## Cake Targets Reference diff --git a/scripts/benchmark-pipeline.sh b/scripts/benchmark-pipeline.sh index 9cfc10976c3..aaacacb1021 100755 --- a/scripts/benchmark-pipeline.sh +++ b/scripts/benchmark-pipeline.sh @@ -51,8 +51,8 @@ export SKIASHARP_BENCHMARK=1 REPO_ROOT=$(git rev-parse --show-toplevel) REPO_SHA=$(git rev-parse HEAD) DATA_CACHE_SHA=$(git -C .data-cache rev-parse HEAD) -TRIAGE_VALIDATOR="$REPO_ROOT/.github/skills/issue-triage/scripts/validate-triage.ps1" -REPRO_VALIDATOR="$REPO_ROOT/.github/skills/issue-repro/scripts/validate-repro.ps1" +TRIAGE_VALIDATOR="$REPO_ROOT/.claude/skills/issue-triage/scripts/validate-triage.ps1" +REPRO_VALIDATOR="$REPO_ROOT/.claude/skills/issue-repro/scripts/validate-repro.ps1" if [[ -n "$RESUME" ]]; then OUTDIR="$(cd "$RESUME" 2>/dev/null && pwd || echo "$REPO_ROOT/$RESUME")"