Releases
Current and past releases. Binaries for every supported platform are on the
GitHub releases page;
see Install for brew, PowerShell and manual options.
To check what you are running:
quay --version
Notable changes per release. This file is also the source of the GitHub release
notes — dist reads the section matching the version being tagged.
0.16.0 — 2026-10-03
Fixed
- Cancelling a prompt now fails the run. Ctrl-C at the extra-files prompt
(
update,add --force) or atadd -i's per-skill collision prompt used to skip ahead and exit 0, so a wrapping script saw success with skills left untouched. It now stops and exits non-zero withinterrupted, instead of a made-upio error at prompt.update -ialso exits non-zero when any selected skill failed. - Copy mirrors follow an update. A copy-strategy mirror kept the old
version — and any file
--delete-extrahad just removed — with a warning. Mirrors now record a hash of everything quay wrote into them, so one nobody touched is refreshed automatically; one you changed in any way, dotfiles included, is still left alone, with the warning on stderr even under--json.quay link checkreports an out-of-date copy. A copy mirror made by an older version is picked up the first time it matches canonical; one that already differs needs a singlequay link --force. - Copy mirrors keep symlinks as symlinks. They were dereferenced into plain files, so a skill containing a symlink never matched its mirror.
- A failed multi-skill
updatestill reports what it changed. The skills updated before the failure — and theirdeleted_extras— are printed before the error, instead of nothing. - An update never touches a directory named
.<skill>.replaced. The old install is parked in a fresh, uniquely named directory instead of a fixed name that was cleared first. - Files with non-UTF-8 names are never offered for deletion. Two such names could map to the same entry, and deleting it removed both.
Added
quay update --jsonreportsdeleted_extrasper skill — what was actually removed, as reported by the install itself.quay diff --jsonreportscommits_aheadandlast_commit_dateforhub_newer.
Changed
quay-core:FolderReport::head_hash→hub_hash,ReconcileReport::head_bytes→hub_bytes, matching the CLI's naming.SkillManager::add_with_extras/update_one_with_extrasreturn the paths they deleted.
Docs
- Eight recipe pages written; corrected
add,remote,profile,updateand the GitHub tutorial where they disagreed with the CLI.
0.15.3 — 2026-08-03
Performance
-
quay diffno longer spends a network round-trip per file. Comparing a skill directory read one git process per file, plus another to establish that the file existed — and because quay clones the hub without file contents and fetches them on demand, each of those reads was its own request over the wire. A twenty-file skill checked against fifty candidate commits meant thousands of processes and as many requests, and against a large hub the command could take minutes.A revision is now read in one pass: a single listing names every file and every object in it, and a single batch read returns their contents. Batching the reads was not enough on its own — git's batch reader still fetches missing objects one at a time — so quay asks for the whole revision's objects in one request first. A clone that already holds them skips that step without opening a connection, so nothing is slower than it was.
Fixed
- A failed read now names the skill it could not read. When the hub becomes
unreachable mid-comparison, the failure used to surface as raw git output with
no indication of which skill or which revision produced it — and
quay diffcan hit it fifty times per skill. It now says both, and points at hub access.
Internal
- Listing and reading a harbor directory are one operation rather than two. The rule for turning a repository path into a skill-relative one had been written out in three places; no caller applies it any more.
- The batch-response decoder is a pure function with its own tests, and it checks each record against the object that was asked for. Pairing content with paths is positional, so a single misaligned record would file one file's bytes under another file's name and render a confident diff between two files that are identical.
- The folder-level test suite now pins the server capability that decides whether a clone is really content-free, so those tests exercise the path production takes instead of depending on the developer's git configuration.
0.15.2 — 2026-07-31
Fixed
quay addno longer tells you that you edited a skill when it simply stopped looking. To decide which side moved, quay walks the hub's history looking for the commit your copy came from, and gives up after 200 commits. Exhausting that budget was reported the same way as searching the whole history and finding nothing: differs from harbor (direction unknown, local edits present). On a skill with a long history that sentence was a claim about you, derived from a spent search. The folder-levelquay diffhas always drawn this distinction; the single-file path now does too, and says only what it knows.
Internal
- The reconcile verdict is a closed set of five cases rather than four plus a
boolean carrying three meanings, and a per-file change now holds its own diff
instead of an
Optionthat was only everNonefor unchanged files. No output changed — verified across six hub fixtures through bothquay diffandquay diff --json. quay add's Replace action carries the bytes it writes. It previously took them as a separate argument, which made a zero-byte overwrite representable if the two ever disagreed.
0.15.1 — 2026-07-31
Fixed
-
A hub you cannot reach no longer reads as a hub that deleted your skill.
quay diffandquay add's collision check clone the hub blobless and fetch file contents on demand. The existence probe treated every non-zero exit from git as "this path does not exist at that revision" — but a genuinely absent path and a failed fetch exit with the same code. So an expired token, a network blip or an outage rendered asno longer on the hub (deleted or renamed there), and the reconcile baseline walk quietly skipped commits it could not read, downgrading the verdict to "no commit matches your copy".Existence is now decided from the repository's tree, which is always present locally and needs no network, and only then is content fetched — where a failure is reported as the failure it is.
Only blobless clones were affected, which is every
quay diffagainst a real hub. Nothing was written to disk incorrectly; the verdicts were wrong, not the files.
0.15.0 — 2026-07-31
Changed
-
updateandadd --forcenow notice local files the hub deleted, and ask what to do with them. Both re-materialize a skill from a fresh fetch, and both used to silently carry forward every local file the new version did not contain, forever. That preserved the notes you wrote — and also resurrected every file the hub had removed, soquay diffreported it as local-only for the life of the install. The default is still to keep everything; nothing is deleted without a flag or an explicit answer.quay cannot tell the two apart on its own: the lockfile records a content hash, not a file list, so nothing on disk says what the previous install put there. So it asks. Files the new version lacks are listed, and you can keep them, delete them, pick individually, or keep these and every remaining skill's without being asked again.
Without a terminal — CI, a pipe, or
--json— nothing is deleted. The files are kept and a note says so, which means no existing script changes behaviour on upgrade.--keep-extraand--delete-extradecide it outright and work unattended;--delete-extranames on stderr every file it removed, so an unattended run still leaves a record of it.Dotfiles, dot-directories and symlinks are never offered and never deleted. They are outside the set quay manages, and one of them —
.quay-mirror— is what marks a copy mirror as quay-managed.
Fixed
- A symlink inside an installed skill no longer gets flattened into a plain
copy on
update/add --force. Carrying an extra file forward decided whether to recurse into it by asking if it was a directory, which follows symlinks — so a symlink to a file was silently replaced by a byte-for-byte copy of its target, and a symlink to a directory was worse: the target's contents were recursed into and copied as though they belonged to the skill. Both are now recreated as the symlink they were. On Windows, where recreating a symlink needs Developer Mode or elevation that an ordinary user is unlikely to have, the update warns and carries on rather than failing: a link to a file falls back to copying its contents, and a link to a directory is skipped, since copying a directory's contents in is the very thing this fixes.
0.14.1 — 2026-07-27
Fixed
push --bumpno longer rewrites your frontmatter. It re-emitted the whole block from the parsed manifest, so the hub copy kept only the fields quay models:license: MITcame back aslicense: null, andcompatibility,metadataandallowed-toolswere dropped outright.allowed-toolsis the only machine-readable statement of what a skill may do, and the hub copy is what everyone else installs. The bump now rewrites theversion:scalar and passes every other byte through, CRLF frontmatter included.
0.14.0 — 2026-07-27
Added
-
quay diff <skill>— read-only report of how a locally installed skill differs from the hub's copy.quay outdatedsays that something differs; this says what, file by file, with a verdict derived from hub history rather than from version numbers (hub is ahead by N commits,your copy is ahead,no longer on the hub, …). Supports--remoteand--json.It compares the whole skill directory. The reconcile engine that backs
quay add's collision prompt only ever looked atSKILL.md, so a skill whosereferences/orscripts/moved on the hub reported as identical. Diffs are pull-oriented:+is what the hub would give you.
Fixed
-
quay outdatedno longer misses a hub edit that shipped without a version bump. Frontmatter skills were compared by semver alone, so a hub maintainer who fixed a typo or editedreferences/without touchingversionleft every consumer reading "everything up to date" on a stale copy. Content is now compared for every skill format and reported as its own row —differs from hub at <version>— alongside the existinglocal -> <version>upgrade rows.--jsonand thequay_outdatedMCP tool gain acontent_driftfield so the two reasons can be told apart.Drift is direction-neutral: two hashes prove the bytes differ, not which side changed them.
quay updatestill acts on version upgrades only, so drift rows point atquay add <name> --force.Line endings are normalized before comparing, so a Windows checkout (
core.autocrlf) does not report every installed skill as drifted. The publishedcontent_hashis unchanged — no registry needs regenerating.
0.13.4 — 2026-07-23
Security
registry.jsonfile paths are validated before anything is fetched. The registry is downloaded from the remote hub, and itsfileslist went straight into a path join unchecked — an entry like"../../../.ssh/authorized_keys"wrote there, and an absolute path escaped the skill directory entirely. Absolute paths,..components and Windows drive/UNC prefixes are now rejected. If you install from a hub you do not control, update.
Fixed
- Windows: frontmatter is parsed in files with CRLF line endings. Git's
default
core.autocrlfrewrites line endings on checkout, so on Windows every frontmatter skill silently degraded to "freestyle" — losing its name, description and version, and listing asunversioned. - Windows:
--forcecan replace a symlinked mirror. Unlinking usedremove_file, which fails on the directory symlinks and junctions that mirrors are on Windows, soquay link --force,quay add --forceandquay agents link --forcecould not replace an existing mirror. - Dot-prefixed directories are never treated as skills. A staging directory
left behind by an interrupted
quay addcould appear inquay listas a skill named.tmpAbCdEf, andquay linkwould mirror it into every tool directory.
Internal
- CI runs
cargo fmt,cargo clippyand the test suite on every pull request, on Linux and Windows. The suite had never compiled on Windows, which is how the two bugs above went unnoticed. - The Rust toolchain is pinned in
rust-toolchain.tomlat the repo root, so a new Rust release cannot turn CI red on its own and contributors resolve the same compiler CI uses.
0.13.3 was tagged but never published — the release build failed — and its changes are included here.
0.13.2 — 2026-07-23
Fixed
quay addno longer leaves a partial skill behind when a fetch fails. Files were written directly into.agents/skills/<name>/as they downloaded, so a network failure part-way through stranded a half-installed skill that then blocked its own retry withAlreadyExists. The fetch now stages in a temporary directory and is renamed into place only once every file has landed.- A failed
--forceinstall no longer destroys the existing skill. The previous copy is moved aside and restored if the replace fails, rather than deleted up front. quay updatepreserves files that are not in the skill manifest — local notes, files dropped upstream — matching the previous overwrite-in-place behaviour.
0.13.1 — 2026-07-23
Fixed
quay linkreported mirrors it had just created as no-ops when the interactive adopt opt-in triggered a second reconcile pass. The actions from the first pass are now kept.
0.13.0 — 2026-07-23
Added
- Mirror reconcile.
quay linkscans all known tool directories on disk (.agents/.claude/.codex/.cursor), not just the ones in[install].mirrors, so a mirror added outside the config is still seen. install.auto_link(opt-in) in.quay/config.toml: adopt an unmanaged tool directory that is byte-identical to canonical, converting it to a managed mirror. Asked once interactively and remembered; non-interactive runs (--json, CI) never adopt.
Changed
quay linkrefuses to overwrite a mirror whose content diverged from canonical. Copy-strategy mirrors were previously re-materialised unconditionally and hand edits were lost silently. Pass--forceto discard the mirror edit, or copy it into the canonical skill first.quay link checkis read-only — it detects drift but never creates or overwrites.
0.2.0
Removed
quay sync— skills are tracked by git history; commit your.agents/skills/changes normally.quay create— writeSKILL.mddirectly, with your editor, an AI agent, or any tool.skills.lock.jsonis no longer written. If a legacy lockfile exists, quay prints a one-time notice and instructions to delete it.
Changed
quay addJSON output no longer returnsversion/remotefields — those came from the lockfile.