Skills are reusable prompt packages that ship with Orion and can be augmented by user-authored skills in the vault. Each skill is a folder with a SKILL.md file at its root and optional supporting files. The model auto-selects skills based on descriptions; users can also invoke them by name from the slash-command palette.
Orion code does NOT load skills directly. Both engines have their own discovery: Claude SDK via CLAUDE_CONFIG_DIR/skills/ (native), Pi via DefaultResourceLoader with additionalSkillPaths. Orion’s job is to point each engine at the right directories.

Skills on disk — three layers feed two engines

Two layers

LayerPathMutability
Built-in<orionDir>/prompts/skills/Read-only — ships with Orion
User<vault>/.orion/skills/ (or ~/Orion/skills/)User-editable — travels with vault
Plugin (third, optional)<vault>/.orion/plugins/<plugin>/skills/Loaded for Claude SDK only (see open question below)
Override semantics: vault wins on slug collision. Layer order at the SDK symlink farm: built-in → plugin → user. Each later layer overrides earlier. ✓ VERIFIED at session-config.mjs:227-240.
// handler.mjs:2354-2356 — ✓ VERIFIED
const promptsDir = join(orionDir, "prompts");
const skillsPaths = [join(promptsDir, "skills")];
if (orionHome) skillsPaths.push(join(orionHome, "skills"));

SKILL.md format

Standard YAML frontmatter (matches Claude Code’s convention). Body is plain markdown.
---
name: email-triage
description: "Scan and process unread emails. Scores by priority, classifies, saves relevant emails as vault notes, and generates a triage report."
trigger: "check my email|email triage|process emails|anything urgent in email"
allowed-tools: Bash, Read, Write, AskUserQuestion, Glob
---

# Email Triage

Scan the email inbox (Gmail), score emails by priority, classify them, save relevant ones as structured vault notes, and generate a triage report.

---

## Security: External Content -- MANDATORY
...
✓ VERIFIED from real bundled skill at prompts/skills/email-triage/SKILL.md:1-6.

Frontmatter fields

name is the skill slug (defaults to the directory name). description is the discovery signal — its first line is what the model uses to decide whether to auto-invoke this skill.
trigger — pipe-separated phrases that the user typing might match ("check my email|email triage|..."). commandName — override the slash-command name (defaults to name).
category is workflow (default) or info. priority defaults to 500 (lower = ranked higher in the palette).
user-invocable: false → hidden from the palette (model-only auto-invoke). disable-model-invocation: true → palette-only, zero context cost because not even the name reaches the model context.
allowed-tools — SDK-native tool allowlist (e.g. Bash, Read, Write, AskUserQuestion, Glob). Limits which tools the skill body can use when invoked. execution: sdk is the only documented value.

How the model sees skills

Per-query resolution

Loading lifecycle

Skills setup runs per query, at session-config-dir construction time (handler.mjs:1535-1538). A process-local cache (_createdSessionDirs Set in session-config.mjs:60) short-circuits if the same conversationId already built its dir this process — so in practice it’s first turn of a conversation in a given sidecar lifetime. For Pi specifically, a new DefaultResourceLoader is constructed per session creation (pi-session.mjs:467-481):
  1. additionalSkillPaths: skillsPaths is passed to the loader constructor.
  2. await resourceLoader.reload() eagerly reads every SKILL.md under those paths.
  3. The budget filter runs immediately as part of skillsOverride.
  4. Log line: [pi-session] ResourceLoader: cwd=..., skills=N paths, loaded=M skills, contextFiles=K.

Engine differences

  • Native discovery from CLAUDE_CONFIG_DIR/skills/ (which points at the per-session symlink farm)
  • No budget cap — SDK does progressive disclosure (skill bodies loaded on demand)
  • Plugin skills symlinked from installed_plugins.json registry
  • Vault-mode path rewriting: when a vault is active, the symlink farm replaces symlinks with real dirs containing SKILL.md files whose ~/Orion/ literals have been rewritten to the active vault root (session-config.mjs:245-260)
  • Disabled-skills manifest at {appDataDir}/skill-manifest.json excludes disabled skills from the symlink farm entirely

Bundled skill inventory — what’s there today

43 directories under prompts/skills/ (verified via ls). Categorized by descriptions:
email-triage, inbox-triage, tag-garden, vault-audit, task-manage, weekly-agenda, meeting-prep, deadline-radar, memory-capture, memory-manage — day-to-day operations on the user’s vault.
content-writer, transcribe, media-generation, widget-composer, canvas-widget-builder, canvas-patterns, remotion-best-practices — generate text, media, and canvas widgets.
workflow-plan, workflow-execute, workflow-lite-plan, workflow-lite-execute, workflow-skill-designer — multi-step plan/execute pipelines.
brainstorm, team-brainstorm, team-coordinate, team-designer, team-executor, team-task, team-ultra-analyze — multi-agent collaboration.
create-agent, manage-agent, agent-browser — custom-agent CRUD.
create-automation — cron / autopilot creation.
skill-generator, skill-iter-tune, skill-simplify, skill-tuning, prompt-generator, spec-generator — build and tune skills/prompts.
brand-gate-check, design-token-migrate — enforce Orion design system.
onboarding, orion-help — first-time setup, capability discovery.
Documentation drift: CLAUDE.md says “~70 skill directories,” and another rule file says “~100 skill dirs.” Actual count today is 43. Likely the older docs were written when an earlier set of skills existed.

Open questions (potential gaps)

The SDK symlink farm rewrites ~/Orion/ literals in skill bodies for vault-mode. Pi reads the same source files directly via additionalSkillPaths — does Pi see un-rewritten paths? ✗ UNCERTAIN. Likely impact: skill bodies that reference ~/Orion/<file> may resolve incorrectly on Pi in vault mode.
skill-manifest.json filtering happens only at the SDK symlink-farm stage. Pi reads prompts/skills/ directly, so disabled skills likely leak into Pi sessions. ✗ UNCERTAIN — needs a code trace to confirm.
skillsPaths only includes prompts/skills + <vault>/skillsNOT plugin paths. The plugin registry walk in session-config.mjs:143-212 only produces SDK symlinks. ? INFERRED bug: plugin skills may be Claude-SDK-only.
The pi-skills-budget.mjs:9 docstring claims “Pi’s DefaultResourceLoader loads ALL skills” — unclear whether that means all metadata or all bodies. The SDK path is “progressive disclosure” (lazy body load) per the same comment. ✗ UNCERTAIN.
README says “NOT consumed by Orion runtime” — but a structured file with trigger keywords is suspicious. Worth confirming no code path reads it at query time.

Invocation paths

PathHow
Model auto-invokesClaude/Pi sees skill names + descriptions in system prompt; selects based on description match. Loads body on selection.
User slash command/email-triage from the auto-generated palette (src/lib/slash-commands/generated-registry.ts, build-time generated).
Agent skills frontmatterAn agent’s config.yaml can declare skills: [skill-1, skill-2] — those skill names auto-prepend to its system prompt.
Tool context auto-detectSkills marked disable-model-invocation: true are loaded only when a tool callsite specifically requests them. Zero context cost otherwise.

Key files

Computes skillsPaths (L2354-2356), passes to Pi session (L2355), cron Pi path (L2623-2633), and subagent dispatch (via tool wiring at L2355 area).
The symlink-farm-er. ensureSessionConfigDir (L86), disabled-skills check (L108-120), plugin registry walk (L143-212), override semantics (L227-240), vault-mode rewriting (L245-260).
Pi-side ResourceLoader wiring (L467-485). additionalSkillPaths, reload(), budget filter via skillsOverride.
The Pi-only budget filter. 12K raw chars cap. Project-local-first sort. Two-pass full → compact format fallback.
Subagent skillsPaths inheritance (L422).
Cron Pi path skillsPaths forwarding (L646, L656-668).
Build-time scanner emits src/lib/slash-commands/generated-registry.ts for the palette.
Frontmatter schema documentation, layered-architecture overview.

Next

Agents

How agents (folder-per-agent + config.yaml) consume skills via frontmatter.

Hooks

Hooks vs skills — when does each fire?