Skip to content

[.NET] SDK should bundle copilot CLI for Mac Catalyst RIDs (maccatalyst-arm64/x64) #454

@PureWeen

Description

@PureWeen

Problem

When using the .NET Copilot SDK (v0.1.23) in a .NET MAUI Mac Catalyst app, the SDK fails to find the bundled copilot CLI binary. This affects any MAUI app targeting Mac Catalyst without a globally installed copilot CLI.

Error: Copilot CLI not found at /path/to/app.app/Contents/MonoBundle/runtimes/maccatalyst-arm64/native/copilot

Root Cause

The SDK's MSBuild targets (GitHub.Copilot.SDK.targets) only map standard RIDs to npm packages:

  • win-x64copilot-win32-x64
  • linux-x64copilot-linux-x64
  • osx-arm64copilot-darwin-arm64
  • etc.

But Mac Catalyst uses maccatalyst-arm64 and maccatalyst-x64 RIDs, which aren't mapped, so the _DownloadCopilotCli target silently skips (condition '$(_CopilotPlatform)' != '' fails).

At build time, no binary is downloaded. At runtime, RuntimeInformation.RuntimeIdentifier returns maccatalyst-arm64, so the SDK looks for runtimes/maccatalyst-arm64/native/copilot — which doesn't exist.

Related Issue

This is the same root cause as #424 (Linux distro-specific RIDs). The SDK maps portable RIDs but runtime uses specific RIDs, causing a mismatch.

Impact

  • Any .NET MAUI app using the SDK on Mac Catalyst breaks for users without globally installed copilot CLI
  • Mac Catalyst is a first-class MAUI platform, so this affects a significant use case
  • The darwin-arm64 binary works perfectly on Mac Catalyst — it just needs to be bundled

Workaround

In the consuming app's .csproj, add targets to map Mac Catalyst RIDs before the SDK's download target:

<Target Name="_FixCopilotRidForMacCatalyst" BeforeTargets="_DownloadCopilotCli">
    <PropertyGroup Condition="'$(_CopilotPlatform)' == '' And $(_CopilotRid.StartsWith('maccatalyst-arm64'))">
        <_CopilotPlatform>darwin-arm64</_CopilotPlatform>
        <_CopilotBinary>copilot</_CopilotBinary>
        <_CopilotRid>osx-arm64</_CopilotRid>
    </PropertyGroup>
    <PropertyGroup Condition="'$(_CopilotPlatform)' == '' And '$(_CopilotRid)' == 'maccatalyst-x64'">
        <_CopilotPlatform>darwin-x64</_CopilotPlatform>
        <_CopilotBinary>copilot</_CopilotBinary>
        <_CopilotRid>osx-x64</_CopilotRid>
    </PropertyGroup>
</Target>

See full workaround: PureWeen/PolyPilot@af249a0

Proposed Fix

In GitHub.Copilot.SDK.targets, add Mac Catalyst RID mappings:

<PropertyGroup>
    <_CopilotPlatform Condition="'$(_CopilotRid)' == 'maccatalyst-x64'">darwin-x64</_CopilotPlatform>
    <_CopilotPlatform Condition="$(_CopilotRid.StartsWith('maccatalyst-arm64'))">darwin-arm64</_CopilotPlatform>
</PropertyGroup>

Better long-term fix (also solves #424): Implement a fallback chain in GetBundledCliPath():

  1. Try specific RID (maccatalyst-arm64, ubuntu.24.04-x64)
  2. Fall back to portable RID (osx-arm64, linux-x64)
  3. Fall back to system PATH

This would handle both Mac Catalyst and distro-specific Linux RIDs gracefully.

Environment

  • SDK version: 0.1.23
  • .NET: 10.0.103
  • Platform: .NET MAUI Mac Catalyst (maccatalyst-arm64)
  • OS: macOS 15.3

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions