microsoft / microsoft/microsoft-ui-reactor
Reactor.Cli can't build offline: one command forces a build-time npm download
- Dominant language
- C#
- Stars
- 646
- Forks
- 54
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 84
Description
## Summary
`src/Reactor.Cli` cannot be built without network access, because `GitHub.Copilot.SDK` downloads a platform-specific Copilot CLI npm tarball during `BeforeBuild`. The dependency exists to serve exactly one command — `mur loc translate` — but the cost is paid by every build of every other command.
## Repro
```
dotnet build src\Reactor.Cli -c Debug -p:Platform=x64
```
```
GitHub.Copilot.SDK.targets(108,5): error MSB3923: Failed to download file
"https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.79.tgz".
The SSL connection could not be established ... TLS alert: 'HandshakeFailure'.
```
Workaround:
```
dotnet build src\Reactor.Cli -c Debug -p:Platform=x64 -p:CopilotSkipCliDownload=true
```
## The coupling
`GitHub.Copilot.SDK` has exactly one consumer in the CLI:
```
src/Reactor.Cli/Loc/AzureOpenAiProvider.cs:2 using GitHub.Copilot;
src/Reactor.Cli/Loc/AzureOpenAiProvider.cs:33 await using var client = new CopilotClient();
```
(The other files matching "Copilot" reference it only in comments or env-var names. The file is renamed to `CopilotTranslationProvider.cs` in #1129.)
So building `mur check`, `mur doctor`, `mur docs`, or `mur --create` from source requires fetching an npm package that only `mur loc translate` will ever use.
## Why it's worth addressing
- **Offline and restricted-network builds fail** with an error that doesn't point at the fix. `MSB3923` naming an npm registry gives no hint that `-p:CopilotSkipCliDownload=true` exists.
- **The opt-out is silently lossy.** Building with the skip flag produces a `mur` whose `loc translate` will fail at runtime, with nothing recording that the binary is degraded.
- **The blast radius is disproportionate.** One command's optional AI backend gates the whole CLI's buildability.
## Options
1. **Move the translation backend into its own assembly** loaded on demand, so `GitHub.Copilot.SDK` isn't in the CLI's build graph. Cleanest, most work.
2. **Make the download lazy/tolerant** — set `CopilotSkipCliDownload=true` by default and have `loc translate` fetch or diagnose at first use, with a clear "run X to enable translation" message.
3. **Minimum, cheap:** keep current behaviour but catch the failure and emit an actionable message naming the opt-out property, and have `loc translate` fail at startup with a clear diagnostic when the binary was built without the asset.
Even option 3 removes most of the pain, since the current failure is a raw `MSB3923` with no breadcrumb.
## Context
Relevant to the broader question of whether `mur loc` is earning its keep: `loc translate` is the least-evidenced command in the CLI (there are zero `.resw` files anywhere in the repo), yet it is the one imposing a build-time network dependency on everything else.
Discovered while building `mur` from source at `88ef6db4`.
Contributor guide
Research direction
Reproduce the offline build with src\Reactor.Cli and inspect the GitHub.Copilot.SDK build target plus src/Reactor.Cli/Loc/AzureOpenAiProvider.cs, the cited SDK consumer. Compare normal and CopilotSkipCliDownload=true builds, then establish a solution that keeps unrelated commands buildable offline and gives loc translate an actionable diagnostic when its asset is unavailable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- build-system, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100