skyl

the cli

Commands

Ten of them. Nothing is written without asking, and every one prints what it would do first.

$npm i skyl.dev

Or prefix any command with npx skyl.dev and install nothing.

Getting skills in

scan

skyl scan

Read the project and propose an install.

Reads build files as text rather than invoking a build. That is instant, works on a project that does not currently compile, and needs no toolchain installed. The cost is that a dependency assembled at runtime from variables is missed, which is why scan proposes and never installs on its own.

It prints what it matched on, what it considered and rejected, and the token cost, before anything is written. Running it again is safe: it shows what is already installed, what is new, and what is no longer detected because a dependency was dropped.

flags

--json
machine-readable output, for a script or a CI check
--dir <path>
read skills from a local checkout instead of the bundled registry
--refresh
prefer the network over the copy shipped in the package
-C <path>
run as if in this directory

examples

$npx skyl.dev scan

propose an install for the current project

$npx skyl.dev scan --json

the same, as JSON

add

skyl add <skill...>

Install skills and everything they require.

Resolves requires and orders dependencies first, because sections are concatenated in the order written and a layer that refers to its core reads wrong if it lands first.

Bare names work once a family has been named, so `add android/core kotlin compose` resolves inside android. An ambiguous bare name is an error rather than a guess: silently picking one of two families installs the wrong thing and looks like it worked.

Only the sections named by agent_sections are written. The reasoning, the pitfalls and the evidence stay in the registry for a human to read and never reach the model.

Each file carries the frontmatter its tool reads to decide whether the rule applies. Without it the file is written, listed and never loaded, which looks exactly like a working install.

Where the tool gives a skill its own directory, `claude` and `agents`, the `references/` files its rules point at are installed beside it. Where it takes one file per skill they cannot be, so `add` names the ones that stayed behind rather than leaving a rule pointing at nothing.

It also says when a target will not read everything it was given: Windsurf reads 6,000 characters of a rule and 12,000 across all of them, and truncates the rest silently.

flags

--target <name>
claude, cursor, windsurf, continue or agents
-y, --yes
do not ask before writing
--dir <path>
install from a local checkout

examples

$npx skyl.dev add android/core kotlin compose

three layers, dependencies first

$npx skyl.dev add compose --target cursor

write .cursor/rules/ instead

remove

skyl remove <skill...>

Take skills back out.

Refuses to orphan a dependency. If something still installed requires the skill being removed, that other skill is left citing rules the agent will not have, which is worse than either keeping both or removing both.

examples

$npx skyl.dev remove compose

remove it, and refuse if something needs it

Keeping them current

list

skyl list

What is installed, and what has moved since.

Reads skyl.lock and compares it against both the files on disk and the registry. It reports a local edit and an upstream change differently, because the fix differs: one is your work to keep, the other is ours to offer.

diff

skyl diff [skill...]

What changed here, and what changed upstream.

A line diff between the file in your repository and what the registry would write today. Read-only. It prefers the network, because currency is the entire point of asking.

flags

--full
the whole file rather than hunks

update

skyl update [skill...]

Apply the upstream side, keeping local edits.

Three cases, handled differently. Upstream moved and the file is untouched: it applies. The file was edited here and upstream did not move: it is left alone. Both moved: it stops, shows the diff, and requires --force, which is the only way to lose the edits.

A version bump that changes nothing installed, a patch that only touched a human-facing section, is recorded in the lockfile and not rewritten. Otherwise every patch release would report an update to something that did not change.

flags

--force
take the upstream side of a conflict
--diff
show what will change before asking

Your own files

audit

skyl audit [file]

Read a hand-written CLAUDE.md and say what is in it.

Analysis, never rewriting. Prose passed through a model comes back longer and more generic, and the file being audited is usually one somebody tuned by hand over months.

It reports which sections share vocabulary with skills in the registry, and always prints the words it matched on, because a claim of overlap that cannot be checked is worth nothing. It also flags sections with no instruction in them, lists what a context file is expected to carry and does not, and refuses to stay quiet about anything that looks like a credential.

It does not claim to find contradictions. That needs a model, and a confident wrong answer about your file is worse than no answer.

examples

$npx skyl.dev audit

find and read the obvious candidates

context

skyl context

Emit what a model needs to describe this project.

Selects files by rule: documentation and schema above code, entry points, dependency wiring, shared foundations, one representative per layer, plus the full tree. Deterministic, so the same repository produces the same bundle and you can review it before it goes anywhere.

A file containing something that looks like a credential is withheld rather than masked. What leaves cannot come back.

flags

--dry-run
list what would be sent, and send nothing
--json
the bundle as structured data
--out <file>
write to a file instead of stdout

examples

$npx skyl.dev context --dry-run

see the selection before trusting it

learn

skyl learn

Derive a project knowledge skill from this repository.

Product knowledge, not code quality: what the product is, what its terms mean, what its parts are called, where things go. The one kind of context a community registry can never supply.

There is no API key anywhere in it. Selecting the files, preserving your hand-written text and merging the result happen locally; the reading is done by whichever model you already pay for, through --agent, or by pasting what --print-prompt gives you.

Anything the model cannot observe becomes a question rather than a claim, marked in the file so it resurfaces on the next run. Text under ## Manual is yours and is never overwritten, because a refresh that eats hand-written rules once is a refresh nobody runs again.

flags

--agent <cmd>
pipe the prompt to an agent CLI, for example claude
--print-prompt
print it instead, to paste anywhere
--out <file>
write the prompt to a file

examples

$npx skyl.dev learn --agent claude

use your own Claude Code login

$npx skyl.dev learn --print-prompt

paste it into any model you like

Authoring

lint

skyl lint [path...]

Check skills against the spec.

Frontmatter, rule shape, id stability, retired ids never reused, cross-references that resolve, and the sections a shipped skill is expected to carry. It also flags wording a reader cannot decide, since a rule nobody can check is a rule nobody can follow.

Run it before opening a pull request. The registry runs an independent second validator in CI, and a disagreement between the two fails the build rather than passing quietly.

flags

--strict
warnings fail the run

examples

$npx skyl.dev lint skills

check a whole registry checkout