Skip to content

Namespaces and Skill Priority

What You'll Learn

  • Understand the skill namespace system to distinguish skills with the same name from different sources
  • Master skill discovery priority rules to predict which skill will be loaded
  • Use namespace prefixes to precisely specify skill sources
  • Resolve same-name skill conflicts

Your Current Struggle

As the number of skills grows, you may encounter these challenges:

  • Same-name skill conflicts: Both project directory and user directory have a skill called git-helper, and you don't know which one is being loaded
  • Confusing skill sources: You're unclear which skills come from project-level, user-level, or plugin cache
  • Unpredictable override behavior: You modified a user-level skill but find it not taking effect, overridden by the project-level skill
  • Lack of precise control: You want to force use of a skill from a specific source but don't know how to specify it

These issues stem from misunderstanding the skill namespace and priority rules.

Core Concept

Namespaces are the mechanism OpenCode Agent Skills uses to distinguish same-name skills from different sources. Each skill has a label (label) that identifies its source, and these labels form the skill's namespace.

Why do we need namespaces?

Imagine you have two skills with the same name:

  • Project-level .opencode/skills/git-helper/ (customized for the current project)
  • User-level ~/.config/opencode/skills/git-helper/ (general version)

Without namespaces, the system wouldn't know which one to use. With namespaces, you can explicitly specify:

  • project:git-helper - Force use of the project-level version
  • user:git-helper - Force use of the user-level version

Priority rules ensure that when no namespace is specified, the system can make a reasonable choice. Project-level skills take priority over user-level skills, so you can customize behavior in your projects without affecting global configuration.

Skill Sources and Labels

OpenCode Agent Skills supports multiple skill sources, each with a corresponding label:

SourceLabel (label)PathDescription
OpenCode project-levelproject.opencode/skills/Skills specific to the current project
Claude project-levelclaude-project.claude/skills/Claude Code compatible project skills
OpenCode user-leveluser~/.config/opencode/skills/General skills shared across all projects
Claude user-levelclaude-user~/.claude/skills/Claude Code compatible user skills
Claude plugin cacheclaude-plugins~/.claude/plugins/cache/Installed Claude plugins
Claude plugin marketplaceclaude-plugins~/.claude/plugins/marketplaces/Claude plugins installed from marketplace

Practical Recommendations

  • Project-specific configurations: Put them in .opencode/skills/
  • General utility skills: Put them in ~/.config/opencode/skills/
  • Migrating from Claude Code: No need to move, the system will automatically discover them

Skill Discovery Priority

When the system discovers skills, it scans each location in the following order:

1. .opencode/skills/              (project)        ← Highest priority
2. .claude/skills/                (claude-project)
3. ~/.config/opencode/skills/     (user)
4. ~/.claude/skills/              (claude-user)
5. ~/.claude/plugins/cache/       (claude-plugins)
6. ~/.claude/plugins/marketplaces/ (claude-plugins)  ← Lowest priority

Key rules:

  • First match wins: The first skill found is kept
  • Same-name skill deduplication: Subsequent skills with the same name are ignored (but a warning is issued)
  • Project-level priority: Project-level skills override user-level skills

Priority Example

Suppose you have the following skill distribution:

Project directory:
.opencode/skills/
  └── git-helper/              ← Version A (project customized)

User directory:
~/.config/opencode/skills/
  └── git-helper/              ← Version B (general)

Plugin cache:
~/.claude/plugins/cache/xxx/skills/
  └── git-helper/              ← Version C (Claude plugin)

Result: The system loads Version A (project:git-helper), and the two subsequent same-name skills are ignored.

Specifying Skills with Namespaces

When you call use_skill or other tools, you can use namespace prefixes to precisely specify skill sources.

Syntax Format

namespace:skill-name

or

skill-name  # No namespace specified, use default priority

Namespace List

project:skill-name         # Project-level OpenCode skills
claude-project:skill-name  # Project-level Claude skills
user:skill-name            # User-level OpenCode skills
claude-user:skill-name     # User-level Claude skills
claude-plugins:skill-name  # Claude plugin skills

Usage Examples

Scenario 1: Default loading (by priority)

use_skill("git-helper")
  • The system searches by priority and loads the first matching skill
  • That is, project:git-helper (if it exists)

Scenario 2: Force use of user-level skill

use_skill("user:git-helper")
  • Skips priority rules and directly loads the user-level skill
  • Even if the user-level skill is overridden by a project-level skill, it's still accessible

Scenario 3: Load Claude plugin skill

use_skill("claude-plugins:git-helper")
  • Explicitly loads a skill from a Claude plugin
  • Suitable for scenarios that require specific plugin functionality

Namespace Matching Logic

When using the namespace:skill-name format, the system's matching logic is as follows:

  1. Parse input: Separate the namespace and skill name
  2. Iterate through all skills: Find matching skills
  3. Matching conditions:
    • Skill name matches
    • The skill's label field equals the specified namespace
    • Or the skill's custom namespace field equals the specified namespace
  4. Return result: The first skill that meets the conditions
Matching Logic Source Code
typescript
export function resolveSkill(
  skillName: string,
  skillsByName: Map<string, Skill>
): Skill | null {
  if (skillName.includes(':')) {
    const [namespace, name] = skillName.split(':');
    for (const skill of skillsByName.values()) {
      if (skill.name === name &&
          (skill.label === namespace || skill.namespace === namespace)) {
        return skill;
      }
    }
    return null;
  }
  return skillsByName.get(skillName) || null;
}

Namespaces in Superpowers Mode

When you enable Superpowers mode, the system injects namespace priority instructions during session initialization:

markdown
**Skill namespace priority:**
1. Project: `project:skill-name`
2. Claude project: `claude-project:skill-name`
3. User: `skill-name`
4. Claude user: `claude-user:skill-name`
5. Marketplace: `claude-plugins:skill-name`

The first discovered match wins.

This ensures that the AI follows the correct priority rules when selecting skills.

How to enable Superpowers mode

Set the environment variable:

bash
OPENCODE_AGENT_SKILLS_SUPERPOWERS_MODE=true opencode

Common Use Cases

Scenario 1: Project customization overrides general skills

Requirement: Your project requires a special Git workflow, but there's already a general git-helper skill at the user level.

Solution:

  1. Create .opencode/skills/git-helper/ in the project directory
  2. Configure the project-specific Git workflow
  3. Default calls to use_skill("git-helper") will automatically use the project-level version

Verification:

bash
# Check skill list, note the label
get_available_skills("git-helper")

Example output:

git-helper (project)
  Project-specific Git workflow

Scenario 2: Temporarily switch to general skill

Requirement: A task needs to use the user-level general skill instead of the project-customized version.

Solution:

use_skill("user:git-helper")

Explicitly specify the user: namespace to bypass the project-level override.

Scenario 3: Load skill from Claude plugin

Requirement: You migrated from Claude Code and want to continue using a specific Claude plugin skill.

Solution:

  1. Ensure the Claude plugin cache path is correct: ~/.claude/plugins/cache/
  2. Check the skill list:
get_available_skills()
  1. Load using namespace:
use_skill("claude-plugins:plugin-name")

Common Pitfalls

❌ Mistake 1: Unaware that same-name skills are being overridden

Symptom: You modified a user-level skill, but the AI still uses the old version.

Cause: The project-level same-name skill has higher priority and overrides the user-level skill.

Solution:

  1. Check if there's a same-name skill in the project directory
  2. Use a namespace to force specification: use_skill("user:skill-name")
  3. Or delete the project-level same-name skill

❌ Mistake 2: Misspelled namespace

Symptom: Using use_skill("project:git-helper") returns 404.

Cause: The namespace is misspelled (e.g., projcet) or has incorrect casing.

Solution:

  1. First check the skill list: get_available_skills()
  2. Note the label in parentheses (e.g., (project))
  3. Use the correct namespace name

❌ Mistake 3: Confusing labels and custom namespaces

Symptom: Using use_skill("project:custom-skill") cannot find the skill.

Cause: project is a label, not a custom namespace. Unless the skill's namespace field is explicitly set to project, it won't match.

Solution:

  • Use the skill name directly: use_skill("custom-skill")
  • Or check the skill's label field and use the correct namespace

Summary

The namespace system of OpenCode Agent Skills achieves unified management of skills from multiple sources through labels and priority rules:

  • 5 source labels: project, claude-project, user, claude-user, claude-plugins
  • 6 priority levels: Project-level > Claude project-level > User-level > Claude user-level > Plugin cache > Plugin marketplace
  • First match wins: Same-name skills are loaded by priority, subsequent ones are ignored
  • Namespace prefix: Use the namespace:skill-name format to precisely specify skill sources

This mechanism allows you to enjoy the convenience of automatic discovery while maintaining precise control over skill sources when needed.

Preview: Next Lesson

In the next lesson, we'll learn Context Compaction Resilience.

You will learn:

  • The impact of context compaction on skills
  • How plugins automatically restore skill lists
  • Techniques to keep skills available during long sessions

Appendix: Source Code Reference

Click to expand source code locations

Last updated: 2026-01-24

FunctionFile PathLine
SkillLabel type definitionsrc/skills.ts30
Discovery priority listsrc/skills.ts241-246
---------
resolveSkill namespace handlingsrc/skills.ts269-283
Superpowers namespace instructionssrc/superpowers.ts18-25

Key Types:

  • SkillLabel: Skill source label enum
  • Skill: Skill metadata interface (including namespace and label fields)

Key Functions:

  • discoverAllSkills(): Discover skills by priority with automatic deduplication
  • resolveSkill(): Parse namespace prefix and find skills
  • maybeInjectSuperpowersBootstrap(): Inject namespace priority instructions

Discovery Path List (in priority order):

  1. project - .opencode/skills/
  2. claude-project - .claude/skills/
  3. user - ~/.config/opencode/skills/
  4. claude-user - ~/.claude/skills/
  5. claude-plugins - ~/.claude/plugins/cache/ and ~/.claude/plugins/marketplaces/