Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Skern is a minimal, agent-first CLI tool for managing Agent Skills across agentic development platforms (Claude Code, Codex CLI, OpenCode, Cursor, Gemini CLI, GitHub Copilot, Windsurf, Continue, and more). It follows the Agent Skills open standard (agentskills.io) and uses `SKILL.md` files with YAML frontmatter as the canonical format.

The project is written in **Go 1.25+** and the current release is **v0.2.0**.
The project is written in **Go 1.25+** and the current release is **v0.3.0**.

## Repository Layout

Expand Down Expand Up @@ -267,7 +267,10 @@ The full list is generated from `internal/platform/spec.go` — append a row the

## Current Status

Milestones M0–M6 are complete (v0.2.0). M6 shipped dynamic skill loading per #52 — batch install/uninstall, capacity reporting in install/uninstall output, `--enforce-budget` opt-in, `--with-platforms` flag on `skill list`, removal of `--platform all`. The v0.1.x → v0.2.0 transition introduced a **breaking change** to the JSON shape of install/uninstall results (`skills[]` + top-level `platform`/`capacity` instead of `platforms[]`).
Milestones M0–M7 are complete (v0.3.0).

- **M6** (v0.2.0) — dynamic skill loading per #52: batch install/uninstall, capacity reporting in install/uninstall output, `--enforce-budget` opt-in, `--with-platforms` flag on `skill list`, removal of `--platform all`. The v0.1.x → v0.2.0 transition introduced a breaking change to the JSON shape of install/uninstall results (`skills[]` + top-level `platform`/`capacity` instead of `platforms[]`).
- **M7** (v0.3.0) — declarative platform registry: per-platform Go files collapsed into a single `Spec` table (`internal/platform/spec.go`) plus a generic `Adapter`. Five new adapters (`cursor`, `gemini-cli`, `github-copilot`, `windsurf`, `continue`) shipped alongside the rewrite. Also in v0.3.0: `skern init --instructions` writes the skern usage snippet into agent instruction files, `--from-template` requires a skill directory (small breaking change), and Windows joins the CI matrix.

### Future Roadmap

Expand Down
53 changes: 36 additions & 17 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [v0.3.0] — 2026-05-07

Platform registry rewrite, five new adapters, agent-instruction snippet
writer, and a focused breaking change to `--from-template`.

### Breaking changes

- **`skill create --from-template <path>` now requires a skill directory.**
A skill is a folder, so `--from-template` accepts only a directory containing
a `SKILL.md`. Passing a bare file (a `SKILL.md` or a body-only markdown file)
is rejected with a clear error pointing at the parent directory. The
previous behavior of treating a non-frontmatter markdown file as a raw body
is removed — wrap such bodies in a directory with a `SKILL.md` instead. ([#84])

### Added

- **`skern init` can now write a skern usage snippet into agent instruction
Expand All @@ -19,19 +33,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`--target <path>` overrides auto-discovery for explicit files, and
`--print-instructions` emits the snippet to stdout without writing files.
The `InitResult` JSON envelope grows an `instructions` field reporting
what was written.
what was written. ([#87])
- **Five new platform adapters: `cursor`, `gemini-cli`, `github-copilot`,
`windsurf`, `continue`.** All five accept the same `--platform` flag, route
installs to the platform's expected skill directory, and participate in
`skern platform list`/`status` matrices. Path conventions follow
[vercel-labs/skills](https://github.com/vercel-labs/skills#supported-agents).
([#80])
([#81])
- **Declarative platform registry.** Adapters are now defined as one row in
`internal/platform/spec.go` — a `Spec` carrying name, user dir, project dir,
and home-relative detection paths. A single generic `Adapter` struct
implements the `Platform` interface from any spec row, replacing the
per-platform Go files (`claude.go`, `codex.go`, `opencode.go`). Adding a
platform is a one-line PR. ([#80])
platform is a one-line PR. ([#81])
- **Windows added to the CI matrix** — every PR now runs the test suite on
Windows in addition to macOS and Linux. ([#86])
- **`--from-template` preserves template frontmatter and copies sibling
assets.** The template's `description`, `tags`, `metadata.author`, and
`metadata.version` are preserved on the new skill (#82) and every sibling
file or subdirectory (`references/`, `templates/`, `VENDORED.md`, …) is
copied alongside the new `SKILL.md` (#83). The CLI `<name>` argument always
wins over the template's name; other flags override template values when
explicitly set, otherwise template values are preserved.

### Changed

Expand All @@ -43,20 +66,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **CLI flag help and error messages enumerate the registered platforms
dynamically** — adding a platform updates `--platform` help and the
"unknown platform" error text without touching the CLI.
- **`skill create --from-template <path>` now requires a skill directory.**
A skill is a folder, so `--from-template` accepts only a directory containing
a `SKILL.md`. Passing a bare file (a `SKILL.md` or a body-only markdown file)
is rejected with a clear error that points at the parent directory. The
template's frontmatter (`description`, `tags`, `metadata.author`,
`metadata.version`) is preserved on the new skill (#82) and every sibling
file or subdirectory (e.g., `references/`, `templates/`, `VENDORED.md`) is
copied alongside the new `SKILL.md` (#83). The CLI `<name>` argument always
wins over the template's `name`; other flags override template values when
explicitly set, otherwise template values are preserved. **Breaking:** the
previous behavior of treating a non-frontmatter markdown file as a raw body
is removed — wrap such bodies in a directory with a `SKILL.md` instead.

[#80]: https://github.com/devrimcavusoglu/skern/issues/80
- **Documentation site comprehensively refreshed** — eight platform pages,
reference covers `skill import` / `skill version` / `skill diff`, validation
page split into errors/warnings/hints, installation page covers all three
OSes, agent-setup leads with `init --instructions`.

[v0.3.0]: https://github.com/devrimcavusoglu/skern/compare/v0.2.1...v0.3.0
[#81]: https://github.com/devrimcavusoglu/skern/pull/81
[#84]: https://github.com/devrimcavusoglu/skern/pull/84
[#86]: https://github.com/devrimcavusoglu/skern/pull/86
[#87]: https://github.com/devrimcavusoglu/skern/pull/87

## [v0.2.1] — 2026-05-03

Expand Down
4 changes: 2 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ Override with the `SKERN_INSTALL_DIR` environment variable.
## Pin a specific version

```sh
SKERN_VERSION=v0.2.1 curl -fsSL https://raw.githubusercontent.com/devrimcavusoglu/skern/main/scripts/install.sh | bash
SKERN_VERSION=v0.3.0 curl -fsSL https://raw.githubusercontent.com/devrimcavusoglu/skern/main/scripts/install.sh | bash
```

```powershell
$env:SKERN_VERSION = 'v0.2.1'; irm https://raw.githubusercontent.com/devrimcavusoglu/skern/main/scripts/install.ps1 | iex
$env:SKERN_VERSION = 'v0.3.0'; irm https://raw.githubusercontent.com/devrimcavusoglu/skern/main/scripts/install.ps1 | iex
```

## Build from source
Expand Down
6 changes: 6 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default defineConfig({
{ text: 'Installation', link: '/guide/installation' },
{ text: 'Quick Start', link: '/guide/quick-start' },
{ text: 'Agent Setup', link: '/guide/agent-setup' },
{ text: 'Writing Skills', link: '/writing-skills' },
],
},
],
Expand Down Expand Up @@ -73,6 +74,11 @@ export default defineConfig({
{ text: 'Claude Code', link: '/platforms/claude-code' },
{ text: 'Codex CLI', link: '/platforms/codex-cli' },
{ text: 'OpenCode', link: '/platforms/opencode' },
{ text: 'Cursor', link: '/platforms/cursor' },
{ text: 'Gemini CLI', link: '/platforms/gemini-cli' },
{ text: 'GitHub Copilot', link: '/platforms/github-copilot' },
{ text: 'Windsurf', link: '/platforms/windsurf' },
{ text: 'Continue', link: '/platforms/continue' },
],
},
],
Expand Down
24 changes: 16 additions & 8 deletions docs/concepts/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ Skern separates concerns into four layers:
```
Skill Author --> skern --> Registry --> Agent Runtime
|
+-------+-------+
| | |
Claude Codex OpenCode
Code CLI
+---------+---------+---------+---------+
| | | | | | |
Claude Codex Open Cursor Gemini Copilot Continue / Windsurf / ...
Code CLI Code CLI
```

## Layers

### Skill Definition

Metadata and behavior live in a single `SKILL.md` file. The file uses YAML frontmatter for structured fields (name, description, author, version, allowed-tools) and markdown body for the skill's instructions.
Metadata and behavior live in a single `SKILL.md` file. The file uses YAML frontmatter for structured fields (name, description, author, version, tags, allowed-tools) and markdown body for the skill's instructions.

See [Skill Format](/concepts/skill-format) for the full specification.

Expand All @@ -30,12 +30,20 @@ See [Registry](/concepts/registry) for details.

### Validation

Before a skill enters the registry, skern validates it against the [Agent Skills](https://agentskills.io) specification. This includes name format checks, description requirements, and overlap detection against existing skills.
Before a skill enters the registry, skern validates it against the [Agent Skills](https://agentskills.io) specification. This includes name format checks, description requirements, folder integrity (referenced files exist), and overlap detection against existing skills. Validation also surfaces stylistic **hints** (short body, vague description, missing trigger prefix) that don't affect validity.

See [Validation](/reference/validation) and [Overlap Detection](/reference/overlap-detection) for rules and thresholds.

### Platform Adapters

Each supported platform has an adapter that knows where to install skills. Adapters copy the `SKILL.md` to the platform-specific directory, making the skill immediately available to the agent runtime.
Each supported platform has an adapter that knows where to install skills. Adapters copy the skill directory (`SKILL.md` plus any sibling files and subdirectories) to the platform-specific location, making the skill immediately available to the agent runtime.

See [Platform Adapters](/concepts/platform-adapters) for how adapters work.
Adapters are **declarative**: every supported platform is one row in `Specs` in [`internal/platform/spec.go`](https://github.com/devrimcavusoglu/skern/blob/main/internal/platform/spec.go). A single generic `Adapter` struct implements every platform's interface from the spec — no per-platform Go file is required.

See [Platform Adapters](/concepts/platform-adapters) for how adapters work and the full path reference.

## Dynamic Skill Loading

Skern is not just a one-shot installer. The `install` and `uninstall` commands return a `capacity` block (installed count, per-scope threshold, headroom, over-budget flag) so agents can size their working set to a context budget. Pass `--enforce-budget` to refuse installs that would exceed the threshold.

See the [Quick Start](/guide/quick-start#3-install-to-a-platform) for the workflow.
108 changes: 70 additions & 38 deletions docs/concepts/skill-format.md
Original file line number Diff line number Diff line change
@@ -1,99 +1,131 @@
# Skill Format

Skills follow the [Agent Skills](https://agentskills.io) open standard. Each skill is a single `SKILL.md` file with YAML frontmatter and a markdown body.
Skills follow the [Agent Skills](https://agentskills.io) open standard. Each skill is a directory containing a `SKILL.md` file with YAML frontmatter and a markdown body, plus any optional companion files.

## Structure

```markdown
---
name: code-review
description: Review PRs for style and correctness
description: |
Use when reviewing pull requests for style and correctness.
tags:
- review
- quality
version: 1.0.0
author:
name: Jane Doe
type: human
allowed-tools:
- Read
- Grep
- Glob
metadata:
author:
name: Jane Doe
type: human # human | agent
platform: claude-code # only when type=agent
version: "1.0.0"
modified-by: # append-only provenance
- name: codex-cli
type: agent
platform: codex-cli
date: "2026-04-12T10:30:00Z"
---

## Instructions
## Overview

Review pull requests for:
- Code style consistency
- Correctness of logic
- Test coverage
1-2 sentence core principle of the skill.

## When to Use

- Triggering conditions and symptoms

## Core Pattern

The main technique or pattern (before/after for techniques).
```

## Frontmatter Fields

| Field | Required | Description |
|-------|----------|-------------|
| `name` | Yes | Skill name matching `[a-z0-9]+(-[a-z0-9]+)*`, 1-64 chars |
| `description` | Yes | What the skill does, max 1024 chars |
| `version` | No | Semantic version (e.g., `1.0.0`) |
| `author.name` | No | Author name |
| `author.type` | No | `human` or `agent` |
| `author.platform` | No | Platform name (e.g., `claude-code`) |
| `name` | Yes | Skill name matching `[a-z0-9]+(-[a-z0-9]+)*`, 1-64 chars. Must equal the directory name. |
| `description` | Yes | What the skill does — start with "Use when…". Max 1024 chars. |
| `tags` | No | List of classification tags |
| `allowed-tools` | No | List of tools the skill may use |
| `modified-by` | No | Modification history entries |
| `allowed-tools` | No | Tools the skill may use. No empty entries. |
| `metadata.author.name` | No | Author name |
| `metadata.author.type` | No | `human` or `agent` |
| `metadata.author.platform` | No | Platform name (e.g. `claude-code`) — used when `type: agent` |
| `metadata.version` | No | Semantic version (e.g. `1.0.0`); defaults to `0.0.1` on `skill create` |
| `metadata.modified-by` | No | Append-only modification history (set via `skern skill edit --modified-by`) |

`name` and `description` are the only hard requirements. The rest help discovery, validation, and provenance.

## Body

The markdown body contains the skill's instructions. This is what the agent reads when the skill is activated. It must be non-empty.

The recommended body structure (also what `skern skill create` scaffolds) is:

1. **Overview** — 1-2 sentence core principle
2. **When to Use** — triggering conditions
3. **Core Pattern** — the main technique
4. **Quick Reference** — scannable summary
5. **Common Mistakes** — frequent errors and fixes

See [Writing Skills](/writing-skills) for details on what makes a discoverable, well-structured skill.

## Author Provenance

Skills track author metadata and an optional `modified-by` history. `skern skill show` displays the full provenance chain when present, including editor name, type (human/agent), platform, and date.
Skills track an author and an append-only `modified-by` history. `skern skill show` prints the full provenance chain when present, including editor name, type (human/agent), platform, and date. `skern skill edit --modified-by <name>` adds a new entry without overwriting earlier ones.

## Folder Structure

Skills can include additional files alongside `SKILL.md` — helper scripts, templates, configuration files, and other assets. When a skill is installed to a platform, the entire directory is copied.
A skill is a directory. `SKILL.md` is the manifest; sibling files travel with it.

```
my-skill/
├── SKILL.md
├── references/
│ └── notes.md
├── scripts/
│ ├── convert.py
│ └── setup.sh
└── assets/
└── template.json
```

The `scripts/` directory is language-agnostic — skills can include Python, shell, JavaScript, or any other scripts. The agent decides which language is appropriate for the skill.
When a skill is installed to a platform, the **entire directory** is copied. The `scripts/` directory is language-agnostic — skills can include Python, shell, JavaScript, or any other scripts. The agent decides which language is appropriate.

Use `skern skill show <name>` to see which files are bundled with a skill, and `skern skill validate <name>` to check that files referenced in the skill body actually exist.
`skern skill validate <name>` checks that files referenced in the body (via backticks or markdown links) actually exist in the skill directory. Missing references produce **warnings**, not errors. `skern skill show <name>` lists every file bundled with the skill.

## Creating Skills

Use `skern skill create` to scaffold a new skill:

```sh
skern skill create code-review \
--description "Review PRs for style and correctness" \
--description "Use when reviewing PRs for style and correctness" \
--author "Jane Doe" \
--author-type human
--author-type human \
--version 1.0.0 \
--tags review,quality
```

Or seed from another skill. `--from-template <dir>` requires a **skill directory**
— a directory containing `SKILL.md` and any optional companion files
(`references/`, `templates/`, `VENDORED.md`, …). Skern parses the template's
frontmatter and copies every sibling into the new skill:
Or seed from another skill. `--from-template <dir>` requires a **skill directory** — a directory containing `SKILL.md` and any optional companion files (`references/`, `templates/`, `VENDORED.md`, …). Skern parses the template's frontmatter and copies every sibling into the new skill:

```sh
skern skill create code-review \
--from-template ~/.skern/skills/source-template
```

A bare file path (a `SKILL.md` or a body-only markdown file) is rejected with an error pointing at the parent directory. The CLI `<name>` argument always wins over the template's name; other flags (`--description`, `--tags`, `--author*`, `--version`) override template values when explicitly set, otherwise the template's values are preserved.

## Importing Skills

`skern skill import <url>` pulls an existing skill into the registry from a GitHub repository directory or gist:

```sh
# Seeds the new skill from an existing skill directory. SKILL.md frontmatter
# (description, tags, metadata.author, metadata.version) is preserved; all
# sibling files and subdirectories are copied alongside the new SKILL.md.
skern skill create code-review --from-template ~/.skern/skills/source-template
skern skill import https://github.com/owner/repo/tree/main/skills/code-review
skern skill import https://gist.github.com/<id>
skern skill import <url> --name local-name --scope project
```

A bare file path (e.g., a `SKILL.md` or a markdown body file) is rejected with
an error pointing you at the parent directory. The CLI `<name>` argument
always wins over the template's `name`; other flags
(`--description`, `--tags`, `--author*`, `--version`) override template values
when explicitly set, otherwise the template's values are preserved.
Overlap detection runs on import too — pass `--force` to override a near-duplicate block.
Loading
Loading