Skip to content

About

skm — declarative skills + agent-definition manager for coding agents (Claude Code, Codex, OpenCode, Gemini CLI, Copilot, Antigravity, Hermes). TypeScript/Bun engine with overlay roots, plan/apply ownership, composed skills, and an HTML review console.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

Skills Manager

Curated local and upstream skills — plus agent definitions — for multiple coding agents.

This repo is both a curated catalog and the implementation of skm. It manages owned local/composed skills and agent definitions with plan/apply, syncs a global upstream baseline, deploys project-specific skill families, and renders an HTML review console. The two upstream workflows delegate fetch and placement to the external skills CLI; owned artifacts use skm's state and drift model.

It also carries agent definitions under agents/: one agent.yaml + instructions.md per subagent, rendered per-harness by skm into each agent's definitions dir (Claude, Codex, Copilot, Cursor, Gemini, OpenCode) and optionally exported as a derived skill or a tprompt prompt. These were absorbed from the retired custom_agents repo at cutover; running its shared-agents tool after cutover is forbidden (see AGENTS.md).

Engine: a TypeScript CLI (skm, under cli/) runs the whole surface, adding agent-scoped skills, private overlay repos, composed skills (one source rendered per consumer — routing tables, self-exclusion, compile-time posture; ADR 0010), gated (user-invoked-only) skills (disable-model-invocation: true translated to each agent's gate — frontmatter or a codex companion file — placed only into gate-honoring agents' own dirs; ADR 0011), and Terraform-style plan/apply with an ownership state file. Design: docs/skills-manager-design.md · decisions: docs/adr/ · usage: cli/README.md. The bash sync/deploy scripts were retired at the ADR 0014 final commit: skm upstream sync and skm deploy replace them (skm still shells to the external skills CLI as the fetch/place engine).

Skills Manager review console showing the public plan-reviewer agent rendered for Codex across clean cross-harness placements

Public-only review artifact generated from this repository.

It also supports an optional gitignored quick-tweak file for extra global skills, per-family additions, exclusions, and custom project families.

Requirements

  • bun (runs the skm CLI under cli/)
  • skills CLI (skm shells to it as the fetch/place engine)
  • git
  • curl for the agents-md sync maintenance script
  • jq is only needed to run the golden-backed parity suites' git shim (dev/test), not at runtime

Quick Start

cd cli
bun install
bun src/cli.ts plan
bun src/cli.ts apply

plan is read-only. apply creates or updates desired placements; stale owned placements are removed only with apply --prune.

After Renaming an Existing Checkout

If this checkout moved from custom_skills to skills-manager, update any registered root before running plan, apply, or status; a configured root that no longer exists is a deliberate hard error:

cd cli
bun src/cli.ts root list
bun src/cli.ts root add ~/code/skills-manager public
bun src/cli.ts root remove ~/code/custom_skills

The machine config is ~/.config/skills-manager/config.json (or under $XDG_CONFIG_HOME). No migration is needed when that file does not exist: the default public root is derived from the CLI's current checkout. Set excludeLocalSkills there to omit named skills from all registered roots on that host. Use excludeLocalAgents the same way for bundled or overlay agent definitions.

Commands

skm upstream sync

Normalizes your global skill setup under ~/.agents/skills and ~/.claude/skills.

It will:

  • remove globally installed skills that are no longer in the curated global catalog
  • update existing global skills
  • add any missing curated global skills
  • audit selected upstream repos for coverage drift
  • clean up broken symlinks in those global directories

Local repo skills are placed separately by skm (see below).

Use it when you want to update your personal baseline skill environment.

If .skills.local.json exists, its globalSpecs are merged into the desired global set and its excludeGlobalSpecs remove explicit upstream skills, or whole upstream repos after normalization, from that resolved global set before stale-skill removal runs. Its preserveGlobalSkillNames protects named handmade global skills from stale removal without adding them to the resolved managed install set.

Exclusion-override behavior, resolved repo summaries, and the ^ full-coverage marker are documented in docs/exclude-overrides.md. The ^ marker means the final resolved set covers all current upstream skills for that repo.

Examples:

cd cli && bun src/cli.ts upstream sync
cd cli && SKILLS_AGENTS="codex opencode" bun src/cli.ts upstream sync
cd cli && SKILLS_AUDIT_REPO_COVERAGE=0 bun src/cli.ts upstream sync

Agent targets

SKILLS_AGENTS is a single space-separated override for upstream sync and deploy. When unset, those verbs use the standard external-CLI target set:

  • codex
  • opencode
  • claude-code

github-copilot, gemini-cli, cursor, and droid are registry opt-in agents: plan/apply place skills for them only on machines that list them in optInAgents.

Override the list to scope a run to a subset of agents, or to opt into additional agents like Hermes (see below).

Hermes opt-in

There are two separate target ids and control planes:

  • skm upstream sync and skm deploy drive the external skills CLI. Use hermes-agent in SKILLS_AGENTS (or deploy's --agents).
  • Local skm plan / apply reads ~/.config/skills-manager/config.json. Use the registry id hermes in that file's agents array; SKILLS_AGENTS does not affect local placement.

For upstream sync, include hermes-agent in SKILLS_AGENTS:

cd cli && SKILLS_AGENTS="codex opencode claude-code hermes-agent" \
    bun src/cli.ts upstream sync

For local placement, append hermes to the existing agents array in machine config. Do not replace that array with the shorter upstream target set above; local defaults also include other supported agents from registry/agents.json.

Hermes behavior is intentionally different:

  • Hermes does not read ~/.agents/skills by default. The skills CLI installs Hermes targets under ~/.hermes/skills/<name>. Local repo artifacts are placed there by skm when hermes is enabled (add-only: skm never prunes hermes placements).
  • ~/.hermes/skills is treated as add-only. Stale-skill removal is scoped with -a to non-Hermes agents so the CLI never removes a Hermes entry on our behalf. Hermes packages and creates its own skills in that directory, and we don't manage what we didn't install. If the narrowed removal leaves ~/.agents/skills/<name> behind (another detected agent still resolves it) and Hermes has no entry under that name, sync follows with an all-agent skills remove so the canonical dir and lock entry go too.
  • We do clean up our own dangling symlinks. After a stale removal, any ~/.hermes/skills/<name> symlink whose target resolves into skills/ or ~/.agents/skills/ is removed. Real directories and symlinks pointing elsewhere are left untouched.
  • Without hermes-agent in SKILLS_AGENTS, skm upstream sync never reads or writes ~/.hermes/skills. To clean up past Hermes writes after opting out, opt back in for one run.
  • Running with SKILLS_AGENTS="hermes-agent" alone is supported but is an edge case: the CLI installs as real directories under ~/.hermes/skills, which look like Hermes-owned content on disk and won't be cleaned up by future runs. Use the additive form (standard + hermes-agent) for any install you want round-trip cleanup on.
  • A fresh Hermes session or /reset is needed for Hermes to pick up newly-added skills. Local entries in ~/.hermes/skills win on name collisions with externally-configured skill roots (skills.external_dirs in ~/.hermes/config.yaml).

skm deploy

Deploys curated skill families into a target directory with project-scoped skills add --copy installs.

Use it when a repo needs a focused set of skills, for example Expo or Convex, without making them part of your global always-on setup.

Behavior:

  • targets the exact positional directory you choose
  • expands current-user ~ and ~/... target paths
  • does not expand ~user/... target paths
  • works in plain directories and git repos
  • copies skills into the project-managed agent directories
  • installs only the selected families
  • does not normalize or remove unrelated project skills
  • audits selected curated family repos for upstream drift when coverage manifests are configured
  • requires git during planning only when a repo-wide spec or exclusion must be expanded; a real deploy may also enumerate during its advisory coverage audit
  • prints repo batches under Planned installs; --dry-run stops before the coverage audit and makes no project changes

If .skills.local.json exists, its familySpecs extend curated families and its excludeFamilySpecs remove explicit upstream skills from each curated family's resolved contribution before the selected families are merged.

Exclusion-override and repo-expansion behavior is documented in docs/exclude-overrides.md.

The bash interactive prompt mode is dropped (skm is agent-first); --list-families plus flags cover the human path:

cd cli && bun src/cli.ts deploy \
  ~/code/my-app \
  --family expo \
  --family convex \
  --agents "codex claude-code" \
  --yes

List available families:

cd cli && bun src/cli.ts deploy --list-families

Local-skill placement (skm)

Local skills from skills/ (and overlay roots) are placed by the skm CLI — symlinks into shared roots for unscoped skills, rendered per-agent trees for gated ones, ownership-tracked and prunable:

cd cli
bun src/cli.ts plan   # preview
bun src/cli.ts apply  # place

Use status for drift, doctor for safety diagnostics (--fix only for its supported repairs), and explain <skill> for source/scoping/visibility. review writes the self-contained console to $XDG_STATE_HOME/skills-manager/review.html by default; use --out <path> to choose another privacy-checked destination.

The former ./link-skills.sh was retired once skm reached placement parity (gate awareness, hermes add-only, stale-link pruning are covered by cli/test).

bash maintenance/sync-agents-md.sh

Refreshes the forked agents-md local skill from upstream getsentry/skills@agents-md.

skills/agents-md/SKILL.md is generated output. Do not edit it by hand. The sync exits nonzero if upstream structure no longer matches the maintained patch, so the weekly workflow surfaces drift instead of retaining stale output.

bash maintenance/sync-agents-md.sh

Catalog

The source of truth is split by purpose; see catalog/README.md for formats and verification:

  • catalog/global-specs.txt global skills managed by skm upstream sync
  • upstream-coverage.json global upstream repos audited for skill drift during skm upstream sync (when SKILLS_AUDIT_REPO_COVERAGE=1)
  • catalog/families.tsv family names and descriptions for project deployment
  • catalog/families/*.txt explicit per-family upstream skill specs
  • catalog/family-coverage.json upstream repos that should be audited for family drift

Current project families:

  • expo
  • convex
  • mattpocock-teaching
  • react
  • security

Notable catalog changes

The global upstream catalog installs diffwarden, tmux, and agent-browser. web-design-guidelines belongs to the React project family and is installed by skm deploy <dir> --family react, alongside the React and React Native skills.

aurokin/diffwarden is listed in upstream-coverage.json so sync audits its full upstream skill set for catalog drift.

Personal Overlay

Create .skills.local.json in the repo root to add personal skills without changing the curated catalog. The file is gitignored; start from .skills.local.json.example. The example file uses placeholder exclusions, so copying it does not opt you out of curated skills until you replace those values intentionally.

This gitignored .skills.local.json is only a quick-tweak layer for the skm upstream sync / skm deploy upstream/family sets — it is not the private overlay repo. Private skills and agent definitions live in a separate registered overlay root (a real repo, resolved by skm); see ADR 0001.

Both upstream verbs validate the entire file when it exists. A malformed or invalid field can therefore block either command even if that field belongs to the other workflow.

Supported keys:

  • globalSpecs additive upstream specs merged into the skm upstream sync desired set
  • excludeGlobalSpecs upstream specs removed from the resolved global install set
  • preserveGlobalSkillNames handmade global skill names protected from stale removal
  • familySpecs additive specs keyed by existing curated family name
  • excludeFamilySpecs explicit upstream specs removed from a curated family's resolved deploy set
  • customFamilies new family definitions with description and specs

See docs/exclude-overrides.md for the implemented exclusion-override semantics, normalization rules, resolved summary output, examples, and implementation notes.

Example:

{
  "globalSpecs": [
    "owner/repo@my-global-skill"
  ],
  "excludeGlobalSpecs": [
    "owner/repo@skill-to-exclude",
    "owner/another-repo"
  ],
  "preserveGlobalSkillNames": [
    "my-handmade-global-skill"
  ],
  "familySpecs": {
    "expo": [
      "owner/repo@my-expo-skill"
    ]
  },
  "excludeFamilySpecs": {
    "expo": [
      "owner/repo@family-skill-to-exclude"
    ]
  },
  "customFamilies": {
    "acme-mobile": {
      "description": "Company mobile workflow skills",
      "specs": [
        "owner/repo@release-ops"
      ]
    }
  }
}

Rules:

  • excludeGlobalSpecs accepts repo-wide owner/repo and explicit owner/repo@skill-name entries
  • preserveGlobalSkillNames accepts exact skill names only, not upstream specs
  • excludeFamilySpecs only accepts explicit owner/repo@skill-name entries
  • familySpecs can only target existing curated families
  • excludeFamilySpecs can only target existing curated families
  • customFamilies cannot reuse a curated family name
  • duplicate specs are deduped with curated entries first

Registering an Agent Variant

A variant is a second instance of an existing agent program with its own config home (e.g. a CLAUDE_CONFIG_DIR profile of the claude binary). Since ADR 0016 this is pure data — no engine code changes:

  1. Probe first (registry entries are evidence-backed): a canary skill in the variant's skills dir must load; dummies present only in ~/.claude/skills and ~/.agents/skills must NOT appear in the variant (and vice versa); the frontmatter gate and agent-def loading re-probed under the relocated home. Remove every probe dummy afterwards.
  2. Registry entry (registry/agents.json): a new directory id for its skills dir plus an agent entry — same dialect as the base program, firstParty: true (it renders per-dialect frontmatter), optIn: true (a variant's existence is per-machine; it must not auto-enable fleet-wide), unscopedOwnDir: true if it should receive unscoped skills, probeCli naming the shared binary (so the gate-version drift probe works without an engine edit), its own agentDefDir, and probe-backed evidence strings. Keep the entry generic: nothing machine- or proxy-specific, no model catalogs.
  3. Machine opt-in (~/.config/skills-manager/config.json): add the variant to optInAgents on the hosts that run it. Allow lists, gated placement, and agent-def fan-out all intersect with enablement, so shared overlays naming the variant are inert on other hosts.
  4. Scoping: trim per-skill with deny (note: existing denies naming the base agent likely need the variant added too), and add it as a composed consumer where wanted — excludeProviders expresses providers the variant routes natively (their chains drop; the consumer file carries the replacement guidance).

Local Skills

Local repo-managed skills live in skills/<name>/SKILL.md.

Current local skills:

  • agents-md
  • bro — gated (disable-model-invocation: true); restates the previous response in plain language. Imported from Lauren Tan's PStack
  • handoff — gated (disable-model-invocation: true); writes session state to a Markdown file outside the checkout so another session or agent can continue
  • html-artifact — creates self-contained HTML documents for plans, reports, comparisons, and UI mock variants; adapted from html-communication by Theo Browne
  • humanizer — gated (disable-model-invocation: true); rewrites AI-sounding prose while preserving its meaning. Locally forked; see credits below.
  • ponytail — gated (disable-model-invocation: true); favors the simplest working coding solution. Locally forked; see credits below.
  • unslop — gated (disable-model-invocation: true); removes AI writing patterns. Locally forked; see credits below.

to-prd and linear-yeet were retired 2026-07 (frontier agents produce PRDs and drive the Linear MCP natively); split-to-prs, an exact fork of the Cursor app's shipped skill, moved to the private overlay root. Gated local skills are never placed in shared roots; skm renders them per-agent (ADR 0011).

To add a new local skill:

  1. Create skills/<name>/SKILL.md
  2. Add frontmatter with name and description
  3. Run skm plan / skm apply (from cli/, via bun)

Skill fork credits

The instruction bodies in these forks are unchanged from upstream. Their only SKILL.md changes are invocation metadata: Unslop, Humanizer, and Ponytail require explicit user invocation. All retain their upstream MIT license notices.

Local fork Author and upstream snapshot License
Unslop Lauren Tan, PStack in cursor/plugins at 93b00b89 MIT
Humanizer Siqi Chen, blader/humanizer at e2e92e7b MIT
Ponytail DietrichGebert, DietrichGebert/ponytail at 356918eb MIT

These skills are local sources, not entries in catalog/global-specs.txt. Upstream refreshes must preserve the local invocation metadata. Existing external installations must be removed through their installer before skm apply can place the local forks; skm will not overwrite foreign files.

Tests

The skm engine (including the upstream sync / deploy parity suites, now golden-backed against the retired scripts' captured output) runs under bun:

cd cli && bun test

The one remaining shell test covers the agents-md fork sync:

bash maintenance/test-agents-md.sh

License

MIT

About

skm — declarative skills + agent-definition manager for coding agents (Claude Code, Codex, OpenCode, Gemini CLI, Copilot, Antigravity, Hermes). TypeScript/Bun engine with overlay roots, plan/apply ownership, composed skills, and an HTML review console.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages