Skip to main content

farrier

PyPI

farrier renders an agent-neutral prompt library into a repository — generating the skill, prompt and instruction adapters expected by Codex, Claude, and GitHub Copilot, plus the launcher scaffolding (.agents/agents.mk and friends) that keeps those adapters current.

A farrier is the craftsman who fits the right gear onto each horse. This tool fits the shared prompt library onto each repository — and refits it as the library moves, so an architecture, testing or review standard changes in one place and every repository's installed copy follows, instead of each one drifting on a private copy.

Install

pipx install farrier        # or: uv tool install farrier

The farrier package ships no library content of its own. Content resolves across two layers: the base library — plain data, the toolchain skills and the packs that select them, with nothing to install or import — and an optional private overlay that shadows it name-for-name. Point farrier at an overlay once:

farrier config set-library /path/to/the/overlay
farrier config show

config writes one shared TOML file, ~/.config/stablemate/config.toml (~/Library/Application Support/stablemate/ on macOS, %APPDATA%\stablemate\ on Windows; $STABLEMATE_CONFIG overrides it). Every stablemate tool reads and writes that same file, so library_dir and base_dir mean one thing across all of them — a pre-existing ~/.config/farrier/config.toml is still read, and folded in on the first write.

Finding the base library. farrier discovers the base via, in order, $STABLEMATE_BASE_DIR → the base_dir config key (farrier config set-base <path>) → a configured stablemate_dir checkout (<checkout>/base-library) → the shared cache at ~/.cache/stablemate. The cache is deliberately last, so a fetched copy can never shadow a checkout you are editing.

farrier install fetches the base, and updates it. It is the only command that touches the cache, so under pipx — where each tool is its own venv and the base is data with no package to import — you get a working base library without configuring anything. An update asks the remote for the head of main first, so an already-current cache costs one round-trip rather than a re-clone. Three qualifications:

  • A base you named is never fetched over. If $STABLEMATE_BASE_DIR, set-base or a stablemate_dir checkout answers, install returns it without even probing the remote.
  • --check fetches but never updates. It writes nothing and runs in CI, where a library moving underneath the comparison would make the result depend on the hour.
  • Failure keeps what works. Offline, STABLEMATE_FETCH_BASE=0, or a broken clone all leave the existing cache in place rather than leaving you with none.

STABLEMATE_FETCH_BASE=0 forbids the network entirely; STABLEMATE_CACHE_DIR relocates the cache. See the monorepo's install guide for the full resolution order and why everything other than install reads the cache frozen.

Use

In a repository that has no agents.yml yet:

farrier init                # write a starter agents.yml (--force to replace one)

init reads nothing — no library, no config — so it works on a fresh machine before farrier config set-library. It refuses to overwrite an existing agents.yml.

Then, from a repository that has one:

farrier --repo .            # render/install the selected packs
farrier --repo . --check    # verify generated files are up to date (no writes)

Rendering is the default action; farrier install --repo . is an accepted alias of farrier --repo .. A bare farrier with no arguments prints the verb listing.

The rest of the verbs:

farrier config show                        # every config key as key=value
farrier config show --profile cheap        # one [profiles.<name>] table, flattened
farrier config --config ./c.toml show      # …read from that file rather than the home one
farrier source .claude/skills/x/SKILL.md   # the library file that generated an adapter
farrier scaffold --list                    # the scaffolds this repo may apply, and their params
farrier scaffold <id> [--param KEY=VALUE]  # seed repo files from one
farrier workflows                          # the workflows installed on this machine
farrier version

source takes the path of a generated file and prints the library file behind it. It is the one to reach for before editing anything under .claude/, .codex/ or .github/: those are outputs, and an edit there is discarded by the next install.

config show --profile <name> prints one [profiles.<name>] table — the named model set a run selects with workhorse-<name> run --profile <name> — flattened to one dotted line per leaf (power.high.claude.model=haiku). A profile replaces the top-level tables rather than layering over them, so what it prints is the whole config that run resolves from, and two profiles diff against each other line by line. --config PATH goes before the action and names the file every config verb reads and writes, so the question can be asked of a config that is not this machine's home one. There is no setter: a profile is a nested table, and set-library-style flat assignment cannot express one — edit the file.

Configuring agents.yml

agents.yml (at your repo root) selects what farrier renders. farrier init writes a starter one with the common keys as commented examples. Every option — repo, agents, packs, skills/prompts/roots, scaffolds, exclude, localInstructions, template/vars, and workflow — is documented with inline comments in agents.example.yml. Copy it to your repo as agents.yml and prune to taste.

Library layout

The other side of the contract is the agent library farrier renders from — what goes in library/skills/, library/prompts/, packs/ and scaffolds/, the file formats expected, and how source names map to generated adapters. That is documented in docs/LAYOUT.md.

A skill or prompt is markdown with YAML frontmatter, and farrier.frontmatter reads it with a markdown parser and yaml.safe_load — never a fence regex. (It is farrier's own module rather than ostler.markdown because farrier needs frontmatter only and does not depend on ostler; both follow the same rule, which the stablemate-structured-parsing skill states in full.) A CRLF file, a closing --- with a trailing space and a file with no newline after it are all ordinary documents, and the regexes that preceded this read every one of them as having no frontmatter at all.

Farrier does not install workflows. A library ships none, agents.yml has no workflows: key, and nothing is written to .agents/workflows/. A workflow is a Python distribution that brings its own command: install it with pip/uv and run it directly.

uv tool install workhorse-workflows
workhorse-research run --dry-run # static preflight, drives nothing
workhorse-coder run

Locating the library

--library DIR, $FARRIER_LIBRARY_DIR and library_dir in the home config (farrier config set-library) select the overlay, in that precedence. The base library is found separately, by the order under Install above, and the two stack: the overlay first, then the base.

A directory counts as a library if it holds library/ — that is the whole contract. Point farrier at one that does not and it exits with a setup hint; configure no overlay at all and it runs base-only, which is a supported setup rather than an error. Only with neither an overlay nor a base does it refuse to start.

Related

  • workhorse-agent — the fail-soft runner that executes the workflows, against the adapters farrier renders.
  • ostler — the documentation-graph toolkit workflows call through its in-process Python API.

All three live in the stablemate workspace.

Metadata

Release files for farrier 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for farrier 3.0.0
File Size Uploaded
farrier-3.0.0.tar.gz 125.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for farrier 3.0.0
File Interpreter ABI Platform
farrier-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 260.8 kB

Release files / farrier-3.0.0.tar.gz

Download URL farrier-3.0.0.tar.gz
Size 125.8 kB
Tags Source
SHA-256 checksum
How to use checksums
9ed674fc60bfb624e64f11c6f1173b905e04f9705708e5b2ba7fda1547523e39
BLAKE2b-256 checksum
How to use checksums
b97df55c154d367a9197c7642bf09f7e2ad7852baea2fc215a1ebaf307682351
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / farrier-3.0.0-py3-none-any.whl

Download URL farrier-3.0.0-py3-none-any.whl
Size 135.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2325e94fe7846b4b1c76c378d97aa7e3fce2468a256e34f9f137df36dd03ff6f
BLAKE2b-256 checksum
How to use checksums
167a963830be9cb82401bbd1a4b81e20ff18518f99dc1cca72b74b6650ecf6fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page