Skip to main content

Skill Manager

Project-scoped declarative skill manager for coding agents that load skills from ./.agents/skills/ (and optionally ~/.agents/skills/).

One source, many projects, slim globals. Each skill lives once in a cached Source. Projects get symlinks (Links), not copies. Keep agent-global skills minimal; declare per project what you actually need.

Compatible with any agent that discovers skill directories containing SKILL.md under those paths (pi is one example).

Project Links live under ./.agents/skills/; user-global Links under ~/.agents/skills/ are managed with the same model via --global (see Global skills).

Features

  • Declare and sync project skills — write .skill-manager.json, run skill-manager sync
  • Inspect source and link statusskill-manager list (linked / external / broken / unlinked)
  • Enable / disable — interactive filterable picker (TTY) or non-interactive batch enable <repo> <name>... / disable <name>...
  • Manage source cacheskill-manager source list|add|remove|update|available-skills
  • Global skills - --global flag applies any command to user-global skills (~/.skill-manager.json, ~/.agents/skills/)
  • Scripting / CI — root --json on every command (skill-manager --json <cmd> ...)

Install

uv tool install cnife-skill-manager
# or: pipx install cnife-skill-manager

# from source (dev):
uv tool install .
# or run in-place:
uv run skill-manager

Configure

Create ./.skill-manager.json in your project:

{
  "skills": [
    {"name": "read", "repo": "tw93/Waza", "path": "skills/read"},
    {"name": "kami", "repo": "tw93/Kami", "path": "."}
  ]
}
  • name: symlink name under ./.agents/skills/ (single path component; duplicates error)
  • repo: GitHub owner/repo (both parts must be safe slug components)
  • path: skill directory inside the repo (. for repo-root skills; must contain SKILL.md; path traversal is rejected)

Usage

skill-manager sync                     # clone/fetch sources, link declared skills
skill-manager list                     # show sources and skill status
skill-manager enable                   # interactive TTY: filterable source → multi-select skills
skill-manager enable <repo> <name>...  # non-interactive batch enable (path derived from cache)
skill-manager enable --all ...         # include hidden/internal skills when resolving
skill-manager disable                  # interactive TTY: multi-select enabled skills
skill-manager disable <name>...        # non-interactive batch disable
skill-manager --json sync              # single JSON object on stdout (all commands)

Batch enable / disable

enable and disable accept multiple skills in one invocation:

skill-manager enable tw93/Waza read write kami   # enable several skills from one repo
skill-manager disable read write                 # disable several skills
  • enable is atomic: every name is validated first; if any is missing or ambiguous, nothing is applied and all problems are reported at once (exit 1). Already-enabled names are idempotent no-ops. The whole batch syncs once.
  • disable is lenient: disabling a name that is not enabled is a no-op, never an error.
  • Interactive picker (TTY only): type to filter, ↑/↓ move, space toggle, Enter confirm, Esc clears filter then cancels, Ctrl-C cancels. enable is two steps (source, then skills; already-enabled rows are locked). disable is one multi-select over current declarations. Non-TTY interactive attempts error with exit 1.

Global skills

Add --global to any of sync / list / enable / disable to target user-global skills instead of the project. The user's home is treated as a project: declarations live in ~/.skill-manager.json and links land in ~/.agents/skills/. Sources and the cache are shared across scopes.

skill-manager --global sync                  # link globally-declared skills into ~/.agents/skills/
skill-manager --global list                  # show global skills status
skill-manager --global enable <repo> <name>...  # declare globally + sync (batch)
skill-manager --global disable <name>...        # remove global declarations + links (batch)
skill-manager --json --global list           # JSON output composes with --global

Running skill-manager from ~ without --global targets ~/.skill-manager.json too (home is the global project) — intentional, not a collision.

Source repository management

skill-manager source list                    # list registered sources and HEAD status
skill-manager source add <owner/repo>        # add and clone a new source
skill-manager source remove <repo>           # remove source (cache + config)
skill-manager source update [repo]           # update one or all sources
skill-manager source available-skills [repo] # list skills in the cache (no project config)
skill-manager source available-skills --all  # include hidden/internal skills

sync is idempotent and never overwrites an existing non-tool symlink (it skips with a notice). Sources are derived from the declared skills' repo fields.

Cold start (new source, no hand-edited JSON)

skill-manager source add <owner/repo>              # clone + register globally
skill-manager source available-skills <owner/repo> # optional: discover skill names
skill-manager enable <owner/repo> <name>           # declare in project + sync

enable does not clone; introduce sources with source add (or declare in .skill-manager.json and sync).

Source skill discovery

source available-skills and enable share one scanner over the cached Source checkout:

  • Default: skip noise directories (node_modules, dist, build, __pycache__), directories whose names start with . (e.g. .git, .archive, .curated), and skills whose frontmatter has metadata.internal: true.
  • --all: include those hidden/internal skills. Skill-root truncation still applies: a directory that contains SKILL.md is one skill and is not walked further.
  • Declared skill path values (including under .archive/) are unaffected — sync / list still honor project config as written.

Layouts like skills/.curated/... therefore need --all to appear in discovery (stricter default than some installers that whitelist curated paths).

With --json, success is {"ok": true, "data": ...} and failure is {"ok": false, "error": {"code", "message"}} (exit 0 / 1 / 2 for success / business error / usage error). Place --json before the subcommand: skill-manager --json list, not skill-manager list --json.

In project scope, list and enable JSON also include a per-skill boolean enabled_globally (matched by skill name against ~/.skill-manager.json). It is omitted under --global. If the global declaration exists but cannot be read, the command still succeeds, values are false, and a top-level warnings: [{code: "global_config_error", message}] is added. Human list marks the same overlap with before the name; interactive enable uses (project-locked) and (global) glyphs without blocking selection.

Paths (XDG)

What Path
Global config $XDG_CONFIG_HOME/skill-manager/config.json (default ~/.config/skill-manager/config.json)
Source cache $XDG_CACHE_HOME/skill-manager/repos/ (default ~/.cache/skill-manager/repos/)
Project skills ./.agents/skills/
Global skills declaration ~/.skill-manager.json
Global skills ~/.agents/skills/

Roadmap

The What — actionable tickets — lives in the issue tracker. This section is the Why: the shape skill-manager is growing toward.

Dual-user design

skill-manager has two users, and every surface must serve both:

  • Humans — an interactive CLI, and a project config (.skill-manager.json) simple enough to read and edit by hand.
  • Agents — batch-friendly flags and machine-readable output for scripts, CI, and AFK coding agents.

Any source

A Source shouldn't be locked to owner/repo on GitHub. Arbitrary Git URLs and local directories should qualify too. Pinning a Source to a specific commit or tag for reproducibility is a lower-priority future direction.

One model, project and global

Project Links and user-global Links (~/.agents/skills/) share one declaration-and-sync model via the --global flag: keep globals slim, declare per project what you actually need.

Download files

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

Source Distribution

cnife_skill_manager-0.7.0.tar.gz (73.7 kB view details)

Uploaded Source

Built Distribution

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

cnife_skill_manager-0.7.0-py3-none-any.whl (29.1 kB view details)

Uploaded Python 3

File details

Details for the file cnife_skill_manager-0.7.0.tar.gz.

File metadata

  • Download URL: cnife_skill_manager-0.7.0.tar.gz
  • Upload date:
  • Size: 73.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for cnife_skill_manager-0.7.0.tar.gz
Algorithm Hash digest
SHA256 06e050106cd3e782bc21dd6682785e54e5052ef241a2e943c6086cb8cc820624
MD5 f95535050bac781d18b7c6d5726ce2fa
BLAKE2b-256 5b8820df932b2256e98f6df497a32804fe6a88b5c9f371adc9bffedf9e93cf5e

See more details on using hashes here.

Provenance

The following attestation bundles were made for cnife_skill_manager-0.7.0.tar.gz:

Publisher: publish.yml on CNife/skill-manager

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

File details

Details for the file cnife_skill_manager-0.7.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cnife_skill_manager-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e7aa4daa938ab80cdba2bfd9e282ce67239a152d26a8197b66303fef299523c8
MD5 8e14713d9ad5ac0f7b8a24bc2861db38
BLAKE2b-256 479b2fd112cc9cc5a35e2fe50d6d9ffbbd5ebfb58e9d5be4431c40ed6212fa8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for cnife_skill_manager-0.7.0-py3-none-any.whl:

Publisher: publish.yml on CNife/skill-manager

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page