Introduction

quay is a CLI and TUI for sharing skills — small Markdown + YAML packages that teach AI coding agents project conventions, internal APIs, and team workflows — across many repos and many machines without a hosted registry.

Skills live as plain files in your repo at .agents/skills/<name>/SKILL.md. quay synchronises them with a hub: any git repository you control (GitHub, GitLab, Azure DevOps, Bitbucket). Push a skill to the hub; teammates quay add <name> it from a different project on a different machine. Mirror directories (.claude/skills/, .cursor/rules/, etc.) stay in sync automatically.

Why not a registry-as-a-service?

  • No third-party server. Your hub is a git repo you already trust. No new accounts, no rate limits, no vendor lock-in.
  • Audit-friendly. Every push is a commit. Every install reads a registry.json committed in plain text. git log is your history.
  • Air-gap-friendly. Self-host the hub on Gitea, GitLab CE, or a Bitbucket server. quay does not phone home.
  • Filesystem-first. Skills are files. Edit them with $EDITOR. git diff works. No special API.

Who this is for

  • Engineers who run Claude Code, Cursor, or other agentic tools and want skill libraries that travel with the team — not the laptop.
  • Teams running a mixed-provider stack (work GitHub + personal GitLab + customer Azure DevOps) who need profile-scoped configuration.
  • Tooling authors building project bootstrapping flows (CI runners, devcontainers, ephemeral envs) that need declarative skill installs.

What's next

Getting started

Five minutes from zero to a skill shared between two projects.

1. Install

Homebrew:

brew install evgeniiPerov/tap/quay

Or download a release binary from https://github.com/evgeniiPerov/quay/releases and put it on your PATH.

Verify:

quay --version

macOS Gatekeeper: the first run may be blocked. Right-click the binary → Open once, or xattr -dr com.apple.quarantine /opt/homebrew/bin/quay.

2. Create a profile

A profile holds your default hub URL, default branch, push mode (PR or direct), and provider kind. The interactive wizard sets everything in one go:

quay profile add -i

Pick a name (e.g. work), paste your hub URL (e.g. git@github.com:my-org/skills-hub.git), answer two more prompts. Done.

Confirm it took:

quay profile show

3. Launch the TUI

quay tui

The Dashboard lists your remotes, recent pushes, and outdated installed skills. Press [1]/[2]/[3] to switch screens, [,] for Settings, [q] to quit.

4. Author a skill

From any project directory:

mkdir -p .agents/skills/hello
$EDITOR .agents/skills/hello/SKILL.md

Paste a minimal frontmatter skill:

---
name: hello
description: Say hello.
version: 0.1.0
---

# Hello

Print "hi" when the agent starts.

5. Push

quay push hello

quay clones your hub into a temp dir, drops the skill into skills/hello/SKILL.md, updates the hub's registry.json, commits, and (depending on push_mode) opens a PR or pushes the commit directly. The URL is printed on success.

From the TUI: open Local ([2]), select hello, press [u].

6. Install in a different project

In a freshly-cloned repo on another machine:

quay add hello

The skill lands at .agents/skills/hello/SKILL.md. Mirror dirs (.claude/, .cursor/, etc.) are populated automatically based on your profile.

Next steps

Concepts

Short definitions for the vocabulary used in the rest of the book.

Skill

A directory under .agents/skills/<name>/ containing at least SKILL.md. The Markdown body is what an AI agent reads; the optional YAML frontmatter (name, description, version, tags) gives quay structured metadata.

quay tolerates three skill formats:

  • Frontmatter — YAML block at the top. Versioned, tagged, the recommended form.
  • SlashCommand — single-line H1 in the form # /<name>. Convention for slash-command-style skills.
  • Freestyle — anything else. Treated as a skill with defaults (dir-name = name, version = 0.0.0).

Hub

Any git repository you control. quay reads and writes skills/<name>/SKILL.md plus a top-level registry.json describing the set. A hub is just a repo — clone it, browse it on GitHub, run CI against it.

Profile

A named bundle of defaults in ~/.config/quay/config.toml: the default hub URL, branch, push_mode, mirror dirs (.claude/skills/, .cursor/rules/, …), and a provider hint. Switch with quay profile use -i or [p] in the TUI.

Remote

A profile's hub URL plus its provider kind (one of github, githubenterprise, gitlab, bitbucket, azuredevops). Per-command override: quay push --remote work-gitlab ….

Provider

The plug-in that knows how to talk to a specific git host: how to parse the URL, how to open a PR (gh, glab, az), how to construct a fallback compare URL, and how to run a connectivity check. Bitbucket has no CLI binding; quay always falls back to a compare URL there.

Mirror dirs

Tools like Claude Code read skills from .claude/skills/, Cursor from .cursor/rules/. quay keeps copies of installed skills synced from the canonical .agents/skills/ into these mirror dirs based on each profile's mirrors setting.

Registry

registry.json at the hub root. A { skills: { <name>: { version, … } } } map describing the hub's contents. quay search and quay add read it. quay rebuild-registry <remote> regenerates it from skills/*/SKILL.md if it ever drifts.

Push log

~/.config/quay/push-log.json. An append-only record of every successful push: skill name, remote, commit SHA or PR URL, timestamp, source project path. Drives the Dashboard "recent pushes" panel and pushed-local / pushed-direct status badges.

Drift detection

quay outdated and quay scan compute a SHA-on-the-fly for every installed skill and compare to the hub's recorded SHA. A modified local file gets the installed-modified badge; the hub having a newer commit gets outdated. quay add --force overwrites local drift.

push_mode

Per-remote setting controlling commit behaviour:

  • pr (default) — quay creates a feature branch, pushes it, and opens a PR via the provider CLI (gh, glab, az). Bitbucket falls back to a compare URL.
  • direct — quay commits straight to the default branch and git push. Used for repos with no branch protection where review overhead is not worth it.

Override per-call: quay push --push-mode direct.

Default-interactive

Most CLI commands detect a TTY and prompt for missing arguments. Pipe them into xargs / scripts and they switch to non-interactive: quay push hello < /dev/null errors instead of prompting. The [i] indicator in --help output marks flags that have wizard equivalents.

[Space] selection

In the TUI's Local screen, [Space] toggles a per-row selection mark. Bulk operations ([U] push selected, [D] delete selected) run against the marked set. [u] / [d] (lowercase) act on the cursor row only.

Author your first skill

End-to-end walkthrough: write a small skill, push it to a hub, install it from a different project.

Pre-reqs: quay on PATH, a profile already configured (quay profile add -i if not).

1. Pick a tiny example

We'll author a skill that teaches an agent to apply a one-rule lint fix: "use early returns instead of nested else."

mkdir -p ~/code/origin-project/.agents/skills/early-returns
cd ~/code/origin-project
$EDITOR .agents/skills/early-returns/SKILL.md

Paste:

---
name: early-returns
description: Refactor nested `else` chains into early returns.
version: 0.1.0
tags: [refactor, code-style]
---

# Early returns

When you see code shaped like:

```js
if (cond) {
  doA();
} else {
  doB();
}

…and doA is short, prefer an early return:

if (cond) {
  doA();
  return;
}
doB();

Apply to JavaScript, TypeScript, and Rust. Skip Python (no early-return idiom in match-case).


## 2. Validate offline

```sh
quay validate early-returns

Expect OK (or warnings on stderr; exit 0 in soft mode). Fix anything flagged before pushing.

3. Push

quay push early-returns

What happens:

  1. quay clones your default-profile hub into a temp dir.
  2. Copies SKILL.md to skills/early-returns/SKILL.md.
  3. Updates the hub's registry.json with name, description, version, tags.
  4. Commits.
  5. Per your remote's push_mode: opens a PR (default) or pushes the branch directly.
  6. Prints the PR URL or commit SHA.
  7. Appends an entry to ~/.config/quay/push-log.json.

If push_mode = pr, merge the PR before continuing.

4. Consume from a different project

In a fresh shell, fresh directory:

mkdir -p ~/code/consumer-project
cd ~/code/consumer-project
git init      # optional; quay does not require git
quay add early-returns

The skill lands at .agents/skills/early-returns/SKILL.md. Mirror dirs (.claude/, .cursor/, …) get copies based on your profile's [install].mirrors.

Confirm:

quay list
quay scan

scan should show early-returns with status installed.

5. What if you edit the local copy?

Edit consumer-project/.agents/skills/early-returns/SKILL.md — add a sentence. Re-scan:

quay scan

Status flips to installed-modified. quay outdated will refuse to overwrite it. To force re-sync:

quay add early-returns --force

Next

Multi-provider setup

Three profiles on one machine: work GitHub, work GitLab, personal Azure DevOps. Switch with one command.

Why three profiles?

Each profile is a bundle of:

  • Commit identity — author email used in hub commits.
  • Remote(s) — hub URLs plus provider kind and push mode.
  • Install settings — mirror dirs.

You want a separate profile per identity so commits to your work hub are tagged with your work email, and personal pushes use your personal email.

1. First profile: work GitHub (wizard)

quay profile add -i

Answer:

  • Name: work-github
  • Email: you@corp.example
  • Hub URL: git@github.com:my-org/skills-hub.git
  • Provider: github (auto-detected)
  • Push mode: pr
  • Activate: yes

Confirm:

quay profile current   # → work-github
quay profile show

2. Second profile: work GitLab (explicit flags)

quay profile add work-gitlab \
  --email you@corp.example \
  --remote main=git@gitlab.com:my-org/skills-hub.git \
  --provider gitlab \
  --push-mode pr \
  --default

--default marks main as the profile's default remote.

3. Third profile: personal Azure DevOps (TOML)

Useful pattern for committable configs. Drop this in ~/code/quay-profiles/personal-azure.toml:

name = "personal-azure"
email = "me@personal.example"

[[remotes]]
name = "main"
url = "https://dev.azure.com/myorg/skills/_git/skills-hub"
provider = "azuredevops"
push_mode = "pr"
default = true

Add it:

quay profile add personal-azure --from-toml ~/code/quay-profiles/personal-azure.toml

Stdin works too — handy for scripted bootstrap:

cat ~/code/quay-profiles/personal-azure.toml | quay profile add personal-azure --from-toml -

4. Switch profiles

Interactive picker:

quay profile use -i

Direct:

quay profile use work-gitlab
quay profile current   # → work-gitlab

For a one-shot override without persisting:

quay --profile personal-azure push early-returns
# or
QUAY_PROFILE=personal-azure quay push early-returns

5. Push the same skill to all three

Author once, publish thrice:

quay profile use work-github
quay push early-returns

quay profile use work-gitlab
quay push early-returns

quay profile use personal-azure
quay push early-returns

Each push records to ~/.config/quay/push-log.json with the active profile + remote URL.

6. Verify

quay profile list

Expect three entries with the active one starred. quay search early-returns (run under any profile) returns hits across that profile's remotes.

Next

GitHub

GitHub-specific setup notes. Covers github.com and GitHub Enterprise (githubenterprise).

Auth

quay clones over SSH or HTTPS — whatever URL you give it. SSH is simplest:

  1. Generate a key: ssh-keygen -t ed25519 -C "you@example.com".
  2. Add the public key at https://github.com/settings/keys.
  3. Test: ssh -T git@github.com (expect a "successfully authenticated" message).

HTTPS works too if you have git config --global credential.helper wired up (Keychain on macOS, libsecret on Linux, manager-core on Windows).

CLI binding: gh

For PR creation, quay shells out to gh. Install:

brew install gh     # macOS
sudo apt install gh # Debian/Ubuntu (or via official .deb)

Authenticate once:

gh auth login

Pick HTTPS or SSH (matching your clone preference). Without gh, quay push in PR mode falls back to printing a compare URL — you'll need to open the PR in the browser manually.

URL formats

FormUse
git@github.com:org/repo.gitSSH. Auto-detected as github.
https://github.com/org/repo.gitHTTPS. Auto-detected as github.
git@ghe.example.com:org/repo.gitGitHub Enterprise. Pass --provider githubenterprise.

Add the remote

quay remote add work git@github.com:my-org/skills-hub.git --provider github --default
quay remote test work    # connectivity probe

Branch policy gotchas

  • If main is protected (required reviews, status checks), push_mode = "direct" will fail at git push origin main. Use push_mode = "pr" (the default) or pass --push-mode pr.
  • The PR is opened against the default branch, not necessarily main. quay reads the remote's HEAD ref after clone.
  • The PR branch is named quay/<skill-name>-<short-sha>. Pruned automatically on merge if your repo has "Automatically delete head branches" enabled.

Enterprise

GitHub Enterprise Server uses the same gh CLI, but you must authenticate against the EE host:

gh auth login --hostname ghe.example.com

Set the provider explicitly:

quay remote add ee git@ghe.example.com:platform/skills.git --provider githubenterprise --default

Common errors

SymptomFix
gh: command not found (in PR mode)Install gh, or accept compare-URL fallback.
Permission denied (publickey)SSH agent not running / key not added. ssh-add ~/.ssh/id_ed25519.
403 Resource not accessible (from gh)PAT scope missing. Re-run gh auth login and grant repo.
Stale registry.json after pushCDN cache; wait ~60s or quay rebuild-registry.

Next

GitLab

GitLab-specific setup. Works for gitlab.com and self-hosted GitLab CE/EE.

Auth

SSH is the typical path:

  1. ssh-keygen -t ed25519 -C "you@example.com".
  2. Paste the public key at https://gitlab.com/-/user_settings/ssh_keys.
  3. Test: ssh -T git@gitlab.com (expect "Welcome to GitLab, @you!").

HTTPS works with a personal access token — generate one at https://gitlab.com/-/user_settings/personal_access_tokens with write_repository scope and configure your credential helper.

CLI binding: glab

For MR (merge request) creation, quay shells out to glab. Install:

brew install glab

Authenticate:

glab auth login

Pick the right host (gitlab.com or your self-hosted instance) and method (HTTPS-token or SSH). Without glab, PR mode falls back to a compare URL.

URL formats

FormUse
git@gitlab.com:group/repo.gitSSH. Auto-detected as gitlab.
https://gitlab.com/group/repo.gitHTTPS. Auto-detected as gitlab.
git@git.corp.example:platform/skills.gitSelf-hosted. Pass --provider gitlab to be explicit.

Add the remote

quay remote add work git@gitlab.com:my-group/skills-hub.git --provider gitlab --default
quay remote test work

Default branch quirks

  • Newer projects default to main; older ones may still be on master. quay reads HEAD after clone, so either works without configuration.
  • Default branch settings on the project page determine which branch your MR targets. Change it there if needed.

Branch policy gotchas

  • "Protect default branch" is the GitLab equivalent of GitHub's branch protection. push_mode = "direct" will fail with remote: GitLab: You are not allowed to push code to protected branches.
  • "Approval rules" do not block glab mr create; they block the merge. Your MR is opened successfully, then awaits approvals.
  • Squash settings come from project config; quay does not override them.

Self-hosted

The provider name is gitlab regardless of where the instance lives — the URL is what matters. Authenticate glab against the right host:

glab auth login --hostname git.corp.example

Common errors

SymptomFix
glab: command not foundInstall glab or accept compare-URL fallback.
error: failed to push some refs to 'gitlab.com'Wrong key in agent, or branch protected. Check ssh-add -l and project settings.
401 Unauthorized from glabToken expired or scope missing. glab auth login again.
MR opens but immediately closesProject has "Auto-close MR" tied to default-branch matches; check project settings → Merge requests.

Next

Azure DevOps

Azure DevOps Repos (dev.azure.com) and Azure DevOps Server (on-prem).

Auth

Two options, both common:

SSH — generate a key, paste at User settings → SSH public keys in Azure DevOps. Test:

ssh -T git@ssh.dev.azure.com

PAT over HTTPS — generate a Personal Access Token with Code (Read & write) scope. Use it as the password when prompted; cache via your credential helper.

CLI binding: az repos

quay uses az repos pr create for PR mode. Install the Azure CLI:

brew install azure-cli      # macOS
# or: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az extension add --name azure-devops

Sign in:

az login
az devops configure --defaults organization=https://dev.azure.com/myorg project=skills

Without az, PR mode falls back to printing a compare URL.

URL formats

Azure DevOps URLs are long. Two equivalents quay accepts:

FormUse
https://dev.azure.com/<org>/<project>/_git/<repo>HTTPS. Auto-detected as azuredevops.
git@ssh.dev.azure.com:v3/<org>/<project>/<repo>SSH. Auto-detected as azuredevops.

Add the remote

quay remote add work https://dev.azure.com/myorg/skills/_git/skills-hub --provider azuredevops --default
quay remote test work

Branch policy gotchas

Azure DevOps "Branch policies" are powerful and strict:

  • Minimum reviewers — direct push to a policied branch fails. Use push_mode = "pr".
  • Build validation — PR cannot complete until pipeline passes. quay's job ends at PR-create; you wait for the build.
  • Required reviewers — auto-assigned, no quay involvement.

For low-friction internal hubs, exempt the hub repo from branch policies (Repos → Branches → policies) and use push_mode = "direct".

Default branch

Reads HEAD from the remote after clone. New repos default to main; older ones may be master. Set the default at Repos → Branches.

Common errors

SymptomFix
az: command not foundInstall Azure CLI + azure-devops extension.
TF401019 (no access)PAT scope wrong; regenerate with Code (Read & write).
RemoteRejection: pre-receive hookBranch policy. Use --push-mode pr.
pull request creation failed from azaz devops configure defaults not set, or extension missing. Re-run setup.

Server (on-prem)

Same provider name (azuredevops). Authenticate az against the on-prem URL:

az devops configure --defaults organization=https://tfs.corp.example/<collection> project=skills

Next

Bitbucket

Bitbucket Cloud (bitbucket.org) and Bitbucket Data Center (server).

The Bitbucket gotcha

Bitbucket has no first-party CLI with the breadth of gh / glab / az repos. quay does not shell out to anything. Consequence: PR mode always falls back to a compare URL. You open the PR in the browser manually.

If you want a hands-off flow, use push_mode = "direct" against an unprotected hub repo.

Auth

SSH:

  1. ssh-keygen -t ed25519 -C "you@example.com".
  2. Paste the public key at https://bitbucket.org/account/settings/ssh-keys/.
  3. Test: ssh -T git@bitbucket.org.

HTTPS uses an App Password, not your account password:

  1. https://bitbucket.org/account/settings/app-passwords/ → Create app password.
  2. Grant Repositories: Read, Write.
  3. Use it as the password when prompted; cache via credential helper.

URL formats

FormUse
git@bitbucket.org:workspace/repo.gitSSH. Auto-detected as bitbucket.
https://bitbucket.org/workspace/repo.gitHTTPS. Auto-detected as bitbucket.

Add the remote

quay remote add work git@bitbucket.org:my-workspace/skills-hub.git --provider bitbucket --default
quay remote test work

Direct push

quay remote add work git@bitbucket.org:my-workspace/skills-hub.git \
  --provider bitbucket --push-mode direct --default
quay push early-returns                  # commit lands on default branch immediately

PR mode (compare-URL fallback)

quay remote add work git@bitbucket.org:my-workspace/skills-hub.git \
  --provider bitbucket --push-mode pr --default
quay push early-returns
# Output: branch pushed, open this URL to create the PR:
# https://bitbucket.org/my-workspace/skills-hub/pull-requests/new?source=...&dest=...

quay pushes the branch and prints the compare URL. Click → fill out the PR description → submit.

Branch policy gotchas

  • Bitbucket "Branch restrictions" block direct pushes. Use push_mode = "pr".
  • "Default reviewers" auto-attach on the compare-URL form; you don't need to add them manually.
  • Bitbucket squash-on-merge is per-repo. quay does not override it.

Data Center (server)

Same provider name (bitbucket). URLs differ (git@stash.corp.example:scm/proj/repo.git); detection by host substring is approximate, so pass --provider bitbucket explicitly.

Common errors

SymptomFix
Permission denied (publickey)SSH key not added at account-settings → SSH keys.
401 over HTTPSUsing account password instead of App Password. Generate one.
pre-receive hook declined on direct pushBranch restriction. Use --push-mode pr.

Next

CLI overview

quay is a single binary with sixteen subcommands. Every subcommand respects four global options:

FlagEffect
--project <PATH>Treat <PATH> as the project root instead of cwd.
--user-config <PATH>Override user config (default: ~/.config/quay/config.toml).
--profile <NAME>Override active profile for this invocation. QUAY_PROFILE env var works too.
--jsonEmit machine-readable JSON on stdout instead of a human table.

Subcommand groups

Project setup

  • init — drop a .quay/config.toml skeleton into the current project.
  • remote — add / list / test / remove configured hub remotes.
  • profile — manage user profiles (work + personal on one machine).

Consume

  • add — install a skill from a hub.
  • list — list currently installed skills (no dedicated page; covered briefly below).
  • info — show metadata for a skill without installing.
  • search — free-text search across configured remotes.
  • outdated — list installed skills with newer hub versions.
  • update — pull newer versions over installed skills.
  • remove — uninstall a skill (optionally --everywhere).
  • link — manage mirror dirs (.claude/, .cursor/, …).

Author / publish

  • scan — discover local skills and their sync status.
  • validate — check frontmatter offline.
  • push — publish a skill to a hub.
  • rebuild-registry — regenerate hub registry.json from disk.

Other

  • tui — launch the interactive terminal UI.

quay list

Prints every installed skill in the current project plus its version and source remote. Common flags only (--profile, --user-config, --project, --json). Use it as a sanity check after quay add, or to feed xargs in scripts:

quay list --json | jq -r '.[].name' | xargs -n1 quay info

Exit codes

See Exit codes for the full table. Quick reference:

CodeMeaning
0Success
1Generic command failure
2clap parse error (bad flags / args)

--json example

quay list --json | jq '.[] | {name, version}'

Use this for piping into other tools. Human-table output is not stable; the JSON shape is.

Top-level help

Skill registry CLI

Usage: quay [OPTIONS] <COMMAND>

Commands:
  init              Initialize quay in the current project
  remote            Manage configured hub remotes
  add               Install a skill from a configured remote
  list              List installed skills
  remove            Remove a previously installed skill
  info              Show metadata for a skill (without installing)
  search            Search across configured remotes
  outdated          List installed skills that have newer versions available
  update            Update installed skills to the latest available version
  scan              Discover local skills under `.agents/skills/` and report their sync status
  validate          Validate a local skill's frontmatter (offline, no network)
  push              Push a local skill to a hub via PR (or directly, if --push-mode=direct or the remote's TOML says so)
  profile           Manage user profiles (multi-org identities + remote bundles)
  rebuild-registry  Rebuild a hub's `registry.json` from disk truth and push it back
  link              Apply or verify mirrors from `[install].mirrors` config
  tui               Launch the interactive TUI
  help              Print this message or the help of the given subcommand(s)

quay add

Install a skill from a configured remote.

Usage

quay add [OPTIONS] [SKILL]

SKILL is the skill name as stored in the hub's registry.json (typically the directory name under skills/). Omit it with -i to pick interactively.

Examples

quay add hello                      # install one
quay add hello world fmt-fixer      # install several
quay add -i                         # interactive checkbox picker
quay add hello --remote work        # explicit remote
quay add hello --force              # overwrite local edits

Inside a TTY, omitting SKILL and not passing -i triggers the picker automatically (default-interactive). Pipe < /dev/null to keep the prompt suppressed in scripts.

Flags

FlagEffect
--remote <NAME>Use a specific remote instead of the profile default.
--forceOverwrite the skill even if it already exists locally.
-i, --interactiveOpen the checkbox picker. Mutually exclusive with SKILL.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay update — refresh an already installed skill to the latest hub version. add errors with "already installed" unless --force.
  • quay info — preview metadata without writing files.
  • TUI Remote screen + [a] — same flow with a UI.

Caveats

  • A skill that fails quay validate on the hub side will still install, but you'll see warnings.
  • Mirror dirs (.claude/skills/, .cursor/rules/, …) are populated automatically based on your profile's [install].mirrors.
  • --force deletes any local edits without confirmation. Use quay outdated first to see drift status.

--help

Install a skill from a configured remote

Usage: quay add [OPTIONS] [SKILL]

Arguments:
  [SKILL]  Skill name(s) to install. Omit when using --interactive (-i)

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --remote <REMOTE>
      --force                      Overwrite the skill if it already exists locally
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
  -i, --interactive                Open an interactive checkbox list to pick skills to install. Mutually exclusive with the positional skill argument
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay push

Publish a local skill to a hub.

Usage

quay push [OPTIONS] [SKILL]

quay push clones the configured hub into a temp dir, drops your skill at skills/<name>/SKILL.md, updates the hub's registry.json, commits, and then either opens a PR (default) or pushes to the default branch directly (--push-mode direct or per-remote setting).

Examples

quay push hello                              # default profile, default remote, push_mode from remote config
quay push hello --remote work                # explicit remote
quay push hello --push-mode direct           # bypass remote setting, push straight to main
quay push hello --bump patch                 # 0.1.0 → 0.1.1 before pushing
quay push hello --bump minor
quay push hello --bump major
quay push -i                                 # interactive checkbox picker

After success, the PR URL (or commit SHA, for direct mode) is printed. The push is also logged to ~/.config/quay/push-log.json.

Flags

FlagEffect
--remote <NAME>Target a specific remote.
--bump <KIND>Bump version in frontmatter: patch / minor / major / as-written (default).
--push-mode <pr|direct>Override the remote's push_mode for this invocation.
-i, --interactiveOpen the checkbox picker.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay rebuild-registry — regenerate a corrupted/missing registry.json. Use after manual hub surgery, not as a normal publish step.
  • TUI Local screen + [u] (single) / [U] (bulk selected via [Space]) — same flow with a UI.
  • quay validate first — catches frontmatter mistakes offline before incurring a hub clone.

Caveats

  • --bump requires Frontmatter format. SlashCommand / Freestyle skills get a clean error if you pass --bump against them.
  • Direct mode against a branch-protected default branch will fail at git push origin main. The error hint suggests --push-mode pr or setting push_mode = "pr" in the remote config.
  • The first push to an empty hub seeds registry.json automatically — no manual setup needed.
  • Bitbucket has no CLI client. PR mode falls back to printing a compare URL; you must open the PR in the browser manually.

--help

Push a local skill to a hub via PR (or directly, if --push-mode=direct or the remote's TOML says so)

Usage: quay push [OPTIONS] [SKILL]

Arguments:
  [SKILL]  Skill name to push. Omit when using --interactive (-i)

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --remote <REMOTE>
      --bump <BUMP>                Bump kind: patch | minor | major | as-written. Default: as-written [default: as-written]
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
      --push-mode <PUSH_MODE>      Override the remote's `push_mode` setting for this invocation. Values: pr, direct [possible values: pr, direct]
  -i, --interactive                Open an interactive checkbox list of local skills to push. Mutually exclusive with the positional skill argument
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay remove

Uninstall a previously installed skill.

Usage

quay remove [OPTIONS] [SKILL]

Default: removes only the local copy under .agents/skills/<name>/ and any mirror dirs. The hub is untouched. Pass --everywhere to also delete the skill from every configured remote that publishes it.

Examples

quay remove hello                   # local only
quay remove hello --everywhere      # also drop from every hub
quay remove -i                      # interactive picker

Flags

FlagEffect
--everywhereAlso commit a deletion to every remote publishing this skill (respects per-remote push_mode).
-i, --interactivePick from installed skills.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay update — to refresh, not uninstall.
  • TUI Local screen + [d] (single) / [D] (bulk selected) — same flow with a UI.
  • quay link remove <path> — remove a mirror directory from the project config, not a skill.

Caveats

  • --everywhere deletes from the remote without a confirmation prompt. Combined with push_mode = "direct" it's a destructive one-shot. Use PR mode if you want a review gate.
  • Removing locally does not edit ~/.config/quay/push-log.json — the push history is preserved for audit.
  • If a skill was installed via mirror dir only (rare), remove still cleans up the canonical .agents/skills/<name>/ path.

--help

Remove a previously installed skill

Usage: quay remove [OPTIONS] [SKILL]

Arguments:
  [SKILL]  Skill name to remove. Omit when using --interactive (-i)

Options:
      --everywhere                 Also push a deletion commit to every remote that publishes the skill
      --project <PROJECT>          Project root (defaults to current directory)
  -i, --interactive                Open an interactive checkbox list to pick skills to remove. Mutually exclusive with the positional skill argument
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay update

Update installed skills to the latest hub version.

Usage

quay update [OPTIONS] [SKILL]

Omit SKILL to update every installed skill that has a newer version on the hub. Inside a TTY this auto-opens a checkbox picker of outdated skills; pass --all to bypass the picker, or --dry-run to preview.

Examples

quay update                          # TTY: opens picker of outdated. Non-TTY: updates all.
quay update hello                    # just this one
quay update --all                    # all outdated, no picker
quay update --dry-run                # show what would change
quay update -i                       # explicit picker

Flags

FlagEffect
--dry-runShow what would change without writing.
-i, --interactiveOpen the picker.
--allSkip the TTY auto-picker; update everything outdated.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay outdated — list-only sibling; identical detection logic without writing anything.
  • quay add <skill> --force — overwrites local drift even when versions match.
  • TUI Local screen — outdated skills show with a colour badge; [u] pushes your local, no in-place update key (use CLI).

Caveats

  • "Outdated" uses semver comparison on the frontmatter version field. Skills without frontmatter (SlashCommand / Freestyle) never show as outdated by version — they're compared by SHA-on-fly instead.
  • Local edits are detected and surfaced: an outdated skill with local modifications is reported as installed-modified. update refuses to overwrite it without --force (which lives on quay add, not update — use quay add <name> --force to nuke).
  • --dry-run does not query CLI tools (gh / glab); pure diff against hub clone.

--help

Update installed skills to the latest available version

Usage: quay update [OPTIONS] [SKILL]

Arguments:
  [SKILL]  Update only this skill; if omitted, updates every installed skill

Options:
      --dry-run                    Show what would change without writing to disk
      --project <PROJECT>          Project root (defaults to current directory)
  -i, --interactive                Open an interactive checkbox list of outdated skills to update. Mutually exclusive with the positional skill argument
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --all                        Update every installed skill without opening the picker, even in a terminal. Explicit bypass for the TTY auto-trigger
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay search

Free-text search across configured remotes.

Usage

quay search [OPTIONS] <QUERY>

Matches <QUERY> case-insensitively against skill name and description in every reachable hub's registry.json. Add --tag to narrow by tag.

Examples

quay search lint
quay search "react component" --tag frontend
quay search foo --remote personal
quay search --json deploy | jq '.[].name'

Flags

FlagEffect
--remote <NAME>Search only one remote. Default: all configured.
--tag <TAG>Restrict to skills whose tags include <TAG>. Repeat not supported.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay info — when you already know the name, get full metadata.
  • quay scan — local-side equivalent; lists your skills, not the hubs'.
  • TUI Search ([s]) — same plus richer token grammar (#tag, status:, mirror:, remote:). The CLI keeps things flat; the TUI parses tokens.

Caveats

  • Search hits a cached registry.json per remote. If the hub was just pushed to seconds ago, you may get a stale result — ?_cb cache-busting in the fetcher mitigates this, but five-minute CDN tail can still bite. Retry after a minute.
  • A hub with a malformed registry.json is skipped silently (logged to stderr); the rest of the search continues.
  • Empty results print a clean "no results" line and exit 0.

--help

Search across configured remotes

Usage: quay search [OPTIONS] <QUERY>

Arguments:
  <QUERY>  Free-text query matched against skill name + description (case-insensitive)

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --remote <REMOTE>
      --tag <TAG>
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay outdated

List installed skills that have a newer version available on the hub.

Usage

quay outdated [OPTIONS]

Read-only sibling of quay update. Detects two things:

  1. Version drift — hub's frontmatter version is semver-greater than the installed copy's.
  2. SHA drift on installed-modified — the local file SHA differs from the install-time SHA on the lockfile entry, regardless of version.

Both are reported with a status badge.

Examples

quay outdated
quay outdated --json | jq '.[].name'

Flags

FlagEffect
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay update --dry-run — same detection, but update can also apply the fix. Use outdated when you want a non-interactive read-only report (CI, status dashboards).
  • quay scan — broader local audit; reports all four statuses (local, installed, installed-modified, pushed-local).
  • TUI Dashboard "Outdated" panel — same data, visual.

Caveats

  • "Outdated" by version only works for Frontmatter skills. Other formats are compared SHA-only.
  • A hub with no registry.json produces a warning and counts as "everything's current."

--help

List installed skills that have newer versions available

Usage: quay outdated [OPTIONS]

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay scan

Discover local skills and report their sync status.

Usage

quay scan [OPTIONS]

Walks .agents/skills/ one level deep, classifies every directory it finds, and prints a table. Cross-references the project lockfile and ~/.config/quay/push-log.json to compute per-skill status:

StatusMeaning
localAuthored here; never pushed.
installedCame from a hub via quay add.
installed-modifiedCame from a hub, but local file has been edited since install.
pushed-localAuthored here, then pushed (so it exists on a hub too).

Examples

quay scan
quay scan --json | jq '.[] | select(.status == "installed-modified")'
quay scan --root ./vendor/skills        # non-default canonical root

Flags

FlagEffect
--root <PATH>Override the canonical skills root (default: <project>/.agents/skills).
--jsonJSON output (also accepted as --json global).
--profile, --user-config, --projectStandard globals.

When to use this vs …

  • quay outdated — only reports drift against the hub. scan reports authorship + drift in one pass.
  • quay list — pre-scan command; shows installed skills only, no local-authored entries.
  • TUI Dashboard "Local skills" panel — same data, visual.

Caveats

  • A skill with no recognisable format still appears (status local, format Freestyle). scan never errors on weird files; it just classifies.
  • --root affects discovery but does not rewrite the project config; if you regularly use a non-default root, set it in .quay/config.toml instead.

--help

Discover local skills under `.agents/skills/` and report their sync status

Usage: quay scan [OPTIONS]

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --root <ROOT>                Override the install canonical root (default: `<project>/.agents/skills`)
      --json                       Emit JSON instead of a human table
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
  -h, --help                       Print help

quay validate

Validate a local skill's frontmatter offline.

Usage

quay validate [OPTIONS] <SKILL>

Reads .agents/skills/<SKILL>/SKILL.md and checks:

  • Frontmatter parses as YAML.
  • Required fields (name, description) present.
  • name matches the directory.
  • version is semver-valid (if present).
  • tags is a string array (if present).

No network calls.

Examples

quay validate hello
quay validate hello --strict
quay validate hello --json

Flags

FlagEffect
--strictTreat missing/required-field issues as errors (exit 1). Default: warns to stderr, exits 0.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • Run before quay push — catches mistakes without paying the hub-clone cost.
  • quay scan — gives status per skill but does not deep-validate frontmatter.
  • TUI Create/Push — runs validate inline before staging the push.

Caveats

  • Default mode is soft: even a missing frontmatter block exits 0 with a warning. --strict is what you want in CI.
  • SlashCommand and Freestyle skills produce a warning (no frontmatter) by design; --strict upgrades that to an error.
  • Validation is purely structural. It does not check whether the content of the skill makes sense for any specific agent runtime.

--help

Validate a local skill's frontmatter (offline, no network)

Usage: quay validate [OPTIONS] <SKILL>

Arguments:
  <SKILL>

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --strict                     Treat missing frontmatter or required fields as errors (exit 1). Default: prints warnings to stderr, exits 0 (lenient/soft mode)
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay info

Show metadata for a skill on the hub, without installing.

Usage

quay info [OPTIONS] <SKILL>

Fetches the hub's registry.json, locates the entry for <SKILL>, prints name, description, version, tags, source format, and the canonical path.

Examples

quay info hello
quay info hello --remote work
quay info hello --json | jq '.description'

Flags

FlagEffect
--remote <NAME>Use a specific remote. Default: profile default.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay search — discovery; use info once you have a name.
  • quay add — when you actually want it installed.
  • TUI Remote screen — info-equivalent preview pane next to the skill list.

Caveats

  • Returns an error if <SKILL> is not in the registry. Possible causes: typo, hub's registry.json is stale (run quay rebuild-registry), or the skill was added without updating the registry (every modern quay push updates it; older flows didn't).
  • Does not download the skill body — just the registry entry. To read the full SKILL.md, install it with --force to a throwaway dir, or browse the hub on GitHub.

--help

Show metadata for a skill (without installing)

Usage: quay info [OPTIONS] <SKILL>

Arguments:
  <SKILL>

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --remote <REMOTE>
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay init

Initialise quay in the current project.

Usage

quay init [OPTIONS]

Creates a .quay/ directory with an empty config.toml. The project config is layered on top of ~/.config/quay/config.toml — anything you set here overrides the user-level value for this project only.

Examples

quay init                           # current dir
quay init --project ~/code/foo      # explicit

Confirm:

ls .quay/
# config.toml

Flags

FlagEffect
--project <PATH>Project root (default: cwd).
--user-config <PATH>Override user config path.
--profile <NAME>Override active profile for this invocation.
--jsonJSON output.

When to use this vs …

  • Use quay init once per repo if you want a per-project override (different mirror dirs, custom remote pinned to that project).
  • If your user-level config already covers everything, init is optional — add / push work fine without it.

Caveats

  • Re-running init on a project that already has .quay/config.toml leaves the existing file untouched. There is no --force.
  • Commit .quay/config.toml so teammates inherit the project config. .quay/push-log.json is gitignored (local-only intent log).

--help

Initialize quay in the current project

Usage: quay init [OPTIONS]

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

quay profile

Manage user profiles — bundles of identity (commit email) + remotes + install settings.

Usage

quay profile <SUBCOMMAND>

Subcommands:

SubcommandWhat
listShow all profiles. Active one is marked.
currentPrint the active profile name.
addCreate a new profile (three modes — see below).
useSwitch the active profile. -i for interactive picker.
removeDelete a profile (cannot remove the last one).
showPrint full profile contents (TOML-shaped).
renameRename a profile.

The three add modes

  1. Wizardquay profile add -i. Walks you through name, email, hub URL, push_mode. Recommended for first-time setup.
  2. Explicit flagsquay profile add work --email me@corp --remote main=git@github.com:corp/skills.git --provider github --push-mode pr --default --activate. Repeatable --remote to seed several; --provider / --push-mode / --default apply to the most recent --remote.
  3. From TOMLquay profile add ci --from-toml /etc/quay/ci.toml (or - for stdin). Lets you commit profile fragments alongside CI configs.

Examples

quay profile add -i                            # wizard
quay profile add work --email me@corp \
  --remote main=git@github.com:corp/skills.git \
  --provider github --push-mode pr --default --activate
quay profile add ci --from-toml ./ci-profile.toml
quay profile use -i                            # picker
quay profile use personal
quay profile show work
quay profile rename work corp
quay profile remove old-profile

Flags

Common globals apply (--project, --user-config, --profile, --json). The add subcommand carries the most flags — see quay profile add --help.

When to use this vs …

  • quay remote add — adds a remote to the currently active profile. profile add creates the profile + can seed remotes in one go.
  • QUAY_PROFILE env var — one-shot override at invocation time. profile use makes the switch persistent.
  • TUI Settings → Profiles (, then Profiles tab) — same flow with a UI.

Caveats

  • The "last profile" cannot be removed. quay always has at least one profile.
  • --activate only matters during add. Use quay profile use <name> afterwards to switch.
  • A profile without any remotes is valid but unhelpful — most commands will error with "no remotes configured." Add one with quay remote add.

--help (top level)

Manage user profiles (multi-org identities + remote bundles)

Usage: quay profile [OPTIONS] <COMMAND>

Commands:
  list     List all profiles, marking the active one
  current  Print the active profile name
  add      Add a new profile
  use      Set the active profile
  remove   Remove a profile (cannot remove the last one)
  show     Print full profile contents
  rename   Rename a profile
  help     Print this message or the help of the given subcommand(s)

quay remote

Manage configured hub remotes inside the active profile.

Usage

quay remote <SUBCOMMAND>

Subcommands:

SubcommandWhat
addRegister a new remote (<NAME> <URL>).
listShow every remote with provider + push_mode + default marker.
testRun a connectivity probe (git archive or shallow clone).
removeDelete a remote from the active profile.

Examples

quay remote add main git@github.com:corp/skills.git --provider github --default
quay remote add personal git@gitlab.com:me/skills.git --provider gitlab --push-mode pr
quay remote list
quay remote test main
quay remote remove personal

add flags

FlagEffect
--defaultMark as the profile's default remote.
--provider <KIND>Force provider: github / githubenterprise / gitlab / bitbucket / azuredevops. Auto-detected from URL if omitted.
--push-mode <pr|direct>Default push mode for this remote (default: pr).
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay profile add … --remote — seeds remotes during profile creation. Use remote add afterwards.
  • TUI Settings → Remotes — same flow with a UI, including a provider picker dropdown.
  • quay rebuild-registry <name> — recovery flow when a hub's registry.json is broken.

remote test

Two-step probe:

  1. git archive --remote=<URL> HEAD -- registry.json (cheap; no clone).
  2. If archive fails, shallow-clone (--depth 1) into a temp dir and look for registry.json.

Exits 0 on success, non-zero on either failure with a diagnostic message identifying which step failed. Useful in CI before quay add to fail fast on bad URLs / missing creds.

Caveats

  • A gitlab URL that points at a GitLab Enterprise instance still works; the provider only affects PR creation, not git clone.
  • Removing the default remote leaves the profile with no default. The next push must use --remote.
  • test will not catch every authentication issue (e.g. SSH known_hosts prompts) — if it succeeds but push fails, suspect agent forwarding / known_hosts.

--help (top level)

Manage configured hub remotes

Usage: quay remote [OPTIONS] <COMMAND>

Commands:
  add     Add a new remote
  test    Test connectivity to a configured remote
  list    List configured remotes
  remove  Remove a remote
  help    Print this message or the help of the given subcommand(s)

quay link

Manage mirror dirs declared under [install].mirrors in the active profile.

Usage

quay link [OPTIONS] [SUBCOMMAND]

Subcommands:

SubcommandWhat
checkVerify mirrors are intact; exit non-zero if drifted.
add <PATH>Add a mirror to the project config and populate it for every installed skill.
remove <PATH>Remove a mirror from the project config (does not delete files).

With no subcommand, quay link applies the configured mirrors for the project (idempotent).

Examples

quay link                              # apply mirrors
quay link check                        # CI: fail if mirrors drifted
quay link add .cursor/rules            # add a Cursor mirror
quay link add .claude/skills --strategy auto
quay link remove .cursor/rules         # forget the mirror (files stay)

Flags

FlagEffect
--strategy <NAME> (on add)Mirror strategy. Default auto (let quay pick per skill format).
--forceOverwrite existing entries even if they conflict with quay's layout.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • quay add — already applies your current mirrors. link is for changing the mirror set or auditing it.
  • quay scan — does not check mirror drift; it checks skill drift. Pair scan + link check for a full audit.
  • TUI Settings → Install (, then Install tab) — UI for managing the mirror list.

Caveats

  • link remove deletes the config entry, not the directory on disk. To also clean files, rm -rf afterwards.
  • link check is the canonical CI gate. Exit code 0 = clean; non-zero = at least one mirror is missing or out-of-sync.
  • --force will overwrite hand-edited mirror dirs without backup. Use carefully.

--help

Apply or verify mirrors from `[install].mirrors` config

Usage: quay link [OPTIONS] [COMMAND]

Commands:
  check   Verify mirrors are intact; exit non-zero if drifted
  add     Add a new mirror to the project config and apply it for every installed skill
  remove  Remove a mirror from the project config (does not delete the mirror dir)
  help    Print this message or the help of the given subcommand(s)

quay rebuild-registry

Regenerate a hub's registry.json from disk truth.

Usage

quay rebuild-registry [OPTIONS] [REMOTE]

Clones the remote, walks skills/<name>/SKILL.md, builds a fresh { skills: { <name>: { … } } } map, commits it, and pushes per the remote's push_mode. [REMOTE] defaults to the profile's default remote when omitted.

Examples

quay rebuild-registry                       # default remote
quay rebuild-registry work
quay rebuild-registry work --push-mode pr   # force PR even if remote says direct

Flags

FlagEffect
--push-mode <pr|direct>Override the remote's push_mode.
--profile, --user-config, --project, --jsonStandard globals.

When to use this vs …

  • Recoveryquay search / quay add return "skill not found" but the file exists on the hub. The registry has drifted; run rebuild-registry.
  • Migration — you imported skills into the hub manually (not via quay push). Rebuild fixes the registry in one shot.
  • Bad seed — a hub started with a malformed registry.json (e.g. { skills: [] } array instead of map). Rebuild regenerates the correct shape.
  • quay push — already updates the registry on every push. Reach for rebuild-registry only when the registry is wrong.

Caveats

  • Rewrites registry.json from scratch. Any hand-edits there are lost.
  • The commit message is a stock "rebuild registry" message; if you want a custom one, edit before the PR is merged.
  • Works against hubs with no registry.json at all (creates one).

--help

Rebuild a hub's `registry.json` from disk truth and push it back.

Clones the remote, walks `skills/<name>/SKILL.md`, regenerates `registry.json` containing every discovered skill, then commits and pushes (PR or direct per the remote's `push_mode`).

Usage: quay rebuild-registry [OPTIONS] [REMOTE]

Arguments:
  [REMOTE]
          Remote name. Uses the default remote when omitted

Options:
      --project <PROJECT>
          Project root (defaults to current directory)

      --push-mode <PUSH_MODE>
          Override the remote's `push_mode` for this invocation
          [possible values: pr, direct]

      --user-config <USER_CONFIG>
          Override user config path (defaults to ~/.config/quay/config.toml)

      --profile <PROFILE>
          Override the active profile for this invocation

      --json
          Output JSON instead of human-readable text

  -h, --help
          Print help (see a summary with '-h')

quay tui

Launch the interactive terminal UI.

Usage

quay tui [OPTIONS]

Boots the ratatui-based interface. On first run with no profiles, the Onboarding screen runs through profile + remote setup; afterwards every launch starts on Dashboard.

Examples

quay tui                                # default
quay tui --profile work                 # launch under specific profile
quay tui --project ~/code/foo

Flags

FlagEffect
--profile, --user-config, --project, --jsonStandard globals. --json is ignored by the TUI itself; the global is still parseable.

What you can do

KeyAction
[1]Dashboard
[2]Local skills
[3]Remote skills
[s]Search
[,]Settings
[p]Profile switcher modal
[g] [c]Create / push (chord)
[q]Quit

See the TUI overview for per-screen detail.

When to use this vs …

  • CLI subcommands — when scripting / piping output / CI. The TUI is for humans.
  • quay add -i / quay push -i — quick one-shot pickers in CLI. The TUI gives you the same flow plus context (status, history, previews).

Caveats

  • The TUI requires a real TTY. Piping its output (quay tui | tee) is unsupported.
  • Bracketed paste is enabled in setup; if your terminal lacks support, pasting still works but multi-line paste may register as separate keystrokes.
  • xdg-open / open / cmd-start must be on PATH for the "open in browser" affordance to work (e.g. after a PR is created from Create/Push).

--help

Launch the interactive TUI

Usage: quay tui [OPTIONS]

Options:
      --project <PROJECT>          Project root (defaults to current directory)
      --user-config <USER_CONFIG>  Override user config path (defaults to ~/.config/quay/config.toml)
      --profile <PROFILE>          Override the active profile for this invocation
      --json                       Output JSON instead of human-readable text
  -h, --help                       Print help

TUI overview

Dashboard

Local

Remote

Search

Settings

Onboarding

Share a skill with a team

CI install via --from-toml

Multi-org profiles

Direct vs PR push

Force update over local edits

Seed an empty hub

Protected default branches

SSH key setup

config.toml

SKILL.md

registry.json

push-log.json

Environment variables

Exit codes