How to Create a New Skill in vertical-plugins and Propagate to Agent Bundles

To create a new skill in vertical-plugins and propagate it to agent bundles, scaffold the skill using scripts/init_skill.py, author the canonical definition in SKILL.md, then run scripts/sync-agent-skills.py to copy it into every agent bundle and validate with scripts/check.py.

The anthropics/financial-services repository manages AI agent skills through a strict source-of-truth model. Skills are authored once in vertical-plugins and automatically vendored into agent-plugins bundles, ensuring consistency across all deployed agents while maintaining fast runtime lookups.

Source-of-Truth Architecture

The repository separates skill authorship from runtime consumption into two distinct layers:

  • Source layer: plugins/vertical-plugins/<vertical>/skills/<skill-name>/ contains the canonical SKILL.md file and optional bundled resources like scripts/, references/, and assets/.
  • Bundle layer: plugins/agent-plugins/<agent-slug>/skills/<skill-name>/ holds a copied snapshot that agents load at runtime.

The scripts/sync-agent-skills.py utility propagates changes from the source layer to every relevant bundle, while scripts/check.py enforces that bundled copies remain in sync with their vertical source, raising drift errors if they diverge.

Step-by-Step: Create a New Skill in vertical-plugins

Scaffold the Skill Directory

Choose a vertical (e.g., wealth-management, private-equity, or financial-analysis) and generate the boilerplate using the built-in initializer:


# From the repository root

scripts/init_skill.py tax-loss-harvesting \
    --path plugins/vertical-plugins/wealth-management/skills/

This invokes the skill-creator helper (defined at plugins/vertical-plugins/financial-analysis/skills/skill-creator/SKILL.md) to create:

  • SKILL.md with required YAML frontmatter placeholders
  • Empty subdirectories: scripts/, references/, assets/

Define the SKILL.md Frontmatter

Open the newly created SKILL.md and replace the placeholders with a trigger-rich description. The file must start with YAML frontmatter delimited by ---:

---
name: tax-loss-harvesting
description: |
  Identify tax-loss harvesting opportunities across taxable accounts.
  Triggers: "tax-loss harvesting", "TLH", "harvest losses".
---

Below the frontmatter, add the workflow body in Markdown and populate the scripts/ or assets/ folders if the skill requires bundled resources.

Add Commands (Optional)

If the skill should expose a slash command, create a Markdown file under:


plugins/vertical-plugins/<vertical>/commands/<command-name>.md

The plugin loader automatically discovers command files in this directory and links them to the corresponding skill.

Propagate to Agent Bundles with sync-agent-skills.py

Once the source skill is complete, propagate it to all agent bundles:

python3 scripts/sync-agent-skills.py

The script executes the following logic (as implemented in lines 20–37 of sync-agent-skills.py):

  1. Builds a source map (lines 20–24): Creates a dictionary src_by_name mapping skill names to their source paths in vertical-plugins.
  2. Iterates over bundles (lines 28–37): Walks every plugins/agent-plugins/*/skills/* directory.
  3. Synchronizes files: Deletes the old bundled copy with shutil.rmtree and replaces it using shutil.copytree from the source directory.
  4. Warns on orphans (lines 31–34): If a bundled skill has no matching source, the script prints a warning but does not delete it automatically.

Validate with check.py

Prevent drift by running the repository-wide lint before committing:

python3 scripts/check.py

The check (lines 18–32 of check.py) verifies that each bundled skill matches its vertical source byte-for-byte. If drift exists, it reports:


bundled-skill: plugins/agent-plugins/<agent>/skills/<skill>/:
    drifted from plugins/vertical-plugins/<vertical>/skills/<skill>/ (run scripts/sync-agent-skills.py)

How the Sync Script Works

Understanding the mechanics of scripts/sync-agent-skills.py helps debug propagation issues. The script:

  • Scans vertically (lines 20–24): It aggregates all SKILL.md files under plugins/vertical-plugins/ to construct the src_by_name lookup table.
  • Matches by folder name (lines 28–37): It assumes the skill directory name (e.g., tax-loss-harvesting) is unique across verticals. Collisions will cause one skill to overwrite another in the bundle.
  • Atomic replacement: By using rmtree followed by copytree, the script ensures bundled agents receive a clean, consistent snapshot without incremental merge conflicts.

Common Pitfalls and Fixes

Pitfall Symptom Fix
Missing frontmatter check.py reports “frontmatter: … missing ‘name’” Ensure SKILL.md begins with --- and includes both name: and description: fields.
Skill name collision Bundled skill contains wrong vertical's logic Rename one of the skill directories; the sync script matches only by folder name, not full path.
Drift after editing check.py reports drifted bundled-skill Run scripts/sync-agent-skills.py before committing to refresh all bundles.
Command not discovered Slash command returns “unknown” Verify the command Markdown file lives under plugins/vertical-plugins/<vertical>/commands/ and matches the intended command name.

Summary

  • Author skills in plugins/vertical-plugins/<vertical>/skills/<skill-name>/SKILL.md as the single source of truth.
  • Scaffold quickly using scripts/init_skill.py <name> --path <vertical>/skills/.
  • Propagate automatically by running python3 scripts/sync-agent-skills.py, which copies source directories into every plugins/agent-plugins/<agent>/skills/ bundle.
  • Validate integrity with python3 scripts/check.py to catch frontmatter errors or drift before deployment.
  • Avoid collisions by ensuring unique skill folder names across verticals, as sync-agent-skills.py matches by directory name only.

Frequently Asked Questions

What happens if two verticals have skills with the same name?

The sync-agent-skills.py script maps skills by directory name only (lines 20–24). If wealth-management/tax-reporting and financial-analysis/tax-reporting both exist, the last one processed will overwrite the previous in agent bundles. Always use unique, descriptive skill directory names to prevent collisions.

Why does the repository copy skills instead of symlinking them at runtime?

Bundled copies in plugins/agent-plugins/<agent>/skills/ eliminate filesystem traversal and dependency resolution at runtime. According to the source architecture, agents load exclusively from their local skills/ folder, ensuring fast startups and hermetic deployments that do not depend on the vertical-plugins directory structure.

How do I add a slash command to an existing skill?

Create a new Markdown file under plugins/vertical-plugins/<vertical>/commands/<command-name>.md. The file should define the command metadata and usage. The plugin loader automatically discovers this file; no manual registration in agent configuration is required. Run sync-agent-skills.py to ensure the command is included in agent bundles.

What causes a "drifted bundled-skill" error in check.py?

This error (reported by lines 18–32 of check.py) occurs when the contents of a bundled skill in plugins/agent-plugins/<agent>/skills/<skill>/ differ from the source in vertical-plugins. Common causes include manual edits directly in the bundle directory or failing to run sync-agent-skills.py after updating the source. Always modify the canonical SKILL.md in vertical-plugins and re-sync.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →