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.
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
| Layer | Path | Mutability |
|---|---|---|
| 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) |
session-config.mjs:227-240.
SKILL.md format
Standard YAML frontmatter (matches Claude Code’s convention). Body is plain markdown.prompts/skills/email-triage/SKILL.md:1-6.
Frontmatter fields
Required: name, description
Required: name, description
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.Discovery: trigger, commandName
Discovery: trigger, commandName
trigger — pipe-separated phrases that the user typing might match ("check my email|email triage|..."). commandName — override the slash-command name (defaults to name).Ranking: category, priority
Ranking: category, priority
category is workflow (default) or info. priority defaults to 500 (lower = ranked higher in the palette).Visibility: user-invocable, disable-model-invocation
Visibility: user-invocable, disable-model-invocation
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.Execution: allowed-tools, execution
Execution: allowed-tools, execution
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):
additionalSkillPaths: skillsPathsis passed to the loader constructor.await resourceLoader.reload()eagerly reads everySKILL.mdunder those paths.- The budget filter runs immediately as part of
skillsOverride. - Log line:
[pi-session] ResourceLoader: cwd=..., skills=N paths, loaded=M skills, contextFiles=K.
Engine differences
- Claude SDK
- Pi
- 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.jsonregistry - Vault-mode path rewriting: when a vault is active, the symlink farm replaces symlinks with real dirs containing
SKILL.mdfiles whose~/Orion/literals have been rewritten to the active vault root (session-config.mjs:245-260) - Disabled-skills manifest at
{appDataDir}/skill-manifest.jsonexcludes disabled skills from the symlink farm entirely
Bundled skill inventory — what’s there today
43 directories underprompts/skills/ (verified via ls). Categorized by descriptions:
PARA / vault workflow (10)
PARA / vault workflow (10)
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 creation (7)
Content creation (7)
content-writer, transcribe, media-generation, widget-composer, canvas-widget-builder, canvas-patterns, remotion-best-practices — generate text, media, and canvas widgets.Workflow orchestration (5)
Workflow orchestration (5)
workflow-plan, workflow-execute, workflow-lite-plan, workflow-lite-execute, workflow-skill-designer — multi-step plan/execute pipelines.Team / brainstorming (7)
Team / brainstorming (7)
brainstorm, team-brainstorm, team-coordinate, team-designer, team-executor, team-task, team-ultra-analyze — multi-agent collaboration.Agent management (3)
Agent management (3)
create-agent, manage-agent, agent-browser — custom-agent CRUD.Automation (1)
Automation (1)
create-automation — cron / autopilot creation.Meta / skill ops (6)
Meta / skill ops (6)
skill-generator, skill-iter-tune, skill-simplify, skill-tuning, prompt-generator, spec-generator — build and tune skills/prompts.Design / brand (2)
Design / brand (2)
brand-gate-check, design-token-migrate — enforce Orion design system.Onboarding / help (2)
Onboarding / help (2)
onboarding, orion-help — first-time setup, capability discovery.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)
Q1: Pi vault path rewriting
Q1: Pi vault path rewriting
~/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.Q2: Pi disabled-skills enforcement
Q2: Pi disabled-skills enforcement
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.Q3: Plugin skills on Pi
Q3: Plugin skills on Pi
skillsPaths only includes prompts/skills + <vault>/skills — NOT 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.Q4: Lazy vs eager body load
Q4: Lazy vs eager body load
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.Q5: skill-rules.json runtime use
Q5: skill-rules.json runtime use
Invocation paths
| Path | How |
|---|---|
| Model auto-invokes | Claude/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 frontmatter | An agent’s config.yaml can declare skills: [skill-1, skill-2] — those skill names auto-prepend to its system prompt. |
| Tool context auto-detect | Skills marked disable-model-invocation: true are loaded only when a tool callsite specifically requests them. Zero context cost otherwise. |
Key files
src-tauri/sidecar/query/handler.mjs
src-tauri/sidecar/query/handler.mjs
skillsPaths (L2354-2356), passes to Pi session (L2355), cron Pi path (L2623-2633), and subagent dispatch (via tool wiring at L2355 area).src-tauri/sidecar/query/session-config.mjs
src-tauri/sidecar/query/session-config.mjs
ensureSessionConfigDir (L86), disabled-skills check (L108-120), plugin registry walk (L143-212), override semantics (L227-240), vault-mode rewriting (L245-260).src-tauri/sidecar/engine/pi-session.mjs
src-tauri/sidecar/engine/pi-session.mjs
additionalSkillPaths, reload(), budget filter via skillsOverride.src-tauri/sidecar/engine/pi-skills-budget.mjs
src-tauri/sidecar/engine/pi-skills-budget.mjs
src-tauri/sidecar/engine/pi-subagent-runner.mjs
src-tauri/sidecar/engine/pi-subagent-runner.mjs
src-tauri/sidecar/cron/executor.mjs
src-tauri/sidecar/cron/executor.mjs
scripts/generate-skill-registry.mjs
scripts/generate-skill-registry.mjs
src/lib/slash-commands/generated-registry.ts for the palette.prompts/skills/README.md
prompts/skills/README.md