| name | api-surface-lifecycle |
| description | Use for MigrateToWinUI API surface scan, match, coverage, gaps, and rescan workflows across Avalonia, WPF, WinUI, and Uno catalogs, including deterministic command templates, pinned assembly inputs, output checks, and classification versus automation coverage gates. |
API Surface Lifecycle
Use this skill when scanning framework assemblies, matching source APIs to WinUI or Uno, producing coverage reports, creating rule-gap catalogs, or repeating pinned rescans.
References
- CLI examples:
README.md
- CLI contract:
specs/001-migration-core/contracts/cli.md
- API surface contract and schema:
specs/001-migration-core/contracts/api-surface.md, specs/001-migration-core/contracts/api-surface.schema.json
- Committed WPF API artifacts:
specs/001-migration-core/api-surface/README.md
- Rule family catalog:
specs/001-migration-core/rule-family-catalog.md
- Remaining work and coverage semantics:
specs/001-migration-core/remaining-work.md
- Helper scripts and manifests:
scripts/api-surface/
Deterministic Inputs
Before scanning, pin all inputs:
- Framework:
avalonia, wpf, winui, or uno.
- Assembly paths: explicit files only; no package feed lookup inside the workflow.
- Package identity: exact
--package-id and --package-version.
- Output path and format: prefer JSON for machine follow-up, Markdown for review summaries, CSV for tabular inspection.
- Rules:
builtins, a rule-pack file, or a rule-pack directory.
The scanner sorts assembly paths and writes stable catalog data. Do not mix floating package versions or machine-specific discovered assemblies into committed artifacts.
Scan
Scan source or target assemblies:
dotnet run --project src/MigrateToWinUI.Cli -- api scan --framework avalonia --assembly "$HOME/.nuget/packages/avalonia/11.3.7/lib/netstandard2.0/Avalonia.Base.dll" --package-id Avalonia --package-version 11.3.7 --out out/api/avalonia.json --format json
dotnet run --project src/MigrateToWinUI.Cli -- api scan --framework wpf --assembly "/absolute/path/PresentationFramework.dll" "/absolute/path/PresentationCore.dll" "/absolute/path/WindowsBase.dll" "/absolute/path/System.Xaml.dll" --package-id Microsoft.WindowsDesktop.App.Ref --package-version 10.0.5 --out out/api/wpf.json --format json
dotnet run --project src/MigrateToWinUI.Cli -- api scan --framework winui --assembly "/absolute/path/Microsoft.UI.Xaml.dll" --package-id Microsoft.WindowsAppSDK --package-version "<pinned-version>" --out out/api/winui.json --format json
dotnet run --project src/MigrateToWinUI.Cli -- api scan --framework uno --assembly "/absolute/path/Uno.UI.dll" --package-id Uno.UI --package-version "<pinned-version>" --out out/api/uno.json --format json
For committed WPF reference lanes, use the repo helpers instead of hand-maintaining assembly paths:
scripts/api-surface/scan-pinned-wpf-reference-assemblies.sh
scripts/api-surface/classify-pinned-wpf-reference-assemblies.sh
Match
Match each source catalog to a target catalog:
dotnet run --project src/MigrateToWinUI.Cli -- api match --source out/api/avalonia.json --target out/api/winui.json --out out/api/avalonia-to-winui.matches.json --format json
dotnet run --project src/MigrateToWinUI.Cli -- api match --source out/api/wpf.json --target out/api/uno.json --out out/api/wpf-to-uno.matches.json --format json
Exit code 2 means unmatched APIs remain. Continue to coverage/gap reporting instead of treating that as a shell failure when the task is classification planning.
Coverage
Run coverage with built-in rules first, then with any explicit rule packs under review:
dotnet run --project src/MigrateToWinUI.Cli -- api coverage --matches out/api/avalonia-to-winui.matches.json --rules builtins --out out/api/avalonia-to-winui.coverage.json --format json
dotnet run --project src/MigrateToWinUI.Cli -- api coverage --matches out/api/wpf-to-uno.matches.json --rules builtins --out out/api/wpf-to-uno.coverage.md --format md
Coverage acceptance is about classification, not automation:
classificationCoveragePercent must be 100.0 for accepted source catalogs.
unclassifiedSymbolIds and conflictingMatchIds must be empty.
automationCoveragePercent can be lower and must not be used as a classification release gate.
- Manual-review, unsupported, and out-of-scope rows count toward classification only when explicit and auditable.
Exit code 3 means unclassified APIs remain.
Gaps
Generate an API rule-gap catalog whenever coverage is incomplete or new API rows need authoring:
dotnet run --project src/MigrateToWinUI.Cli -- api gaps --source out/api/avalonia.json --matches out/api/avalonia-to-winui.matches.json --rules builtins --out out/api/avalonia-to-winui.gaps.json --format json
dotnet run --project src/MigrateToWinUI.Cli -- api gaps --source out/api/wpf.json --matches out/api/wpf-to-uno.matches.json --rules builtins --out out/api/wpf-to-uno.gaps.md --format md
Use the gap catalog to drive rule-family work. Each row should have one effective classification or a suggested family for authoring.
Rescan
Use manifest-driven rescans for pinned catalog refreshes:
dotnet run --project src/MigrateToWinUI.Cli -- api rescan --manifest specs/001-migration-core/api-surface/manifests/wpf-pinned-reference-assemblies.json --out specs/001-migration-core/api-surface
For ad hoc rescan manifests, require each scan entry to pin framework, assemblies, package id, package version, target framework when relevant, output path, and optional baseline/diff path.
Output checks:
- One catalog is written per scan entry.
- One
.diff.json artifact is written per scan entry.
- Added and changed APIs are counted as unresolved until classified.
- Removed APIs are reviewed before deleting rule evidence.
- Machine-local paths are normalized before committing artifacts.
Manual-Review Gates
Pause before accepting or committing API artifacts when:
- Assembly paths came from floating restore or latest-version probing.
- A source catalog has less than
100.0 classification coverage.
- A match row has conflicting classifications.
- A manual-review, unsupported, or out-of-scope row lacks a diagnostic id, pattern id, rule id, or rationale.
- A rescan diff contains added or changed APIs without a rule-gap follow-up.
- Automation coverage is presented as if it were classification coverage.
Quick Inspection
Prefer structured CLI output, then use text search for triage:
rg -n '"classificationCoveragePercent"|"automationCoveragePercent"|"unclassifiedApiCount"|"unresolvedApiCount"|"classification": "Unknown"' out/api specs/001-migration-core/api-surface
rg -n 'AW2U|WP2U|ManualReview|Unsupported|OutOfScope|SafeRewrite|DiagnosticOnly' out/api specs/001-migration-core/api-surface