MusePi

Skills

English | 中文

Skills are file-backed capability packs discovered at startup and exposed to the model as:

This document covers current runtime behavior in src/extensibility/skills.ts, src/discovery/builtin.ts, src/internal-urls/skill-protocol.ts, and src/discovery/agents-md.ts.

What a skill is in this codebase

A discovered skill is represented as:

The runtime only requires name and path for validity. In practice, matching quality depends on description being meaningful.

Required layout and SKILL.md expectations

Directory layout

For provider-based discovery (native/Claude/Codex/Agents/plugin providers), skills are discovered as one level under skills/:

Nested patterns like <skills-root>/group/<skill>/SKILL.md are not discovered by provider loaders.

For skills.customDirectories, scanning uses the same non-recursive layout (*/SKILL.md).

Provider-discovered layout (non-recursive under skills/):

<root>/skills/
  ├─ postgres/
  │   └─ SKILL.md      ✅ discovered
  ├─ pdf/
  │   └─ SKILL.md      ✅ discovered
  └─ team/
      └─ internal/
          └─ SKILL.md  ❌ not discovered by provider loaders

Custom-directory scanning is also non-recursive, so nested paths are ignored unless you point `customDirectories` at that nested parent.

SKILL.md frontmatter

Supported frontmatter fields on the skill type:

Current runtime behavior:

Discovery pipeline

loadSkills() in src/extensibility/skills.ts does three passes:

  1. Capability providers via loadCapability("skills") (the managed/auto-learn provider’s skills are skipped here and handled in pass 3)
  2. Custom directories via scanSkillsFromDir(..., { requireDescription: true }) (one-level directory enumeration)
  3. Managed (auto-learn) skills (musepi-managed provider) resolved dead-last with first-wins, so any same-named authored skill from any provider or custom directory takes precedence

If skills.enabled is false, discovery returns no skills.

Built-in skill providers and precedence

Provider ordering is priority-first (higher wins), then registration order for ties.

Current registered skill providers:

  1. native (priority 100) — .musepi user/project skills via src/discovery/builtin.ts
  2. omp-plugins (priority 90) — skills/ bundled next to extension packages loaded through extensions:, --extension/-e, or installed plugins under ~/.musepi/plugins/node_modules
  3. claude (priority 80)
  4. priority 70 group (in registration order):
    • claude-plugins
    • agents
    • codex
  5. opencode (priority 55)
  6. github (priority 30) — .github/skills/<name>/SKILL.md (GitHub Agent Skills layout, project-only)
  7. musepi-managed (priority 5) — auto-learn skills under ~/.musepi/agent/managed-skills, registered in src/discovery/builtin.ts and discovered unconditionally (only writing/nudging is gated by autolearn.enabled); always defers to a same-named authored skill

Dedup key is skill name. First item with a given name wins.

Source toggles and filtering

loadSkills() applies these controls:

Filter order is:

  1. not disabled by disabledExtensions
  2. source enabled
  3. not ignored
  4. included (if include list present)

The agents provider (.agent[s]/skills) is the canonical OMP-native location and has its own enableAgentsUser/enableAgentsProject toggles — disabling Claude/Codex/Pi does not turn it off. For providers without a dedicated toggle (claude-plugins, opencode, gemini, github, …), enablement falls back to: enabled if any named source toggle is enabled.

Collision and duplicate handling

Runtime usage behavior

System prompt exposure

System prompt construction (src/system-prompt.ts) uses discovered skills as follows:

hide: true does not disable the skill. Hidden skills are still loaded and remain reachable through skill://<name> and /skill:<name> when skill commands are enabled.

Task tool subagents receive the session’s discovered/provided skills list via normal session creation; there is no per-task skill pinning override.

Interactive /skill:<name> commands

If skills.enableSkillCommands is true, interactive mode registers one slash command per discovered skill.

/skill:<name> [args] behavior:

There is no flag, mode-selector, or frontmatter knob to override this — the keybinding is the choice, identical to how free text is routed during streaming (input-controller.ts:562-568 for Enter, input-controller.ts:961-966 for Ctrl+Enter; both dispatch through #invokeSkillCommand).

skill:// URL behavior

src/internal-urls/skill-protocol.ts supports:

skill:// URL resolution

skill://pdf
  -> <pdf-base>/SKILL.md

skill://pdf/references/tables.md
  -> <pdf-base>/references/tables.md

Guards:
- reject absolute paths
- reject `..` traversal
- reject any resolved path escaping <pdf-base>

Resolution details:

Content type:

No fallback search is performed for missing assets.

Skills vs AGENTS.md, commands, tools, hooks

Skills vs AGENTS.md

src/discovery/agents-md.ts walks ancestor directories from cwd to discover standalone AGENTS.md files. For repositories nested under the user’s home directory, it continues through enclosing workspace directories up to but not including the home directory. With no repository root under home, the home boundary remains included. Otherwise it stops at the repository root, or at the filesystem root when no repository root is known outside home. Files in hidden owner directories are skipped.

Skills vs slash commands

Skills vs custom tools

Skills vs hooks

Practical authoring guidance tied to discovery logic