Skill discovery, install, check-updates and update all download the
whole GitHub repo ZIP. The compressed body was collected into a Vec in
memory and capped at 128 MiB, so repos whose docs/ images dwarf the
skills themselves (K-Dense-AI/scientific-agent-skills: 235 MiB ZIP,
277 MiB uncompressed, 20 MiB of skills) failed before extraction even
though they fit the 512 MiB extraction budget and 30k entry cap. The
download cap also reused ARCHIVE_TOO_LARGE, so the UI blamed the
extraction limit.
Stream the body chunk by chunk into an anonymous temp file (deleted on
drop, including error paths), still counting actually received bytes,
and open the ZipArchive from that file. With memory no longer the
constraint, align the download cap with the extraction budget, since a
larger compressed body could not be extracted anyway. Report the
download cap under its own ARCHIVE_DOWNLOAD_TOO_LARGE code with
four-locale text. Extraction budget, entry cap and path/symlink
protections are unchanged.
Refs #8421
Presets: add optional family/versionKey fields so one vendor's regional
and plan variants show as a single row in step 1 (Claude 94 presets ->
71 rows) and as a version switch in step 2. Switching versions after the
user typed into the form asks first, since the form is refilled. The
category field and preset order are unchanged.
Tray: show a dot and a problem tooltip on the icon only while the
routing service failed to start, fell back to direct, or a tray action
failed; spell out that quitting stops the routing service while it is in
use; name the default provider in the Stack submenu title; add the
"restart X to apply" line after tray switches; refresh the tray when the
routing service starts or stops.
Panels: record when the background session scan last finished and show
the newer of that and a manual sync on the usage page; add
resync_mcp_to_apps and resync_skills_to_apps; report per-repo failures
from skill discovery and update checks; report ZIP skills skipped
because the directory is taken. MCP/Skills bulk actions keep applying
to the filtered rows only.