Skip to content

Repository files navigation

sklz

sklz lets you cherry-pick skills from multiple folders into each agent's folder. List and sync them by copy or symlink—interactively or through agent-friendly commands.

Why F#?

F# makes sklz concise, reliable, and practical to maintain while retaining the mature .NET ecosystem.

  1. Strong domain modelling — F# records, discriminated unions, pattern matching, and type inference let the code describe the application’s concepts directly. This makes invalid states harder to represent and shifts many integration mistakes from runtime into compiler errors, so a change that builds and passes tests has stronger correctness guarantees.

  2. Efficient for AI context — An exploratory Rosetta Code comparison found F# and Haskell among the more token-efficient typed languages, close to the best dynamic languages tested. F# gains much of this from type inference: it avoids repetitive declarations while preserving compiler and language-server feedback, keeping code, diffs, and AI-agent context more compact.

  3. Pragmatic platform choice — F# runs on .NET, providing established cross-platform build, test, packaging, and deployment tooling alongside libraries such as Spectre.Console for the terminal interface. Go and Rust were considered, but F# gives this project a more direct implementation and maintenance path without giving up performance or ecosystem support.

Install

Install the latest release on macOS or Linux with:

curl -fsSL https://raw.githubusercontent.com/rodsfreitas/sklz/main/install.sh | sh

This detects your OS and architecture, downloads the matching self-contained binary from the latest GitHub release, and installs it to ~/.local/bin (falling back to /usr/local/bin). Pin a specific version with SKLZ_VERSION=v0.5.0.

Every push to main can produce a release automatically based on Conventional Commits (feat → minor, fix → patch, BREAKING CHANGE → major); GitHub Actions builds and attaches binaries for macOS (arm64/x64), Linux (x64/arm64), and Windows (x64).

The project supports syncing skills for Claude, Codex, and Pi.

Quickstart

# Create the default sklz configuration.
sklz init

# Add another existing folder that contains skills (optional).
sklz source add personal ~/Developer/personal-skills

# See skills discovered across configured source folders.
sklz list

# Interactively choose skills and agent targets to sync.
sklz sync

# Or sync every skill to Claude without prompts (useful for agents).
sklz sync --all --to claude

License

This project is licensed under the MIT License. See LICENSE for details.

Contributing

See CONTRIBUTING.md for setup, testing, commit, and pull-request guidance.

Build from source

Requires .NET 10 SDK. This is also the path for contributors, or for running straight from a checkout without waiting on a release.

dotnet build src/Sklz/Sklz.fsproj

# create ~/.sklz/config.toml with sensible defaults
dotnet run --project src/Sklz/Sklz.fsproj -- init

# list source skills + per-target install state
dotnet run --project src/Sklz/Sklz.fsproj -- list

# add Pi's global skills folder as a named source
dotnet run --project src/Sklz/Sklz.fsproj -- source add pi ~/.pi/agent/skills

# interactively pick skills (grouped by source folder) + targets to sync
dotnet run --project src/Sklz/Sklz.fsproj -- sync

# sync one skill by name; qualify as <source>/<name> if the name is ambiguous
dotnet run --project src/Sklz/Sklz.fsproj -- sync my-skill --to claude

# batch: several skills, several targets, or everything
dotnet run --project src/Sklz/Sklz.fsproj -- sync pp iterate commit --to claude
dotnet run --project src/Sklz/Sklz.fsproj -- sync my-skill --to claude,codex,pi
dotnet run --project src/Sklz/Sklz.fsproj -- sync --all --to claude

Configuration

~/.sklz/config.toml (override the location with the SKLZ_CONFIG environment variable). Skills can live in more than one folder, declared as named [sources.<name>] sections:

[sources.personal]
path = "~/notes/skills"

[sources.work]
path = "~/Developer/work-skills"

[targets.claude]
path = "~/.claude/skills"

[targets.codex]
path = "~/.codex/skills"

[targets.pi]
path = "~/.pi/agent/skills"

[sync]
# "copy" (default) or "symlink"
strategy = "copy"

Add a named source without editing TOML with sklz source add <name> <path>. The folder must already exist; for Pi global skills, use sklz source add pi ~/.pi/agent/skills.

The legacy single-source form still works and is treated as one source named default:

[skills]
source = "~/ai-skills"

What it does

  • init — writes ~/.sklz/config.toml with default paths if it doesn't already exist.
  • source add <name> <path> — adds an existing folder as a named source while preserving the rest of the config file.
  • list — scans each configured source folder for {skill}/SKILL.md, parses optional YAML frontmatter (name, description, dateAdded), and renders one table per source showing whether each skill is also present under the configured Claude, Codex, and Pi skill folders. Skill names that appear in more than one source are flagged.
  • sync — interactive picker grouped by source folder: <space> on a folder header toggles the whole folder, <space> on a skill toggles just that skill, then choose targets.
  • sync <name>... --to <targets> — installs the named skills into the named targets, searching every source. <targets> is claude, codex, pi, or a comma-separated list (claude,codex,pi). Pi defaults to ~/.pi/agent/skills. If a name exists in more than one source the command lists the candidates; disambiguate with sync <source>/<name> --to …. The [sync] strategy controls whether skills are copied (the default) or directory-symlinked.
  • sync --all --to <targets> — installs every skill from every source.

The whole batch is validated before anything is copied: an ambiguous name, an unknown skill, or an invalid target aborts with nothing written, and every offending name is reported rather than just the first. Each copy prints name → target (created|overwritten), followed by a summary count. The command exits non-zero if any copy failed.

Drift detection, doctor, symlink strategy, etc. come in later iterations.

Layout

src/Sklz/
  Domain.fs        types (Skill, Target, …)
  Frontmatter.fs   tiny YAML frontmatter reader
  Config.fs        load/write ~/.sklz/config.toml (multi-source aware)
  Scanner.fs       discover {skill}/SKILL.md under a source folder
  Inventory.fs     join source skills with per-target install state, per source
  Sync.fs          copy a skill folder into a target
  Table.fs         ASCII table renderer
  Commands.fs      init + list + sync
  Program.fs       arg dispatch

About

A small F#/.NET terminal app that syncs locally-authored AI skills across CLI tools (Claude, Codex, Pi).

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages