Real-world telemetry showed --lang "English (United States)" failing
for several consumer products that only list "English International"
-- the exact example used in --help. The mismatch error now lists the
languages actually available, and the help text notes names vary by
product.
Also fixes truncateError to keep both head and tail of long error
strings (previously kept only the head, which for wrapped errors with
a long URL cut off the actual root cause at the end).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Failure telemetry only recorded success=false with no context. Adds
a truncated error string (150 chars, CLI-side) forwarded to a new
msdl:telemetry:errors Redis hash so failure causes are diagnosable
from /metrics instead of guessed at.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Telemetry was fired as a goroutine then the process exited immediately,
killing it before the HTTP request could complete. Now called
synchronously — sendTelemetry already has a 2s internal timeout so
worst-case latency is unchanged for the user.
Also moves the combined picker into run() so eval products selected
interactively are tagged action=eval with the correct eval_slug instead
of action=interactive with no slug.
Adds What's New changelog section to release notes, auto-generated from
commits since the previous tag.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Interactive `msdl` (no flags) now lists consumer + eval products in one
picker with an Evaluation / Enterprise separator; selecting a server
product routes to the eval flow automatically
- copyToClipboard calls clip.exe by full SystemRoot path, bypassing
cmd.exe PATH lookup that failed in some terminal environments
- CliHandoff card: winget primary install + msdl (no .exe) in run command
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cmd.exe treats & as a command separator, truncating Microsoft's signed
download URLs at the first query parameter boundary. Writing the URL to
a Windows Internet Shortcut (.url) file means cmd.exe only ever sees a
temp filename with no special characters; the browser reads the full URL
from the file contents.
Uses %COMSPEC% to locate cmd.exe reliably across environments.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When multiple download links are returned (e.g. x32+x64 for consumer
ISOs), an architecture picker is shown before printing the URL.
After the URL is printed, an interactive menu lets the user open the
link in the default browser (O), copy it to the clipboard (C), or exit
(Enter). Menu is suppressed when stdout is not a terminal (piping).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show the ISO filename above each link with a separator rule so the
output is easier to read. Updated contribute message to reference
MSDL Web App with URL instead of bare domain.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Redis L2 persistent cache: initRedis() from REDIS_URL env, seed
in-memory linkCache on startup, write-through on every fresh fetch
and background refresh (silent fallback to memory-only if unavailable)
- POST /contribute endpoint: validates product catalog, expiry > 1h,
Microsoft CDN host allow-list, per-IP token bucket (~5/min),
CONTRIBUTE_SECRET header; writes to in-memory + Redis; logs all
accepts and rejections
- CLI --no-contribute flag (also MSDL_NO_CONTRIBUTE=1 env var):
background goroutine posts raw MS JSON to /contribute after every
consumer fetch; best-effort 5s timeout; opt-out message to stderr
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>