Skip to content

adityachilka1/skillforge

skillforge

CLI for authoring Claude Skills. Scaffold, validate, and lint SKILL.md files for the agent ecosystem.

npm ci license


Status — v0.0.2, early days. init, validate, lint, pack, install, update, format, inspect, diff, tree, cat, ls, and uninstall work today. Registry, publish, and eval flows land in v0.1.

Install

npm install -g @adityachilka/skillforge
# or
pnpm add -g @adityachilka/skillforge

Use

skillforge init <name>

Scaffold a new skill directory containing a SKILL.md with sensible-default frontmatter:

skillforge init code-review
# ✓ scaffolded /path/to/code-review/SKILL.md

The generated file is a real template — proper frontmatter, sectioned body (What / When / Instructions / Examples), TODO markers wherever you need to write.

Pass --out <dir> to choose the parent directory. Pass --force to overwrite an existing SKILL.md.

skillforge validate <path>

Validates a SKILL.md against the frontmatter schema and reports any issues:

skillforge validate ./code-review/SKILL.md
# ✓ ./code-review/SKILL.md — frontmatter valid, 42 body lines

Exits 0 on full validity, 1 on any issue. Drop into CI:

- run: npx @adityachilka/skillforge validate ./skills/*.md

skillforge lint <path>

A stricter peer of validate. Where validate checks the schema (hard pass/fail), lint surfaces style and quality smells — short or noun-phrase descriptions, missing trigger language, empty tags, stale 0.0.1 versions, missing ## When to use / ## Examples headings, residual TODOs, second-person prose, trailing whitespace:

skillforge lint ./code-review/SKILL.md
# warnings (2)
#   · ./code-review/SKILL.md: description-no-trigger: description should include triggering language…
#   · ./code-review/SKILL.md: tags-empty: tags array is empty — add a few for discoverability

Exits 0 on warnings-only (advisory), 1 on any error (e.g. residual TODO), 2 with --strict if there's any issue at all. Pass --json for machine-readable output:

skillforge lint ./code-review/SKILL.md --strict --json

skillforge pack <dir>

Bundle a skill directory into a .skill archive (a plain zip), ready to drop into Claude / Cowork's "Save skill" install flow:

skillforge pack ./code-review
# ✓ packed 4 files → code-review.skill (3.2 KB)

Validates the SKILL.md before packing (skip with --skip-validation). Default output is <dirname>.skill in the current working directory — override with --out <file>. Excludes .git, node_modules, hidden files, and *.log to keep bundles clean. Pure-JS zipping via jszip — no native deps.

skillforge install <url>

Download a remote .skill archive and extract it into ~/.claude/skills/<skill-name> (override with --out <dir>):

skillforge install https://example.com/code-review.skill
# ✓ code-review → ~/.claude/skills/code-review (4 files, 3.2 KB)

Refuses plaintext http:// (skills execute on your machine), refuses zip-slip entries, refuses symlinks in archives, caps downloads at 64 MB, and validates the bundle's SKILL.md before writing a single file to disk. Pass --force to clear an existing install directory before extracting; pass --dry-run to validate and report what would happen without touching the filesystem.

skillforge update <path>

Bump the version: field of a SKILL.md without hand-editing the frontmatter. Accepts either a file path or a directory containing a SKILL.md:

skillforge update ./code-review --bump patch
# ✓ ./code-review/SKILL.md: 0.1.0 → 0.1.1

skillforge update ./code-review/SKILL.md --new-version 1.0.0
# ✓ ./code-review/SKILL.md: 0.1.1 → 1.0.0

Pass exactly one of --bump <patch|minor|major> or --new-version <semver>. Pre-release tags (-beta, -rc.1, …) are dropped on any bump, matching npm version. A missing version: field is treated as 0.0.1 (the schema default) so a patch on a freshly-scaffolded skill produces 0.0.2. The proposed frontmatter is validated against the schema before anything hits disk, and the write is line-surgical — body bytes, field order, and other YAML formatting are preserved byte-for-byte. Pass --dry-run to print the would-be new version without writing.

skillforge format <path>

Reformat a SKILL.md to canonical shape — frontmatter keys in the schema's declared order (name, description, version, tags, author, homepage, then any passthrough fields alphabetized at the end), trailing whitespace stripped, runs of blank lines collapsed to two, exactly one trailing newline. Think prettier for the SKILL.md envelope: lint flags style smells, format fixes them.

skillforge format ./code-review/SKILL.md
# ✓ formatted ./code-review/SKILL.md

skillforge format ./code-review/SKILL.md --check
# exits 1 if anything would change — useful in CI

skillforge format ./code-review/SKILL.md --dry-run
# dry-run ./code-review/SKILL.md (nothing written)

skillforge format ./code-review/SKILL.md --write=false
# prints the formatted result to stdout instead of writing

Fenced code blocks (```) are preserved verbatim — format is gentle on the body, never reflowing prose. The output is always validated against the schema before writing; an already-canonical file is a no-op (exit 0, no write). Format is idempotent: running twice produces byte-identical output the second time.

skillforge inspect <path>

One-shot diagnostic report — rolls validate + lint + a frontmatter summary + body stats + (for directory inputs) the attached-file inventory into one structured view. The "give me everything you know about this skill" command. Accepts a .skill archive, a directory containing a SKILL.md, or a SKILL.md file directly — same recognition rule as cat and install:

skillforge inspect ./code-review
# Directory: /…/SKILL.md
# code-review  ISSUES
#
# FRONTMATTER
#   name         code-review
#   description  Use this when the user asks for a code review on a diff…
#   version      0.1.0
#   tags         code, review
#
# BODY
#    42  lines
#   210  words
#  1832  characters
#     4  sections
#   headings:
#     · What this skill does
#     · When to use
#     · Examples
#
# VALIDATION
#   ✓ no issues
#
# LINT
#   · warning …/SKILL.md: tags-empty: tags array is empty…
#
# ATTACHED FILES
#   · SKILL.md
#   · templates/letter.md
#
# SUMMARY
#   ✗ validation: 0  lint: 1

# Inspect a packed bundle without extracting anything
skillforge inspect ./code-review.skill
# Archive: /…/code-review.skill
# code-review  OK
#

# Force archive mode against a renamed bundle (sniffs zip magic)
skillforge inspect ./code-review.bundle --from-bundle

The first line of the report shows the source — Archive: …, Directory: …, or File: … — so you can tell which mode inspect is in at a glance. Archive mode opens the .skill in memory, materializes SKILL.md to a one-off temp file just long enough to run validate / lint against it, then cleans up; no other archive entries are extracted. The attached-file inventory is intentionally directory-only (a bundle is opaque — use tree or install --dry-run to peek at its file list).

Pass --json for machine-readable output (CI-friendly — every field is JSON-stable). Exit 0 if validation passes and there are no lint errors, 1 otherwise. Reuses pack's exclusion rules so the attached-file list matches exactly what pack would bundle.

skillforge diff <a> <b>

Structural comparison of two SKILL.md files. A plain diff is noisy — a reordered heading or a one-word frontmatter change drowns in re-wrapped paragraphs. skillforge diff pulls the structural signal out: which frontmatter fields changed, which ## / ### sections were added, removed, or reordered, and a coarse body line-count delta.

skillforge diff ./code-review-v1/SKILL.md ./code-review-v2/SKILL.md
# diff …v1/SKILL.md → …v2/SKILL.md
#   frontmatter: 1  headings: 2  body lines: +6 -3
#
# FRONTMATTER
#   ~ version: 0.1.0 → 0.2.0
#
# HEADINGS
#   + Examples
#   ~ When to use it  (position 1 → 2)
#
# BODY
#   +6  -3  lines (coarse)

Pass --json for machine-readable output. Exit 0 if the files are structurally identical, 1 if they differ (mirrors mcp-devtools diff), 2 on validation or IO error. Both files must validate against the schema — broken frontmatter is refused so the structural view stays trustworthy.

skillforge tree <dir>

Preview what files pack would include in a .skill bundle without actually building the archive. Walks the directory with the same exclusion rules pack uses (.git, node_modules, hidden files, *.log) and prints a tidy box-drawing tree with per-file sizes:

skillforge tree ./code-review
# /…/code-review
# ├──   312 B  SKILL.md
# ├──            templates/
# │   └──   24 B  letter.md
# └──   12 B  tool.py
#
# 3 files · 348 B

Pass --json for machine-readable output. Pass --sort size to see files in descending byte-size order (useful for spotting heavy fixtures); --sort path is the default. Side-effect free — tree never writes.

skillforge cat <skill>

Print the bundled SKILL.md of a .skill archive to stdout — like tar -xOf for skill bundles, but with frontmatter validation and section slicing. Accepts a .skill archive, a SKILL.md file, or a directory containing one:

skillforge cat ./code-review.skill
# ---
# name: code-review
# description: …
# ---
#
# # code-review body…

skillforge cat ./code-review.skill --section frontmatter
# name: code-review
# description: …
# version: 0.1.0
# tags: [code, review]

skillforge cat ./code-review.skill --section body
# # code-review body…

skillforge cat ./code-review.skill --json
# { "name": "code-review", "version": "0.1.0", "frontmatter": "…", "body": "…" }

Validates frontmatter against the schema before emitting — a broken .skill is refused with a clear error rather than printing garbage. Default behaviour prints the raw bytes; --section frontmatter returns just the YAML (no --- fences), --section body returns the markdown body. Pass --json for a structured { name, version, frontmatter, body } payload. Side-effect free — cat never extracts other files or writes to disk.

skillforge ls

List installed skills in ~/.claude/skills/ (the default install target) — the npm ls analogue for the Claude skills tree:

skillforge ls
# INSTALLED SKILLS  (/Users/you/.claude/skills)
#
# Name         Version     Path
# alpha-skill  0.2.1       /Users/you/.claude/skills/alpha-skill
# code-review  1.0.0       /Users/you/.claude/skills/code-review
# zebra-skill  3.0.0-beta  /Users/you/.claude/skills/zebra-skill
#
# 3 skills installed

skillforge ls --from ./local-skills
# scan a different tree (CI fixtures, sandbox testing)

skillforge ls --include-invalid
# include skill dirs whose SKILL.md fails validation, tagged `(invalid)`

skillforge ls --json | jq '.skills[] | .name'
# machine-readable output for shell pipelines

Read-only directory scan — ls never fetches, never writes. A missing ~/.claude/skills/ returns an empty result with exit 0 (a fresh machine is not an error); a --from path that points at a file rather than a directory is a hard error. Loose files and skill-less subdirectories are skipped silently — a half-pulled install shouldn't pollute every ls invocation. Results are sorted by name ascending so the output is stable across platforms.

skillforge uninstall <name>

Remove an installed skill from ~/.claude/skills/ — the counterpart to install. Names a single skill (not a path); refuses anything that contains a path separator or .. traversal segment so a typo can never escape the install root:

skillforge uninstall code-review
# remove /Users/you/.claude/skills/code-review (4 files, 3.2 KB freed)? [y/N] y
# ✓ removed /Users/you/.claude/skills/code-review (4 files, 3.2 KB freed)

skillforge uninstall code-review --force
# ✓ removed /Users/you/.claude/skills/code-review (4 files, 3.2 KB freed)
#   skips the prompt — handy for CI / scripts

skillforge uninstall code-review --dry-run
# dry-run would remove /Users/you/.claude/skills/code-review (4 files, 3.2 KB) — nothing written

skillforge uninstall code-review --from ./local-skills
# operate on an alt-tree (CI fixtures, sandbox testing)

Without --force, prints the resolved path + the size that would be reclaimed, then asks [y/N] on stdin — saying anything other than y/yes aborts with exit 1 and writes nothing. --dry-run walks the tree to compute bytesFreed / fileCount and returns without touching disk. Exit codes: 0 on success, 1 on user-aborted / target-not-found, 2 on path-safety errors (traversal, separator in name, non-directory at target, empty name).

Schema

---
name: code-review              # required, 1-80 chars
description: |                 # required, 20-500 chars
  Use this when the user asks for a code review on a diff or pull request.
  Avoid auto-merging anything; comment with specific line references.
version: 0.0.1                 # optional, semver, defaults to 0.0.1
tags: [code, review]           # optional
author: "@adityachilka1"       # optional
homepage: https://…            # optional, must be URL
---

# code-review body…

Unknown frontmatter fields are preserved (forward-compatible with whatever Anthropic ships next).

Roadmap

  • v0.0.1init, validate
  • v0.0.2pack, install, ls ✓ (this release)
  • v0.1publish to the skillforge.dev registry, eval suite, install from registry
  • v0.2 — MCP-compatible installer so any MCP client can install skills from the registry

Companion projects

  • mcp-devtools — Chrome DevTools for the Model Context Protocol.
  • agentbench — snapshot tests for AI agent traces.

License

MIT © 2026 Aditya Chilka.

About

Open registry + CLI for Claude Skills — in early development. Star to follow v0.1.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors