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 at add -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 with interrupted, instead of a made-up io error at prompt. update -i also 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-extra had 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 check reports 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 single quay 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 update still reports what it changed. The skills updated before the failure — and their deleted_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 --json reports deleted_extras per skill — what was actually removed, as reported by the install itself.
  • quay diff --json reports commits_ahead and last_commit_date for hub_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_extras return the paths they deleted.

Docs

  • Eight recipe pages written; corrected add, remote, profile, update and the GitHub tutorial where they disagreed with the CLI.

0.15.3 — 2026-08-03

Performance

  • quay diff no 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 diff can 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 add no 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-level quay diff has 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 Option that was only ever None for unchanged files. No output changed — verified across six hub fixtures through both quay diff and quay 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 diff and quay 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 as no 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 diff against a real hub. Nothing was written to disk incorrectly; the verdicts were wrong, not the files.

0.15.0 — 2026-07-31

Changed

  • update and add --force now 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, so quay diff reported 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-extra and --delete-extra decide it outright and work unattended; --delete-extra names 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 --bump no 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: MIT came back as license: null, and compatibility, metadata and allowed-tools were dropped outright. allowed-tools is the only machine-readable statement of what a skill may do, and the hub copy is what everyone else installs. The bump now rewrites the version: 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 outdated says 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 --remote and --json.

    It compares the whole skill directory. The reconcile engine that backs quay add's collision prompt only ever looked at SKILL.md, so a skill whose references/ or scripts/ moved on the hub reported as identical. Diffs are pull-oriented: + is what the hub would give you.

Fixed

  • quay outdated no 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 edited references/ without touching version left 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 existing local -> <version> upgrade rows. --json and the quay_outdated MCP tool gain a content_drift field so the two reasons can be told apart.

    Drift is direction-neutral: two hashes prove the bytes differ, not which side changed them. quay update still acts on version upgrades only, so drift rows point at quay add <name> --force.

    Line endings are normalized before comparing, so a Windows checkout (core.autocrlf) does not report every installed skill as drifted. The published content_hash is unchanged — no registry needs regenerating.

0.13.4 — 2026-07-23

Security

  • registry.json file paths are validated before anything is fetched. The registry is downloaded from the remote hub, and its files list 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.autocrlf rewrites line endings on checkout, so on Windows every frontmatter skill silently degraded to "freestyle" — losing its name, description and version, and listing as unversioned.
  • Windows: --force can replace a symlinked mirror. Unlinking used remove_file, which fails on the directory symlinks and junctions that mirrors are on Windows, so quay link --force, quay add --force and quay agents link --force could not replace an existing mirror.
  • Dot-prefixed directories are never treated as skills. A staging directory left behind by an interrupted quay add could appear in quay list as a skill named .tmpAbCdEf, and quay link would mirror it into every tool directory.

Internal

  • CI runs cargo fmt, cargo clippy and 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.toml at 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 add no 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 with AlreadyExists. The fetch now stages in a temporary directory and is renamed into place only once every file has landed.
  • A failed --force install no longer destroys the existing skill. The previous copy is moved aside and restored if the replace fails, rather than deleted up front.
  • quay update preserves 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 link reported 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 link scans 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 link refuses to overwrite a mirror whose content diverged from canonical. Copy-strategy mirrors were previously re-materialised unconditionally and hand edits were lost silently. Pass --force to discard the mirror edit, or copy it into the canonical skill first.
  • quay link check is 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 — write SKILL.md directly, with your editor, an AI agent, or any tool.
  • skills.lock.json is no longer written. If a legacy lockfile exists, quay prints a one-time notice and instructions to delete it.

Changed

  • quay add JSON output no longer returns version/remote fields — those came from the lockfile.