npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-plugin-preload-skills

v1.8.0

Published

Smart skill loading for OpenCode — automatic, contextual, and budget-aware

Readme

opencode-plugin-preload-skills

Smart skill loading for OpenCode — automatic, contextual, and budget-aware

npm version License: MIT GitHub

A powerful plugin for OpenCode that intelligently loads skills based on context — file types, directory patterns, agent type, conversation content, and more.


Features

| Feature | Description | |---------|-------------| | Always-On Skills | Load skills at session start | | File-Type Triggers | Load skills when touching .py, .ts, etc. | | Agent-Specific | Different skills for different agents | | Path Patterns | Glob patterns like src/api/** | | Content Triggers | Keywords in conversation trigger skills | | Skill Groups | Bundle skills together with @group-name | | Conditional Loading | Load only if dependency exists | | Token Budget | Cap total skill tokens to protect context | | Summaries Mode | Load compact summaries instead of full content | | Content Minification | Minify skill content before injection to save tokens | | System Prompt Injection | Inject skills into system prompt instead of messages | | Toast Notifications | Show TUI toast when skills are loaded | | loaded_skills Tool | LLM agent can query loaded skills (also shows toast to user) | | Usage Analytics | Track which skills are actually used |

⚠️ Warning: Preloaded skills consume context window tokens. Use maxTokens to set a budget, useSummaries for large skills, or useMinification to reduce token usage.


Quick Start

1. Add to opencode.json:

{
  "plugin": ["opencode-plugin-preload-skills"]
}

2. Create .opencode/preload-skills.json:

{
  "skills": ["coding-standards"],
  "fileTypeSkills": {
    ".py": ["flask", "python-patterns"],
    ".ts,.tsx": ["typescript-patterns"]
  }
}

3. Create skill files in .opencode/skills/<name>/SKILL.md


Configuration Reference

All Options

{
  "skills": ["always-loaded-skill"],
  "fileTypeSkills": {
    ".py": ["flask"],
    ".ts,.tsx": ["typescript"]
  },
  "agentSkills": {
    "plan": ["planning-skill"],
    "code": ["coding-skill"]
  },
  "pathPatterns": {
    "src/api/**": ["api-design"],
    "src/components/**": ["react-patterns"]
  },
  "contentTriggers": {
    "database": ["sql-patterns"],
    "authentication": ["auth-security"]
  },
  "groups": {
    "frontend": ["react", "css", "testing"],
    "backend": ["api-design", "database"]
  },
  "conditionalSkills": [
    { "skill": "react", "if": { "packageHasDependency": "react" } },
    { "skill": "prisma", "if": { "fileExists": "prisma/schema.prisma" } }
  ],
  "skillSettings": {
    "large-skill": { "useSummary": true },
    "critical-skill": { "useSummary": false }
  },
  "injectionMethod": "systemPrompt",
  "maxTokens": 10000,
  "useSummaries": false,
  "useMinification": false,
  "showToasts": false,
  "enableTools": true,
  "analytics": false,
  "persistAfterCompaction": true,
  "debug": false
}

Options Table

| Option | Type | Default | Description | |--------|------|---------|-------------| | skills | string[] | [] | Always load these skills | | fileTypeSkills | Record<string, string[]> | {} | Map file extensions to skills | | agentSkills | Record<string, string[]> | {} | Map agent names to skills | | pathPatterns | Record<string, string[]> | {} | Map glob patterns to skills | | contentTriggers | Record<string, string[]> | {} | Map keywords to skills | | groups | Record<string, string[]> | {} | Define skill bundles | | conditionalSkills | ConditionalSkill[] | [] | Load if condition met | | skillSettings | Record<string, SkillSettings> | {} | Per-skill settings | | injectionMethod | "chatMessage" \| "systemPrompt" | "systemPrompt" | Where to inject skills | | maxTokens | number | undefined | Max tokens for all skills | | useSummaries | boolean | false | Use skill summaries (global) | | useMinification | boolean \| "standard" \| "aggressive" | false | Minify skill content (true/"standard" or "aggressive") | | showToasts | boolean | false | Show TUI toast notifications when skills are loaded | | enableTools | boolean | true | Register loaded_skills tool for LLM agents | | analytics | boolean | false | Track skill usage | | persistAfterCompaction | boolean | true | Keep skills after compaction | | debug | boolean | false | Enable debug logs |


Feature Details

File-Type Skills

Load skills when agent touches files with specific extensions:

{
  "fileTypeSkills": {
    ".py": ["flask", "python-best-practices"],
    ".ts,.tsx": ["typescript-advanced-types"],
    ".go": ["golang-patterns"]
  }
}

Triggers on: read, edit, write, glob, grep tools.

Agent-Specific Skills

Load different skills for different OpenCode agents:

{
  "agentSkills": {
    "plan": ["architecture-planning", "task-breakdown"],
    "code": ["coding-standards", "testing-patterns"],
    "review": ["code-review-checklist"]
  }
}

Path Patterns

Use glob patterns to match file paths:

{
  "pathPatterns": {
    "src/api/**": ["api-design", "rest-patterns"],
    "src/components/**/*.tsx": ["react-component-patterns"],
    "tests/**": ["testing-best-practices"]
  }
}

Content Triggers

Load skills when keywords appear in conversation:

{
  "contentTriggers": {
    "database": ["sql-patterns", "orm-usage"],
    "authentication": ["auth-security", "jwt-patterns"],
    "performance": ["optimization-tips"]
  }
}

Skill Groups

Bundle related skills and reference with @:

{
  "groups": {
    "frontend": ["react", "css", "accessibility"],
    "backend": ["api-design", "database", "caching"]
  },
  "skills": ["@frontend"]
}

Use @frontend anywhere you'd use a skill name.

Conditional Skills

Load skills only when conditions are met:

{
  "conditionalSkills": [
    {
      "skill": "react-patterns",
      "if": { "packageHasDependency": "react" }
    },
    {
      "skill": "prisma-guide",
      "if": { "fileExists": "prisma/schema.prisma" }
    },
    {
      "skill": "ci-patterns",
      "if": { "envVar": "CI" }
    }
  ]
}

Condition types:

  • packageHasDependency — Check package.json dependencies
  • fileExists — Check if file exists in project
  • envVar — Check if environment variable is set

Token Budget

Limit total tokens to protect your context window:

{
  "maxTokens": 8000,
  "skills": ["skill-a", "skill-b", "skill-c"]
}

Skills load in order until budget is exhausted. Remaining skills are skipped.

Skill Summaries

Add a summary field to your skill frontmatter for compact loading:

---
name: my-skill
description: Full description
summary: Brief one-liner for summary mode
---

Enable with:

{
  "useSummaries": true
}

If no summary field, auto-generates from first paragraph.

Content Minification

Reduce token usage by minifying skill content before injection:

{
  "useMinification": true
}

Minification levels:

| Value | Description | |-------|-------------| | true or "standard" | Standard minification (safe, ~20% reduction) | | "aggressive" | Vercel-style compression (~50%+ reduction) |

Standard minification (true or "standard"):

  • HTML/markdown comments removed
  • Frontmatter stripped
  • Multiple blank lines collapsed
  • Whitespace normalized

Aggressive minification ("aggressive"):

Inspired by Vercel's AGENTS.md research, this mode achieves maximum compression:

{
  "useMinification": "aggressive"
}

Transformations:

  • All standard minification, plus:
  • # Headers[HEADERS] (uppercase, bracketed)
  • **bold** and *italic* → plain text
  • Code blocks → pipe-delimited single line
  • Lists → pipe-delimited (- item|item)
  • Links → text only (URLs removed)
  • Skills wrapped as [SKILL:name]|content|[END]

Example output:

[SKILL:api-patterns]|[API RULES]|MANDATORY: Use REST conventions|Endpoints:|/users|/orders|[END]

Works with both systemPrompt and chatMessage injection methods.

Toast Notifications

Show a TUI toast notification whenever skills are loaded or triggered:

{
  "showToasts": true
}

Toasts appear for:

  • Initial skills — when session-start skills are first injected
  • Triggered skills — when file-type, path, agent, or content triggers load new skills

Each toast displays the skill names and how many were loaded, e.g. Loaded 2 skills: react, typescript or Triggered skill: api-design.

loaded_skills Tool

Registers a custom tool that LLM agents can call to query skill state:

{
  "enableTools": true
}

Enabled by default. When the agent calls loaded_skills, it:

  • Returns a list of all loaded skills with names, descriptions, and token counts
  • Shows a toast notification to the user with the same info (requires showToasts: true)

Ask the agent "what skills are loaded?" and it will use this tool — you'll see the answer both in the conversation and as a toast. Disable with "enableTools": false.

Per-Skill Settings

Override global settings for specific skills:

{
  "useSummaries": false,
  "skillSettings": {
    "large-reference": { "useSummary": true },
    "critical-instructions": { "useSummary": false }
  }
}

Available settings:

  • useSummary — Override global useSummaries for this skill

Priority: skillSettings > useSummaries (global)

This lets you use full content for critical skills while summarizing large reference materials.

Injection Method

Choose where skills are injected:

{
  "injectionMethod": "chatMessage"
}

Methods:

| Method | Description | Use Case | |--------|-------------|----------| | systemPrompt (default) | Injects into system prompt via experimental.chat.system.transform hook | Persistent across all LLM calls, invisible to user | | chatMessage | Injects skills into user messages | One-time injection, visible in conversation |

System prompt injection benefits (default):

  • File-triggered skills available on next LLM step (same turn)
  • Skills persist automatically (no need for persistAfterCompaction)
  • Cleaner conversation history (skills not visible in messages)

Chat message injection benefits:

  • Skills visible in conversation for debugging
  • Works with older OpenCode versions
  • More control over when skills appear

Usage Analytics

Track which skills are loaded and how often:

{
  "analytics": true
}

Saves to .opencode/preload-skills-analytics.json.


Skill File Format

---
name: skill-name
description: Brief description for logs
summary: Optional one-liner for summary mode
---

# Skill Content

Full instructions here...

Locations (in priority order)

  1. .opencode/skills/<name>/SKILL.md (project)
  2. .claude/skills/<name>/SKILL.md (project)
  3. ~/.config/opencode/skills/<name>/SKILL.md (global)
  4. ~/.claude/skills/<name>/SKILL.md (global)

How It Works

┌─────────────────────────────────────────────────────────┐
│                     SESSION START                        │
├─────────────────────────────────────────────────────────┤
│  1. Load `skills` + `conditionalSkills` (if met)        │
│  2. Apply token budget if set                           │
│  3. Inject on first message                             │
├─────────────────────────────────────────────────────────┤
│                   DURING SESSION                         │
├─────────────────────────────────────────────────────────┤
│  On file access:                                         │
│    → Check fileTypeSkills (by extension)                │
│    → Check pathPatterns (by glob match)                 │
│                                                          │
│  On message:                                             │
│    → Check agentSkills (by agent name)                  │
│    → Check contentTriggers (by keyword)                 │
│    → Inject any pending skills                          │
├─────────────────────────────────────────────────────────┤
│                    COMPACTION                            │
├─────────────────────────────────────────────────────────┤
│  All loaded skills added to compaction context          │
│  (if persistAfterCompaction: true)                      │
└─────────────────────────────────────────────────────────┘

Best Practices

  1. Use fileTypeSkills over skills — Only load what's needed
  2. Set maxTokens — Protect your context window
  3. Use groups — Organize related skills
  4. Enable analytics — Find unused skills
  5. Write summary fields — For large skills, enable useSummaries
  6. Enable useMinification — Strip unnecessary whitespace and comments to save tokens

Troubleshooting

| Problem | Solution | |---------|----------| | Skills not loading | Check config path, skill file exists, frontmatter valid | | Wrong skills loading | Check trigger conditions, enable debug: true | | Context too small | Reduce skills, set maxTokens, enable useSummaries or useMinification | | Skills lost after compaction | Ensure persistAfterCompaction: true |


License

MIT