steer

Quickstart

Build, validate, and install a skill in five minutes.

Install steer

uv tool install steer-ai        # installs the `steer` command
# or: pip install steer-ai
# latest from main: uv tool install git+https://github.com/bh-rat/steer
steer --version

Python ≥ 3.11, zero dependencies.

1. Scaffold

steer new pr-review \
  --description "Reviews a pull request and posts findings. Use when the user asks for a PR review, code review, or pre-merge check." \
  --with secrets,context,flow --secrets GITHUB_TOKEN --scripts
Created skill at pr-review
  + SKILL.md
  + flow.toml
  + scripts/steer.py
  + scripts/example.py

Validation: clean

Components are opt-in: --with secrets,store,context,flow,proc wires the matching sections into the generated SKILL.md. Choosing any component also writes scripts/steer.py, the skill's bundled runtime: a self-contained, stdlib-only copy of exactly those components, which is what the generated SKILL.md invokes (python3 scripts/steer.py ...). --scripts adds an example script that follows the agentic-interface rules (non-interactive, JSON envelope on stdout, diagnostics on stderr).

2. Write the skill

Open SKILL.md and replace the TODOs. The description is the most important line in the file; it's all the agent sees before deciding to use the skill. Say what it does and when to use it, with the words users actually say.

Then define the real process in flow.toml:

name = "pr-review"

[[steps]]
id = "fetch"
description = "Pull the PR diff"
directive = "Run scripts/fetch.py --pr <number>; it writes out/diff.json"
command = "python3 scripts/fetch.py"

[steps.verify]
file_exists = "out/diff.json"

[[steps]]
id = "review"
description = "Confirm the findings are real"
directive = "Read out/diff.json; draft findings and confirm each one is real before posting"
requires = ["fetch"]

[[steps]]
id = "post"
description = "Post the review"
directive = "Run scripts/post.py; it posts the review and writes out/review.json"
requires = ["review"]

[steps.verify]
file_exists = "out/review.json"

Steps with [steps.verify] complete only when reality matches (file_exists, dir_exists, glob, command, env). The review step has no verify: it's a mandate step the agent marks done with steer flow done review, and marking is refused while prerequisites are incomplete.

3. Try the runtime

cd pr-review

steer context                       # what the agent sees first
steer secrets check GITHUB_TOKEN    # exit 1 + exact remediation command
steer secrets set GITHUB_TOKEN      # hidden prompt; lands in the OS keychain

steer flow status --workspace ~/work/acme   # progress + current directive

These are the author's spelling; the generated SKILL.md spells the same commands python3 scripts/steer.py ..., which works on machines where steer was never installed.

  PR-REVIEW WORKFLOW
  ─────────────────────────────────────────
  Progress: 0/3 steps  ● fetch  ○ review  ○ post

  ▸ Next: fetch
    Run scripts/fetch.py --pr <number>; it writes out/diff.json

    Run: python3 scripts/fetch.py

4. Validate and ship

steer validate            # spec rules + broken refs + budgets + hygiene
steer install . --user    # → ~/.claude/skills/pr-review
steer package             # → pr-review.zip for the Claude API / claude.ai

steer validate fails the build on spec violations (bad name, missing or oversized description, broken file references) and refuses packaging when credential-looking files are inside the skill directory. It also checks the bundled runtime: a stale bundle is refreshed by steer package, an edited one is refused.

5. Use it

In Claude Code, the skill is now invocable as /pr-review and triggers automatically when a request matches its description. Other clients pick it up from .claude/skills / .agents/skills per their discovery rules (steer install --dest targets any root).

Whoever the skill reaches runs it with plain python3: the runtime rides along in scripts/steer.py, so nobody who receives your skill has to install steer.

On this page