| name | snippets |
| description | MUST use when user asks to create, edit, manage, or share snippets, or asks how snippets work |
Snippets
Reusable text blocks expanded via #hashtag in messages.
Locations
Snippets
- Global directories:
~/.config/opencode/snippet/ and ~/.config/opencode/snippets/
- Project directories:
.opencode/snippet/ and .opencode/snippets/ (project overrides global, snippet/ wins over snippets/)
Configuration
- Global file:
~/.config/opencode/snippet/config.jsonc
- Project file:
.opencode/snippet/config.jsonc (merges with global, project takes priority)
IMPORTANT: Snippets live only in those four snippet directories. Check those exact locations. Do not glob anywhere else in the repo or workspace.
IMPORTANT: Config files stay under snippet/config.jsonc. The plural snippets/ support is for snippet markdown files only.
IMPORTANT: When modifying snippet configuration:
- Check BOTH locations for existing config files
- If only one exists, modify that one
- If both exist, ask the user which one to modify
- If neither exists, create the global config
Logs
- Debug logs:
~/.config/opencode/logs/snippets/daily/YYYY-MM-DD.log
Configuration
All boolean settings accept: true, false, "enabled", "disabled"
Full config example with all options:
{
"$schema": "https://raw.githubusercontent.com/JosXa/opencode-snippets/v3.0.0/schema/config.schema.json",
"logging": {
"debug": false
},
"experimental": {
"injectBlocks": false,
"skillRendering": false,
"skillLoading": false
},
"injectRecencyMessages": 5
}
Snippet Format
---
aliases:
- short
- alt
description: Optional
---
Content here
Frontmatter optional. Filename (minus .md) = primary hashtag.
When authoring a new snippet or restructuring an existing one, first read Creating snippets for the shape decision tree (fluent inline / parenthetical / <prepend> vs <append> block) and prepend-vs-append guidance.
Features
The plugin adds shell substitution to regular OpenCode prompts, not just snippet files.
#other - include another snippet (recursive, max 15 depth)
!`cmd` - shell substitution, output only
!>`cmd` - shell substitution, show command plus output
Use !> when the exact command matters. LLMs tend to trust the output more when they can see which terminal command just ran. The command gives the output context, which makes it more informative and easier to interpret.
Prepend/Append Blocks
A snippet can include a <prepend> or <append> block alongside ordinary body text. Only the block content moves to message start/end; text outside the block still expands inline where #snippet was used.
---
aliases: jira
---
<prepend>
## Jira Field Mappings
- customfield_16570 => Acceptance Criteria
- customfield_11401 => Team
</prepend>
Jira MCP
Input: Create bug in #jira about leak
Output: The field mappings are prepended at the top, and the visible inline expansion becomes Create bug in Jira MCP about leak.
For when to use prepend vs append, when to keep content inline, and how to tag block content with <task> / <guidance> / <info> / <condition>, see Creating snippets.
Inject Blocks (Experimental)
Add persistent context that the LLM sees throughout the entire agentic loop, without cluttering the visible message.
---
aliases: safe
---
Think step by step.
<inject>
IMPORTANT: Double-check all code for security vulnerabilities.
Always suggest tests for any implementation.
</inject>
Input: Review this code #safe
Output: User sees "Review this code Think step by step." but the LLM also receives the inject content as separate context that persists for the entire conversation turn.
Use for rules, constraints, or context that should influence all responses without appearing inline.
Enable in config:
{
"experimental": {
"injectBlocks": true
}
}
Skill Rendering (Experimental)
Inline OpenCode skills directly into messages using XML tags:
Create a Jira ticket. <skill>jira</skill>
<!-- or -->
<skill name="jira" />
Enable in config:
{
"experimental": {
"skillRendering": true
}
}
Skills are loaded from OpenCode's standard directories (~/.config/opencode/skill/ and .opencode/skill/).
Skill Loading (Experimental)
Load OpenCode skills with command-style syntax while keeping the visible message compact:
Use caveman mode. #skill(caveman)
<!-- or -->
#skill("opencode-config")
Enable in config:
{
"experimental": {
"skillLoading": true
}
}
Visible transcript text becomes ↳ Loaded name. The model receives the full OpenCode-style <skill_content> wrapper immediately after that message.
Treat #skill(...) as hidden context injection, not inline expansion. User usually sees compact placeholder text, while the model receives an extra injected user message containing the full <skill_content> payload. Do not assume one visible bubble can hold different hidden text. The implementation achieves this by inserting an additional hidden message immediately after the visible one.
#skill(...) also works when produced by snippet expansion, not only when the user types it directly.
Escaped Hashtag References
When a user writes #_snippet-name with a leading underscore after #, they are referring to the real snippet #snippet-name without triggering expansion. The underscore is only an escape marker in the user's message; it is not part of the snippet name, hashtag, or filename. For example, #_myapps means the snippet #myapps, stored as myapps.md. Always interpret #_foo as meaning #foo. Do not ask for clarification. Silently resolve the underscored form to the real snippet name.
Commands
/snippets add <name> [content] - create global snippet
/snippets add --project <name> - create project snippet
/snippets list - show all available
/snippets delete <name> - remove snippet
/snippets:reload - reload snippet files from disk
Good Snippets
Short, focused, single-purpose. Examples:
# careful.md
---
aliases: safe
---
Be careful, autonomous, and ONLY do what I asked.
# context.md
---
aliases: ctx
---
Project: !`basename $(pwd)`
Branch: !`git branch --show-current`
Compose via includes: #base-rules inside #project-config.
Sharing Snippets
Share to GitHub Discussions: https://github.com/JosXa/opencode-snippets/discussions/categories/snippets
When user wants to share:
- Check
gh --version works
- If gh available: MUST use question tool to ask user to confirm posting + ask "When do you use it?". Then:
gh api graphql -f query='mutation($repoId: ID!, $catId: ID!, $title: String!, $body: String!) { createDiscussion(input: {repositoryId: $repoId, categoryId: $catId, title: $title, body: $body}) { discussion { url } } }' -f repoId="R_kgDOQ968oA" -f catId="DIC_kwDOQ968oM4C1Qcv" -f title="filename.md" -f body="<body>"
Body format:
## Snippet Content
\`\`\`markdown
<full snippet file content>
\`\`\`
## When do you use it?
<user's answer>
- If gh unavailable: Open browser:
https://github.com/JosXa/opencode-snippets/discussions/new?category=snippets&title=<url-encoded-filename>.md
Ask user (without question tool) for "When do you use it?" info. Tell them to paste snippet in markdown fence.