Skip to main content

🛠️ skeel

Declarative agent skill management.

skeel reads a desired-state manifest and applies it through gh skill.

✨ Features

  • Desired state: declare skill sources in one YAML file
  • Inventory, dry run, and diff: list selected skill inventory, preview commands, and compare managed skills against what's installed locally
  • Add, apply, and update: edit desired state, reconcile installed skills with live progress, and update declared installed skills
  • Target flags: choose local or global scope from the CLI
  • JSON output: pass --json for one machine-readable object on stdout

🚀 Quickstart

Run skeel directly with uvx:

uvx skeel

⚙️ Manifest

Default path: .agents/skills.yaml in project scope, ~/.agents/skills.yaml in user scope.

sources:
  anthropics/skills:
    - skill-creator
  mavam/quarto-brief:
  openclaw/gogcli:
    - gog
  tenzir/skills:
    pin: main
    skills:
      - tenzir-ecs

An empty value installs all skills from a source. A list is the common form for selected skills. Use a nested mapping only for source options, such as pin or custom install commands. During update, selected skills refresh independently, while an install-all source refreshes once and discovers newly added upstream skills.

By default, skeel uses project scope: .agents/skills.yaml and .agents/skills in the current working directory. Use -g or --scope user for global installs into ~/.agents/skills:

uvx skeel -g apply

Use --manifest (-m) for a non-default desired-state manifest:

uvx skeel --manifest ./skills.yaml apply --dry-run

Scope selects the base directory for the implicit manifest and managed skill directory: project scope uses the current working directory and user scope uses $HOME. Use -a or --all with commands that can operate on both scopes. If the implicit manifest does not exist, apply, diff, list, and update are no-ops; add creates the manifest. Use --manifest or SKEEL_MANIFEST to use a manifest from another path. Because an explicit manifest path is not scoped, -a and --all are rejected when --manifest or SKEEL_MANIFEST is set.

✨ Commands

By default, every command operates on project scope. Use -g, --user, --global, or --scope user to operate on user scope. Use -a or --all to operate on both project and user scopes for diff, list, apply, remove, and update when using the implicit manifests.

Human output is consistent across commands: the first column is the action marker, the second column is a muted scope glyph ( for project, for user), followed by the skill name, the source, and a muted suffix for versions, paths, or diagnostic details.

For scripts, pass --json to add, apply, diff, list, path, remove, or update to emit one machine-readable object on stdout.

list

Show installed skills together with manifest status. Missing manifest skills are marked with ; installed skills that are not declared in the manifest still appear in the inventory and include "managed": false in JSON output. Rows are tagged with their scope glyph. Sources declared without a skill list expand to the installed skills from that source instead of showing *.

uvx skeel list -a
✔︎ ★ tenzir-docs tenzir/skills main@a5d04ab
✘ ★ gog openclaw/gogcli
✔︎ ⌂ skill-creator anthropics/skills main@3cf9a8d
✔︎ ⌂ wrangler cloudflare/skills main@45cc198
✔︎ ⌂ clacks
✔︎ ⌂ quarto-brief mavam/quarto-brief main@e89c555

diff

Compare desired state with installed skills. + rows would be installed by apply; - rows would be removed.

uvx skeel diff
+ ★ wrangler cloudflare/skills
+ ★ vectorize cloudflare/skills
- ★ obsolete-skill installed
- ★ old-experiment installed

apply

Reconcile installed skills with the manifest. Missing skills are installed and extra skills are removed. Use --reinstall to run every manifest installer without diffing first, or apply <source> [skill] to target one source. A selector that does not match the manifest exits with an error.

uvx skeel apply --dry-run
↳ gh skill install cloudflare/skills wrangler --allow-hidden-dirs --dir .agents/skills --force
↳ gh skill install cloudflare/skills vectorize --allow-hidden-dirs --dir .agents/skills --force
↳ rm -rf .agents/skills/obsolete-skill
uvx skeel apply
+ ★ wrangler cloudflare/skills
+ ★ vectorize cloudflare/skills
- ★ obsolete-skill

update

Update installed skills that are represented by the manifest. Explicit skill entries update independently, and remote update checks run in parallel. An install-all entry refreshes once at source level, including when it uses a branch pin such as main. This refresh also installs skills added to the upstream source since the previous update.

Pass a source, or a source and skill, to update only that manifest selection. A source-and-skill selector stays targeted to that skill, even when the manifest entry normally installs all skills. A selector that does not match the manifest exits with an error.

uvx skeel update
uvx skeel update tenzir/skills
uvx skeel update tenzir/skills tenzir-docs
uvx skeel update -a
✔︎ ★ teach mattpocock/skills main@975430f
✔︎ ★ tenzir-docs tenzir/skills main@f3842c1
✔︎ ★ clacks downstairs-dawgs/clacks
✘ ★ broken-skill broken/source

Pinned GitHub entries are updated by resolving the configured pin and refreshing installed files when the source changes. Branch pins are checked for new content. Immutable tag and commit pins report current when their recorded tree is unchanged, without downloading the same archive again. Skills installed by gh skill include provenance in SKILL.md frontmatter, so future updates can track them directly.

Updates for pinned install-all sources also prune skills removed upstream. Skeel deletes a directory only when its github-repo matches the source exactly and its github-path is absent from the source's current inventory. Metadata-less, malformed, and differently owned directories stay untouched. The source-level result names removed skills, and JSON output includes their paths.

A dry run resolves a pinned source and previews each removal without changing local files. Unpinned install-all sources still add and refresh skills without pruning because gh skill install --all doesn't expose the remote inventory. Use apply --reinstall when you need to force-refresh an install-all entry without pruning it.

add

Upsert a source or source/skill entry into the manifest. Omit the skill to select all skills from the source. Pass --apply to reconcile immediately.

uvx skeel add tenzir/skills tenzir-docs@main
✔︎ ★ tenzir-docs tenzir/skills .agents/skills.yaml
uvx skeel add mavam/quarto-brief --dry-run
↳ mavam/quarto-brief .agents/skills.yaml

remove

Remove an unambiguous skill name from the selected manifest. Pass --apply to reconcile immediately. A selector that does not match the manifest exits with an error.

add and remove are intentionally asymmetric: adding starts from a source because skeel needs to know where to install from, while removing starts from a skill because that is the common user intent. Use --source only to disambiguate or remove a whole source.

uvx skeel remove tenzir-docs
✔︎ ★ tenzir-docs tenzir/skills .agents/skills.yaml

When multiple sources declare the same skill name, disambiguate with --source:

uvx skeel remove tenzir-docs --source tenzir/skills

Omit the skill to remove the whole source selected by --source:

uvx skeel remove --source mavam/quarto-brief --dry-run
↳ mavam/quarto-brief .agents/skills.yaml

path

Print the manifest path that skeel would use for the selected scope.

uvx skeel path
.agents/skills.yaml

Use -a to print both implicit paths:

uvx skeel path -a
project .agents/skills.yaml
user    /Users/alice/.agents/skills.yaml

🧰 GitHub Skill Policy

When applying, skeel delegates placement to gh skill with:

gh skill install <repo> <skill> --dir .agents/skills --force

The target directory is derived from scope: project scope uses the current working directory and user scope uses $HOME. A bare GitHub source installs all skills from that repository:

sources:
  mavam/quarto-brief:

which runs:

gh skill install mavam/quarto-brief --all --dir .agents/skills --force

For installers that are not backed by gh skill, provide source-level install commands under the source key. Skeel runs those commands as the complete install command set:

sources:
  slack-clacks/clacks:
    skills:
      - clacks
    install:
      - uvx --from slack-clacks clacks skill --mode universal --force

To add a GitHub source from the CLI, use the same positional shape as gh skill install:

uvx skeel add tenzir/skills tenzir-docs@main
uvx skeel remove tenzir/skills tenzir-docs
uvx skeel add mavam/quarto-brief --apply

📄 License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

skeel-1.1.0.tar.gz (54.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

skeel-1.1.0-py3-none-any.whl (38.8 kB view details)

Uploaded Python 3

File details

Details for the file skeel-1.1.0.tar.gz.

File metadata

  • Download URL: skeel-1.1.0.tar.gz
  • Upload date:
  • Size: 54.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for skeel-1.1.0.tar.gz
Algorithm Hash digest
SHA256 01f1105b68ad2eeada0be044bc58b64bbf962248a0a2c5d727caf9b926dca9c3
MD5 68a3ac9fd8e903f5186a4b4f2977b829
BLAKE2b-256 51c71f6eeeb58388a1f7f2812be011b82a6619050717de2ef4517c7f3ecb34c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for skeel-1.1.0.tar.gz:

Publisher: release.yaml on mavam/skeel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file skeel-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: skeel-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 38.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for skeel-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ab515353215263dae6e2902a989de7372e915a6df009c4beb0f3af84e9a6326
MD5 98d73f9e95493e166a7be63c9c8ea582
BLAKE2b-256 678d6ec44c9a96700a71767a7315ef902d3e2bf0cd808f1f02427a15be60dd18

See more details on using hashes here.

Provenance

The following attestation bundles were made for skeel-1.1.0-py3-none-any.whl:

Publisher: release.yaml on mavam/skeel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

2.1.0

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

This release

1.1.0 This release

2 files

1.0.1

2 files

1.0.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.1

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 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