Skills

Install reusable instructions that teach agents repeatable workflows.

A skill is an on-demand instruction doc: a Markdown file that teaches an agent a procedure, such as how to install a tool or how to deal with an audio message. Skills are how an agent learns to do something new without a single line of code changing.

Listed, not loaded

A skill is never pasted into the system prompt in full. Only its name and a one-line summary are listed in the agent’s context. When the topic comes up, the agent calls the skill tool with that name, reads the whole document, and follows it.

That is what keeps skills cheap. An agent can know dozens of procedures without them weighing the conversation down, because each one costs a single line until the moment the work actually calls for it. The summary is simply the first non-empty line of the file, so that opening line should say when the skill applies.

The skill tool. An agent needs the skill tool in its tool list to read skills. Without it the skills are listed in its context but never opened.

Built-in skills

These ship with Pepe, under priv/skills/:

Writing your own

User skills live in ~/.pepe/skills/*.md. A user skill overrides a built-in of the same name, so writing a handle-media.md of your own replaces the one that ships with Pepe. The first non-empty line is the summary; everything after it is the procedure, in plain Markdown, written for the agent to read and follow.

~/.pepe/skills/cut-a-release.md

There is no registration step and no restart. Drop the file in and the skill appears in the agent’s list on its next message.

Let the agent write it

An agent can author its own skills. Ask it to remember how to do something as a skill and, guided by skill-creator, it writes a new skills/<name>.md that shows up in its own list right away.

You: that worked. remember how to cut a release as a skill

Agent: saved skills/cut-a-release.md. I will follow it the next time you ask for a release.

This is what makes an agent’s know-how durable. A procedure it worked out once gets written down instead of being rediscovered every session.

Packaging a skill with scripts

A skill can also ship as a small package instead of a single file: a <name>/ directory holding SKILL.md (its entry doc, read exactly like a loose <name>.md) alongside whatever else it needs, typically a scripts/ folder.

~/.pepe/skills/cut-a-release/
  SKILL.md
  scripts/tag-and-push.sh

The bundled files are never copied anywhere: an agent reaches them in place, the same way it already reaches the shared workspace or an installed plugin, by giving run_script (or read_file) a path shaped skills/<name>/scripts/<file>. Point SKILL.md’s own instructions at that path and the script runs exactly as shipped, instead of the agent re-authoring it from scratch on the first request of every session.

A skill installed through manage_skill/mix pepe skill install (below) brings its whole package along automatically when the source has one: a SKILL.md at the root of what’s installed is what marks it as a package; anything without one still installs as a single <name>.md, exactly as before. Every file in a package is security-scanned before install, not just the doc: SKILL.md gets the usual prompt-injection scan, and each bundled script gets the same deep scan a plugin’s code gets.

Installing one from elsewhere

Two paths, depending on where it’s coming from. An agent holding the manage_skill tool uses it for anything the marketplace can resolve: a name in the bundled registry or a tap, or a PepeHub reference (@handle/name, or its page URL), the same registry-aware install mix pepe skill install does, with trust and provenance tracked the same way. For a source with no registry entry at all (a bare URL, a gist, a one-off repo), the install-skill skill teaches an agent to fetch it by hand instead. Either way, skill text from outside is untrusted input: the agent security-scans it with the scan_skill tool before writing it to disk. The scan flags prompt injection, secret exfiltration, destructive commands, persistence and obfuscation. It is a second check, not a substitute for reading the content, and it never installs anything itself.

Installing from a marketplace

manage_skill (above) is the conversational path for anything the registries/PepeHub can resolve. mix pepe skill is the operator path to the exact same registries, with the same search and update story:

pepe skill search release            # search every tap plus the bundled registry
pepe skill install cut-a-release     # install by name
pepe skill install @jhonathas/google-workspace   # or a PepeHub reference (see below)
pepe skill install cut-a-release --source https://example.com/cut-a-release.md   # or directly
pepe skill update cut-a-release      # re-fetch from the exact source it was installed from
pepe skill tap add https://github.com/your-team/pepe-skills   # add a registry beyond the bundled default

A name shaped @handle/name (or the package’s own page URL, copied straight from PepeHub) resolves against PepeHub itself, Pepe’s plugin/skill registry, instead of the bundled registry or a tap. It’s checked first, since no bundled entry or tap uses that shape. It’s installed under the bare package slug (google-workspace, not @jhonathas/google-workspace), the name every other skill command and the skill tool use. Pointing skill install at a name that turns out to be a plugin on PepeHub, not a skill, fails with a clear message telling you to use plugin install instead.

Every install goes through the same static security scan manage_skill/install-skill use; a dangerous verdict is refused unless you pass --force. Trust is "official" for the bundled, in-repo registry (curated by Pepe’s own maintainers) and for a PepeHub package PepeHub itself has manually marked official. Anything resolved through a tap you added, an unmarked PepeHub package, or installed with --source, is "community": when an agent reads it with the skill tool, its content is wrapped in the same untrusted-content marker a fetched web page carries, until you’ve reviewed it yourself.

update is pinned to the exact source a skill was installed from. If a tap’s registry later points that name at a different source, update refuses rather than silently following it. A same-named skill from elsewhere can only replace an installed one via an explicit install --force, never a routine update.

Skills, plugins and scripts

Skills, plugins and scripts work together, and that combination is what lets you ask an agent in plain language for something it cannot do yet.

Combined with plugins and enable_tool, an agent can be told in chat to install a tool that does X. It reads the install-tool skill, writes the plugin to plugins/<name>.exs, enables the tool on itself, and starts calling it, with no restart.

For complex or multi-step work an agent does not grind through it by hand. The run_script tool lets it write a short program (Python, Node, Ruby, Bash or Elixir, and Elixir is always available) and run it, getting back stdout, stderr and the exit code so it can iterate on the errors. Worthwhile scripts are saved under scripts/ and re-run later by passing run_script a file: reference. When the agent works out how to do a recurring task, reading a PDF or crunching a spreadsheet, it writes itself a skill under skills/<name>.md. The write-a-script skill teaches that whole loop.