skills.mdx 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. ---
  2. title: "Skills"
  3. description: ""
  4. ---
  5. Skills are Markdown instructions that OpenCode can advertise to an agent and
  6. load when they are relevant. A skill can include supporting scripts,
  7. references, and other files in the same directory.
  8. ## Create a skill
  9. Create one directory per skill with a `SKILL.md` file:
  10. ```text
  11. .opencode/skills/
  12. └── git-release/
  13. ├── SKILL.md
  14. ├── scripts/
  15. │ └── changelog.ts
  16. └── references/
  17. └── release-policy.md
  18. ```
  19. ```markdown title=".opencode/skills/git-release/SKILL.md"
  20. ---
  21. name: Git Release
  22. description: Prepare release notes, version bumps, and GitHub releases
  23. metadata:
  24. opencode/slash: "true"
  25. ---
  26. ## Workflow
  27. 1. Read `references/release-policy.md`.
  28. 2. Summarize merged changes since the previous tag.
  29. 3. Propose the version bump before changing files.
  30. 4. Run `scripts/changelog.ts` only after the user approves the version.
  31. ```
  32. Paths in a skill are relative to the directory containing `SKILL.md`.
  33. ## Discovery
  34. OpenCode automatically adds the following source directories:
  35. | Scope | Sources |
  36. | --- | --- |
  37. | Global | `~/.config/opencode/skills` |
  38. | Global compatibility | `~/.claude/skills`, `~/.agents/skills` |
  39. | Project | `.opencode/skills` |
  40. | Project compatibility | `.claude/skills`, `.agents/skills` |
  41. For project sources, OpenCode searches from the current directory upward to
  42. the project root and includes matching directories at every level.
  43. Within each source directory, OpenCode discovers:
  44. - Markdown files at the source root, such as `skills/git-release.md`
  45. - `SKILL.md` files at any depth, such as `skills/git-release/SKILL.md`
  46. The directory form is recommended because it gives the skill a private base
  47. directory for supporting files.
  48. ## Configure sources
  49. Use the `skills` array in any `opencode.json` or `opencode.jsonc` to add local
  50. directories or HTTP catalogs:
  51. ```jsonc title="opencode.jsonc"
  52. {
  53. "$schema": "https://opencode.ai/config.json",
  54. "skills": [
  55. "./team-skills",
  56. "~/shared/opencode-skills",
  57. "/opt/company-skills",
  58. "https://example.com/opencode/skills/"
  59. ]
  60. }
  61. ```
  62. Relative paths are resolved from the active OpenCode working directory, not
  63. from the directory containing the config file. Paths beginning with `~/` use
  64. the current user's home directory. Only `http://` and `https://` values are
  65. treated as URL sources.
  66. Every discovered config document contributes its `skills` entries; the arrays
  67. are additive rather than replacing one another.
  68. ### HTTP catalogs
  69. An HTTP source is a base URL containing an `index.json`:
  70. ```json title="index.json"
  71. {
  72. "skills": [
  73. {
  74. "name": "git-release",
  75. "version": "3",
  76. "files": [
  77. "git-release.md",
  78. "references/release-policy.md"
  79. ]
  80. }
  81. ]
  82. }
  83. ```
  84. OpenCode downloads those files from
  85. `<base-url>/git-release/<file>`. File paths must be safe, relative,
  86. same-origin paths. Each entry must include either `SKILL.md` or a Markdown file
  87. named after the index entry, such as `git-release.md`.
  88. Use the named Markdown form for HTTP catalogs. Each downloaded skill directory
  89. is itself a source root, so `git-release.md` produces the ID `git-release`; a
  90. root-level `SKILL.md` produces the literal ID `SKILL` in the current V2
  91. implementation. Increment `version` when files change so OpenCode refreshes
  92. the cached copy.
  93. ## Frontmatter
  94. V2 reads these fields:
  95. | Field | Purpose |
  96. | --- | --- |
  97. | `name` | Display name; defaults to the path-derived ID |
  98. | `description` | Summary shown to the model and command catalog |
  99. | `slash` | Set to `false` to hide the skill from the V2 slash-command catalog |
  100. | `metadata.opencode/slash` | Boolean or `"true"`/`"false"`; overrides `slash` |
  101. | `metadata.opencode/autoinvoke` | Set to `false` to omit the skill from model-facing discovery |
  102. Frontmatter, `name`, and `description` are optional at runtime. However, a
  103. clear `description` is strongly recommended: skills without one are not
  104. advertised to the model. `license`, `compatibility`, and other metadata may be
  105. included for portability, but V2 does not interpret them.
  106. `opencode/autoinvoke: false` only removes the skill from the model's available
  107. skills list. The skill remains registered and can still be activated explicitly
  108. by its ID.
  109. ## IDs and validation
  110. The skill ID comes from its path, not its frontmatter:
  111. | File | ID |
  112. | --- | --- |
  113. | `<source>/git-release.md` | `git-release` |
  114. | `<source>/git-release/SKILL.md` | `git-release` |
  115. | `<source>/teams/release/SKILL.md` | `release` |
  116. IDs are exact and case-sensitive. V2 currently does not enforce the Agent
  117. Skills name regex, length limits, a match between `name` and the directory, or
  118. a maximum description length. The frontmatter `name` is only a display label.
  119. For portable, predictable skills, use a unique lowercase kebab-case ID of 1-64
  120. characters and keep it aligned with the directory name:
  121. ```text
  122. ^[a-z0-9]+(-[a-z0-9]+)*$
  123. ```
  124. ## Precedence
  125. Skills are keyed by ID. If several sources define the same ID, the later source
  126. wins. Sources are registered in this order, from lower to higher precedence:
  127. 1. Built-in skills
  128. 2. `.claude/skills` sources, global first and then from the current directory upward
  129. 3. `.agents/skills` sources, global first and then from the current directory upward
  130. 4. `~/.config/opencode/skills`
  131. 5. Project `.opencode/skills`, from the project root toward the current directory
  132. 6. Explicit `skills` config entries, in config priority and array order
  133. Avoid duplicate IDs unless an override is intentional.
  134. ## Runtime loading
  135. At each model step, OpenCode advertises permitted skills that have a
  136. description and do not set `opencode/autoinvoke` to `false`. The advertisement
  137. contains only each skill's ID, name, and description; it does not add every
  138. skill body to the prompt.
  139. When the model calls the `skill` tool with an exact ID, OpenCode:
  140. 1. Resolves the current winning definition for that ID
  141. 2. Checks the `skill` permission for the selected agent
  142. 3. Adds the Markdown body, without frontmatter, to the conversation
  143. 4. Provides the skill's base directory and a sample of up to ten supporting file paths
  144. Supporting file contents are not loaded automatically. The agent can read a
  145. referenced file when the skill instructs it to do so. The supporting-file
  146. sample is available for directory-based `SKILL.md` skills; flat Markdown skills
  147. receive no neighboring file list.
  148. In the V2 CLI, skills appear as `/id` commands unless `slash` resolves to
  149. `false`. Selecting one appends the skill body as a skill message and resumes
  150. the session.
  151. ## Permissions
  152. Permission rules use the `skill` action and the skill ID as the resource. Rules
  153. are evaluated in order, with the last matching rule winning:
  154. ```jsonc title="opencode.jsonc"
  155. {
  156. "permissions": [
  157. { "action": "skill", "resource": "*", "effect": "allow" },
  158. { "action": "skill", "resource": "internal-*", "effect": "deny" },
  159. { "action": "skill", "resource": "experimental-*", "effect": "ask" }
  160. ]
  161. }
  162. ```
  163. `deny` removes matching skills from model-facing discovery and rejects skill
  164. tool loading. `ask` advertises the skill but requests approval when the model
  165. loads it. The same rules can be placed under an individual
  166. `agents.<id>.permissions` array.
  167. ## Troubleshooting
  168. If a skill is missing or loads the wrong content:
  169. 1. Confirm the file is either a root-level `*.md` or a nested file named exactly `SKILL.md`.
  170. 2. Check the path-derived ID rather than the frontmatter `name`.
  171. 3. Add a `description` if the skill should be advertised to the model.
  172. 4. Check `opencode/autoinvoke` and the selected agent's `skill` permissions.
  173. 5. Look for a later source defining the same ID.
  174. 6. For HTTP catalogs, verify `index.json`, same-origin file paths, and a changed `version`.