Skip to content

How It Works

Skills

A skill is a Markdown file (SKILL.md) with YAML frontmatter:

---
name: fastapi-guideline
description: Use this skill whenever working with FastAPI...
---

# FastAPI
Instructions for the agent...

The description field is what the agent reads to decide whether to load the skill. Keep it specific — the more clearly it describes when to trigger, the more reliably it auto-activates.

Loading system

Skills use three-level progressive loading:

1. description (~100 words)   → always in context
2. SKILL.md body              → loaded when skill triggers
3. references/ files          → loaded on demand

This keeps the agent's context lean. Heavy reference material stays on disk until it's actually needed.

Auto-triggering

When you send a message, Claude reads all installed skill descriptions and decides which ones are relevant. If a skill's description matches what you're doing — even without a slash command — it loads the full SKILL.md automatically.

Example: you write "add asyncpg connection pooling to my FastAPI app" — the fastapi-guideline and postgres-best-practices skills activate without you typing anything.

Slash commands

Every skill is also available as a slash command. Type / in Claude Code to see all installed skills:

/coding-guidelines-python
/init-app-stack
/spark-connect
/autoresearch
/bms

Hooks

The coding and bms plugins ship PreToolUse hooks — shell scripts that run before Claude executes a Bash command. They intercept common tool invocations and rewrite them to preferred tools:

  • pip install → uv add
  • npm run dev → bun run dev
  • pytest → uv run pytest

The rewrite is silent. The agent sees the corrected command as if it typed it.

A separate global hook rewrites pyright → uv run ty check, since ty is the team's standard type checker.

The dev-workflow plugin ships three enforcement hooks:

  • PreToolUse on Edit/Write/NotebookEdit (deny) — blocks edits outside a worktree*/.worktree*/.claude path, so changes land in an isolated worktree rather than a shared main checkout.
  • PreToolUse on EnterWorktree (allow) — auto-approves entering or creating a worktree whose path/name matches the same worktree*/.worktree* pattern, so switching into an already-isolated worktree doesn't hit a permission prompt.
  • PreToolUse on Bash (deny) — blocks commands that publish or complete a PR (bdt pr publish, bdt pr create --no-draft, az repos pr create/update --auto-complete, gh pr create/ready/merge, etc.) unless a code review has already run earlier in the session — /code-review or /bms-code-review, directly or via a subagent, or a review done by the local OpenAI codex CLI. The hook reads the session transcript (and subagents/*.jsonl). A codex review counts only if the transcript holds a real Bash call whose command word is codex and that runs codex exec "<prompt>" (the prompt must mention a code review / the bms-code-review skill, or say "review" together with diff, branch, PR, pull request, changes or commit) or codex review (also codex exec review), and the run is known to have finished: a foreground call whose tool result is not an error, a run_in_background call with a completed task notification, or a shell-backgrounded run (nohup codex exec ... &, where the tool result only says "started") whose -o <file> output file exists, is non-empty and is newer than the call's transcript timestamp. The -o file is proof only for shell-backgrounded runs: it never rescues a failed foreground or run_in_background call, which can leave partial output behind, and a backgrounded run without -o does not count. The tool result is the exit status of the whole command line, so a foreground or run_in_background run only counts when the codex call decides that status: cd x && codex exec ... and codex exec ... && echo ok are fine, but codex review | cat, codex exec ... | tee out.md (unless set -o pipefail comes earlier), codex exec ...; echo done and codex exec ... || true are not accepted, because they exit 0 even when codex failed. For those, background with & and -o, or drop the tail. A codex exec prompt may come from a variable assigned earlier in the same command (P="...code review..."; codex exec "$P"); an unresolved variable does not count. A start alone, codex --version/--help, and the word "codex" in a commit message, echo or grep never count. As with the Claude-side check, the review counts for the whole session: it is not tied to HEAD and later commits do not invalidate it.

The same two hooks run in Codex, from the generated .agents/plugins/marketplace.json. The worktree check reads the files of an apply_patch patch, and the PR gate reads the Codex rollout (session_meta first row) instead of a Claude Code transcript; Codex has no EnterWorktree, so that hook is left out. node scripts/sync-codex.mjs keeps the Codex marketplace identical in content to the Claude one, and CI fails when it is stale.

Plugins

Skills are bundled into plugins for easier distribution. A plugin is a named group of skills that install together.

The bmsuisse-skills marketplace (this repo) defines all available plugins. When you enable coding@bmsuisse-skills, all skills in that plugin become available in your Claude Code session.

Plugin definitions live in .claude-plugin/marketplace.json.

File locations

After installation, skills land here:

Platform Path
Claude Code .claude/skills/ (project) or ~/.claude/skills/ (global)
Cursor .cursor/rules/
Codex CLI ~/.codex/skills/

Contributing a skill

  1. Create skills/<skill-name>/SKILL.md
  2. Add it to the relevant plugin in .claude-plugin/marketplace.json as ./skills/<skill-name>
  3. Run npm run skill:validate and npm run plugins:check to confirm every skill, agent and hook script a plugin references exists
  4. Open a PR — CI auto-updates the skills table in README