# Create and install skills

> Author a skill package with skill-creator, required SKILL.md fields, Python package layout, and load-path verification.

- Repository: PrimeIntellect-ai/prime-agent
- GitHub: https://github.com/PrimeIntellect-ai/prime-agent
- Human docs: https://grok-wiki.com/public/docs/primeintellect-ai-prime-agent-3367c32760b1
- Complete Markdown: https://grok-wiki.com/public/docs/primeintellect-ai-prime-agent-3367c32760b1/llms-full.txt

## Source Files

- `packages/coding-agent/skills/skill-creator/SKILL.md`
- `packages/coding-agent/examples/sdk/04-skills.ts`
- `packages/coding-agent/test/fixtures/skills/python-skill/SKILL.md`
- `packages/coding-agent/test/fixtures/skills/python-skill/src/python_skill/__init__.py`
- `packages/coding-agent/test/fixtures/skills/missing-description/SKILL.md`
- `packages/coding-agent/skills/goal/SKILL.md`

---

---
title: "Create and install skills"
description: "Author a skill package with skill-creator, required SKILL.md fields, Python package layout, and load-path verification."
---

Prime Agent skills are directories that contain a required `SKILL.md` (YAML frontmatter plus markdown instructions). At startup the agent loads only each skill’s `name` and `description` into the system prompt; the full body loads on demand when a task matches. Prime Agent follows the [Agent Skills standard](https://agentskills.io/specification) and extends it with Python-backed skills callable from the persistent IPython kernel. The built-in `skill-creator` skill is the authoring contract for both kinds.

## Skill kinds

| Kind | Surface | Use when |
|---|---|---|
| `markdown` | `SKILL.md` plus optional `scripts/`, `references/`, and `assets/` | Workflows, CLI recipes, domain knowledge, multi-step instructions |
| `python` | A markdown skill that also ships a Python package installed into the agent’s persistent IPython kernel | Capabilities that are naturally one Python call (`await my_skill(...)`): API wrappers, fetchers, converters, computations |

Default to markdown. Choose Python only when the agent should call a capability from IPython instead of following instruction text.

## Install locations

Pick one install root when the scope is not already fixed by the repo or product surface:

| Scope | Path | Shared how |
|---|---|---|
| Project | `.prime/agent/skills/<name>/` | Checked into the repository |
| Personal (global) | `~/.prime/agent/skills/<name>/` | Local to the user agent directory |
| npm package | package `skills/` directory, or `pi.skills` paths in that package’s `package.json` | Shipped with a package |

`<name>` must match the skill frontmatter `name` and the parent directory name.

The SDK resource loader discovers skills from project and agent skill trees (example discovery comment: `cwd/.pi/skills`, `~/.pi/agent/skills`, and related roots). Prefer the `.prime/agent/skills` locations when authoring or installing for Prime Agent via `skill-creator`.

### Name collision precedence

On a name collision, the first skill found wins:

1. Explicit `--skill` paths and `skills` settings entries
2. Project skills
3. Global skills
4. Package skills
5. Built-in skills

## Create a skill

<Steps>
<Step title="Choose kind and location">
Use markdown unless the agent must call the capability as Python (`await my_skill(...)`). Place the directory under project, personal, or package skill roots from the table above.
</Step>
<Step title="Scaffold the directory">
Create `<name>/SKILL.md`. Optionally add `scripts/`, `references/`, and `assets/`. Everything except `SKILL.md` is freeform.
</Step>
<Step title="Write frontmatter and body">
Set required `name` and `description`. Keep the body short (decision flow, common commands, contract). Put long reference material in `references/*.md` and link it.
</Step>
<Step title="Verify load">
Confirm frontmatter rules, reload the session, check diagnostics/warnings, and invoke `/skill:<name>`. For Python-backed skills, also follow the package checks documented in `skill-creator`’s `references/python-skills.md`.
</Step>
</Steps>

## Directory layout

:::files
my-skill/
├── SKILL.md              # Required: frontmatter + instructions
├── scripts/              # Optional helper scripts the instructions reference
├── references/           # Optional detailed docs, loaded only when needed
└── assets/               # Optional templates and data files
:::

Reference files with paths relative to the skill directory. The agent resolves them against the directory that contains `SKILL.md`.

### Python package fixture layout

A Python-backed skill keeps the same `SKILL.md` root and ships importable code under `src/`:

:::files
python-skill/
├── SKILL.md
└── src/
    └── python_skill/
        └── __init__.py
:::

The test fixture exports an async entrypoint:

```python
# src/python_skill/__init__.py
async def run(value: str = "ok") -> str:
    """Return the provided value."""
    return value
```

Its `SKILL.md` points callers at the import name:

```markdown
---
name: python-skill
description: A Python-backed skill for testing.
---

# Python Skill

Use the `python_skill` import.
```

<Note>
`skill-creator` requires reading `references/python-skills.md` for the full Python package contract before authoring production Python skills. That package-contract detail is not duplicated here.
</Note>

## SKILL.md frontmatter

```markdown
---
name: my-skill
description: What this skill does and when to use it. Be specific.
---
```

| Field | Required | Rules |
|---|---|---|
| `name` | Yes | Max 64 chars. Lowercase `a-z`, `0-9`, hyphens. No leading, trailing, or consecutive hyphens. Must match the parent directory name. |
| `description` | Yes | Max 1024 chars. Missing or empty description → skill is **silently not loaded**. |
| `disable-model-invocation` | No | `true` hides the skill from the system prompt; only explicit `/skill:<name>` invokes it. |
| `license` | No | License name or reference to a bundled file. |
| `compatibility` | No | Max 500 chars. Environment requirements. |
| `metadata` | No | Arbitrary key-value mapping. |
| `allowed-tools` | No | Space-delimited pre-approved tools (experimental). |

Unknown fields are ignored. Name rule violations produce warnings; the skill still loads (when `description` is present and non-empty).

### Description routing

The description is the only text the model sees before deciding to load the skill. State what the skill does and the trigger conditions (`Use when ...`), naming concrete tasks, tools, and request phrases.

| Quality | Example |
|---|---|
| Good | `Extracts text and tables from PDF files, fills PDF forms, and merges PDFs. Use when working with PDF documents.` |
| Poor | `Helps with PDFs.` |

Built-in examples of routing-ready descriptions:

- `skill-creator`: create, validate, and install markdown and Python skills; use when the user asks to create a skill, turn a workflow/script/prompt into a skill, add a Python skill, or asks how to write `SKILL.md` and where skills live.
- `goal`: manage the persistent thread goal from IPython; use to read status/budget, start a goal when explicitly requested, or mark the active goal complete.

### Body progressive disclosure

Keep `SKILL.md` short: decision flow, common commands, and contract. Push API schemas, full option lists, and long examples into `references/*.md` and link them so they enter context only when needed. State setup steps (installs, env vars, credentials) explicitly and early.

## Load path and session verification

After writing the skill:

1. Re-read frontmatter against the field table, especially `name` matching the directory and a non-empty `description`.
2. In an interactive session, run `/reload` to pick up new skills without restart. Other sessions load skills on start.
3. Loading problems (bad name, missing description, name collisions) surface as warnings/diagnostics.
4. Invoke the skill with `/skill:<name>`.
5. For Python-backed skills, run the additional checks from `skill-creator` → `references/python-skills.md`.

<Check>
Success signals: skill appears in discovery, no fatal diagnostics for that skill, and `/skill:<name>` invokes the body. Missing/empty `description` does not load at all (silent skip).
</Check>

### Missing description (silent skip)

This fixture is not loaded because `description` is absent:

```markdown
---
name: missing-description
---

# Missing Description

This skill has no description field.
```

## SDK: discover, filter, and inject skills

Programmatic sessions use `DefaultResourceLoader` from `@earendil-works/pi-coding-agent`. Skills can be discovered, filtered, merged, or replaced through `skillsOverride`.

```ts
import {
  createAgentSession,
  createSyntheticSourceInfo,
  DefaultResourceLoader,
  getAgentDir,
  SessionManager,
  type Skill,
} from "@earendil-works/pi-coding-agent";

const customSkill: Skill = {
  name: "my-skill",
  description: "Custom project instructions",
  filePath: "/virtual/SKILL.md",
  baseDir: "/virtual",
  sourceInfo: createSyntheticSourceInfo("/virtual/SKILL.md", { source: "sdk" }),
  disableModelInvocation: false,
  kind: "markdown",
};

const loader = new DefaultResourceLoader({
  cwd: process.cwd(),
  agentDir: getAgentDir(),
  skillsOverride: (current) => {
    const filteredSkills = current.skills.filter(
      (s) => s.name.includes("browser") || s.name.includes("search"),
    );
    return {
      skills: [...filteredSkills, customSkill],
      diagnostics: current.diagnostics,
    };
  },
});

await loader.reload();
const { skills: allSkills, diagnostics } = loader.getSkills();

await createAgentSession({
  resourceLoader: loader,
  sessionManager: SessionManager.inMemory(),
});
```

### `Skill` object fields (SDK)

| Field | Role |
|---|---|
| `name` | Skill identifier |
| `description` | Routing text |
| `filePath` | Path to `SKILL.md` (may be virtual for synthetic skills) |
| `baseDir` | Skill base directory for relative resolution |
| `sourceInfo` | Provenance via `createSyntheticSourceInfo(...)` (example uses `{ source: "sdk" }`) |
| `disableModelInvocation` | When true, hide from model-driven invocation |
| `kind` | e.g. `"markdown"` |

### Loader APIs

| API | Behavior |
|---|---|
| `new DefaultResourceLoader({ cwd, agentDir, skillsOverride })` | Construct loader with optional skill transform |
| `await loader.reload()` | Reload resources, including skills |
| `loader.getSkills()` | Returns `{ skills, diagnostics }` |

Inspect `diagnostics` after reload for load warnings (name issues, collisions, and related problems).

## Troubleshooting

| Symptom | Cause | Action |
|---|---|---|
| Skill never appears | Missing or empty `description` | Add a non-empty `description` (max 1024 chars). Silent non-load. |
| Warning on load, skill still present | `name` rule violation | Fix casing, length, hyphens, or directory match. Name violations warn but still load. |
| Unexpected skill content | Name collision | First match wins; check `--skill` / settings, then project → global → package → built-in. |
| New skill not visible in open session | Session started before install | Run `/reload`, or start a new session. |
| Python skill docs incomplete locally | Package contract not followed | Use `skill-creator` and complete checks in `references/python-skills.md`. |
| SDK session missing expected skills | Override filtered them out | Inspect `skillsOverride` and `diagnostics` from `getSkills()`. |

## Related pages

<CardGroup>
<Card title="Skills model" href="/skills-model">
Skills as importable packages, frontmatter constraints, collision precedence, and project vs personal scope.
</Card>
<Card title="Built-in skills reference" href="/builtin-skills">
Catalog of shipped skills (`goal`, `refine`, `compact`, and others) with entry modules and roles.
</Card>
<Card title="Skills, tools, and extensions (SDK)" href="/sdk-skills-tools-extensions">
SDK recipes for loading skills, registering tools, extensions, and related session wiring.
</Card>
<Card title="RLM control plane" href="/rlm-control-plane">
Persistent IPython as the control tool and how Python-callable skills fit agent execution.
</Card>
<Card title="Continual Harness" href="/continual-harness">
Durable harness state including skill specs, refine boundaries, and rollback snapshots.
</Card>
</CardGroup>
