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
- 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.
- 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.
- 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.
Summary
src/Reactor.Clicannot be built without network access, becauseGitHub.Copilot.SDKdownloads a platform-specific Copilot CLI npm tarball duringBeforeBuild. The dependency exists to serve exactly one command —mur loc translate— but the cost is paid by every build of every other command.Repro
Workaround:
The coupling
GitHub.Copilot.SDKhas exactly one consumer in the CLI:(The other files matching "Copilot" reference it only in comments or env-var names. The file is renamed to
CopilotTranslationProvider.csin #1129.)So building
mur check,mur doctor,mur docs, ormur --createfrom source requires fetching an npm package that onlymur loc translatewill ever use.Why it's worth addressing
MSB3923naming an npm registry gives no hint that-p:CopilotSkipCliDownload=trueexists.murwhoseloc translatewill fail at runtime, with nothing recording that the binary is degraded.Options
GitHub.Copilot.SDKisn't in the CLI's build graph. Cleanest, most work.CopilotSkipCliDownload=trueby default and haveloc translatefetch or diagnose at first use, with a clear "run X to enable translation" message.loc translatefail 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
MSB3923with no breadcrumb.Context
Relevant to the broader question of whether
mur locis earning its keep:loc translateis the least-evidenced command in the CLI (there are zero.reswfiles anywhere in the repo), yet it is the one imposing a build-time network dependency on everything else.Discovered while building
murfrom source at88ef6db4.