qory

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

README

🐝 qory

qory composes the harness a runtime like Claude Code or Codex loads, from the layers a repository names: a core your team shares, one for the framework, a specialised one for marketing or automation, and whatever this repository alone needs. The repository commits that list, not copies of the skills, agents, commands and settings the layers hold.

The problem

You have instructions, skills, agents, commands and settings that your coding agent reads from the repository, and you have more than one repository and more than one agent. Claude Code reads .claude, Codex reads .codex and AGENTS.override.md, Gemini CLI reads .gemini and GEMINI.md, OpenCode reads .opencode and opencode.json. So every repository holds a copy per tool, and when the shared set improves, the copies drift. A skill fixed in one place is stale in the next, and nothing tells you which version a checkout runs with.

What qory does

qory reads a compose file, the profile, that names the layers in order: the shared core, the framework, the specialised one, the repository's own. It composes them into one tree and renders that tree the way the target tool reads it. The tree is linked into the checkout and left out of git, so what the repository carries is the profile and its own layer, and a report names the layer every entry came from.

One layer, written once, serves Claude Code, Codex CLI, Gemini CLI, OpenCode, Cursor, GitHub Copilot CLI, Amp, Goose, and every tool that reads AGENTS.md and .agents/skills. qory harness compose --runtime codex renders the same profile for another one.

A checkout can hold two of them at once: runtime: [claude, codex], or qory hc --runtime claude,codex, and both agents read the same harness in the same directory. Stop working in one, continue in the other, and nothing has to be composed again.

The model is Docker's: a layer is an image, the compose file is the Compose file, and the composed tree is what runs. One rule differs on purpose. When two layers provide the same entry, qory refuses to compose until the profile says which one to keep. There is no last-wins.

Three steps

  1. Write harness-compose.yaml in the repository, or in a directory above several repositories:

    apiVersion: qory.ai/v1alpha1
    kind: HarnessProfile
    target:
      runtime: claude          # or both at once: [claude, codex]
      model: opus
    layers:
      - name: core             # what every repository of yours gets
        source: {path: ../harness/core}
      - name: nextjs           # the framework
        source: {path: ../harness/nextjs}
      - name: marketing        # a specialised layer, on the repositories that want it
        source: {path: ../harness/marketing}
      - name: app              # this repository's own, committed with it
        source: {path: ./harness}
    
  2. Compose it:

    qory harness compose
    
  3. Start your agent in the checkout. It reads the composed tree through the files it already looks for.

Install

With Homebrew, on macOS:

brew install qoryai/tap/qory

With the install script, on macOS and Linux. It downloads the release binary for the machine, verifies its checksum, and puts it in ~/.local/bin:

curl -fsSL https://raw.githubusercontent.com/qoryai/qory/main/install.sh | sh

Set QORY_BIN_DIR to install somewhere else, and QORY_VERSION to install a version other than the latest. Any version manager that reads GitHub releases works as well, for example mise use -g ubi:qoryai/qory.

From source, with Go 1.27 or later:

go install github.com/qoryai/qory@latest

The binary lands in $(go env GOPATH)/bin; put that directory on your PATH.

Try it

mkdir hello && cd hello && git init
qory harness init      # writes a profile and two layers
qory hc                # or: qory hc --runtime codex
claude                 # type /hello; or codex, gemini, opencode
qory hr

Two layers, both convinced they invented greeting. The README that init writes says what to delete to watch qory refuse the collision. The same files are in examples/hello.

Commands

qory harness init        # write the hello example into the current directory
qory harness compose     # compose the profile into the checkout you stand in   (qory hc)
qory harness inspect     # print the report: every entry and the layer it came from (qory hi)
qory harness remove      # remove the composed tree and the link                 (qory hr)
qory version

qory harness compose --dry-run prints the report and writes nothing. -f <file> reads a profile instead of discovering one. --runtime and --model override the profile's target for one compose, and --runtime takes a list: --runtime claude,codex. -v prints one line per entry.

The reference, one page per command, is under docs/commands.

What you get

  • The files your tool reads, linked to a composed tree under .qory in the checkout, all of it excluded from git through the clone-local exclude file. The tree is built once; each tool gets its own directory in it.
  • Settings merged from every layer per target file, in the tool's own format: permission lists concatenated and deduplicated, hooks concatenated, hook commands rewritten to the composed tree's path.
  • One instruction file, concatenated from the layers in order, presented as CLAUDE.md, AGENTS.override.md or GEMINI.md where a tool wants another name.
  • Agents and commands written in each tool's format from one source file, and a line in the compose output for every kind a tool has no place for.
  • A report, printed by qory harness inspect, that names the layer of every entry and every exclude the profile made.
  • A refusal, with the lines that resolve it, when two layers provide the same entry.

The format

The compose file, the optional layer manifest harness.yaml, the composition rules and the runtimes are specified in contracts/harness/v1, with JSON schemas and the fixtures the test suite runs.

Contributing

See CONTRIBUTING.md. Contributions are made under the agreement in CLA.md.

Licence

Apache License 2.0. See LICENSE. Qory™ is a trademark of 8wonders GmbH; TRADEMARKS.md says what you may do with the name.

Documentation

Overview

Command qory composes the harness a coding agent runs with from layers.

Directories

Path Synopsis
Package cmd is the command tree of the qory binary: one command per noun, one subcommand per verb.
Package cmd is the command tree of the qory binary: one command per noun, one subcommand per verb.
internal
checkout
Package checkout locates the git checkout a command works on and names it.
Package checkout locates the git checkout a command works on and names it.
compose
Package compose turns a profile into one flat tree: every entry once, from one layer.
Package compose turns a profile into one flat tree: every entry once, from one layer.
gendocs command
Command gendocs writes the command reference, one Markdown page per command, into the directory given as its argument.
Command gendocs writes the command reference, one Markdown page per command, into the directory given as its argument.
layer
Package layer reads one directory of harness material: its optional manifest, the entries it ships per kind, its settings fragments and its instruction file.
Package layer reads one directory of harness material: its optional manifest, the entries it ships per kind, its settings fragments and its instruction file.
profile
Package profile reads harness-compose.yaml and finds the one that covers a checkout.
Package profile reads harness-compose.yaml and finds the one that covers a checkout.
render
Package render writes a composed harness into a checkout the way one runtime reads it.
Package render writes a composed harness into a checkout the way one runtime reads it.
render/amp
Package amp renders for Amp, which reads a project's .amp directory for its settings, AGENTS.md at the checkout root, and skills from .agents/skills.
Package amp renders for Amp, which reads a project's .amp directory for its settings, AGENTS.md at the checkout root, and skills from .agents/skills.
render/any
Package any renders for a program that follows the AGENTS.md convention and has no package of its own, reading the instructions from AGENTS.md at the checkout root and skills from .agents/skills.
Package any renders for a program that follows the AGENTS.md convention and has no package of its own, reading the instructions from AGENTS.md at the checkout root and skills from .agents/skills.
render/claude
Package claude renders for Claude Code, which reads a project's .claude directory: the skills, agents, commands, output styles and hooks under it, its settings.json, and CLAUDE.md beside them.
Package claude renders for Claude Code, which reads a project's .claude directory: the skills, agents, commands, output styles and hooks under it, its settings.json, and CLAUDE.md beside them.
render/codex
Package codex renders for Codex CLI, which reads a project's .codex directory, skills from .agents/skills, and AGENTS.override.md ahead of AGENTS.md.
Package codex renders for Codex CLI, which reads a project's .codex directory, skills from .agents/skills, and AGENTS.override.md ahead of AGENTS.md.
render/copilot
Package copilot renders for GitHub Copilot CLI, which reads agents from .github/agents, hook files from .github/hooks, AGENTS.md at the checkout root, and skills from .agents/skills.
Package copilot renders for GitHub Copilot CLI, which reads agents from .github/agents, hook files from .github/hooks, AGENTS.md at the checkout root, and skills from .agents/skills.
render/cursor
Package cursor renders for Cursor and the Cursor CLI, which read a project's .cursor directory for agents, hooks and settings files such as hooks.json, cli.json and mcp.json, AGENTS.md at the checkout root, and skills from .agents/skills.
Package cursor renders for Cursor and the Cursor CLI, which read a project's .cursor directory for agents, hooks and settings files such as hooks.json, cli.json and mcp.json, AGENTS.md at the checkout root, and skills from .agents/skills.
render/gemini
Package gemini renders for Gemini CLI, which reads a project's .gemini directory, holding its settings.json and the skills, agents, commands and hooks under it, and GEMINI.md at the checkout root.
Package gemini renders for Gemini CLI, which reads a project's .gemini directory, holding its settings.json and the skills, agents, commands and hooks under it, and GEMINI.md at the checkout root.
render/goose
Package goose renders for Goose, which reads AGENTS.md at the checkout root, skills from .agents/skills and agents from .agents/agents.
Package goose renders for Goose, which reads AGENTS.md at the checkout root, skills from .agents/skills and agents from .agents/agents.
render/opencode
Package opencode renders for OpenCode, which reads a project's .opencode directory for agents, commands and hooks, opencode.json for its config, AGENTS.md at the checkout root, and skills from .agents/skills.
Package opencode renders for OpenCode, which reads a project's .opencode directory for agents, commands and hooks, opencode.json for its config, AGENTS.md at the checkout root, and skills from .agents/skills.
report
Package report is the JSON record of one compose: every layer with its pin, every entry with its layer.
Package report is the JSON record of one compose: every layer with its pin, every entry with its layer.
source
Package source resolves a layer's source to a directory on disk and a pin.
Package source resolves a layer's source to a directory on disk and a pin.
ui
Package ui prints everything a person reads on the terminal, in one vocabulary.
Package ui prints everything a person reads on the terminal, in one vocabulary.
user
Package user reads the name to greet a person with from the local configuration.
Package user reads the name to greet a person with from the local configuration.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL