Version: 1.1 Status: Stable
This document defines the syntax and semantics of the triggers field in SKILL.md frontmatter. Triggers are advisory hints that help agents decide when to activate a skill.
The triggers field is an optional list of strings in the YAML frontmatter. Each string describes a condition under which the skill is relevant. When any trigger matches the current context, the agent may activate the skill.
---
name: testing-patterns
description: Patterns for writing effective tests across frameworks.
triggers:
- user-asks-about-testing
- project-has-jest-config-js
- file-type:*.test.ts
- command:test
- context:debugging
---
Triggers use OR logic: if any single trigger matches, the skill is considered relevant. An agent is not required to activate a skill just because a trigger matches – triggers are one input among potentially many heuristics.
There are five trigger types. Each is identified by its prefix or structure.
user-asks-about-<topic>Matches when the user’s message contains keywords related to the topic.
Syntax:
user-asks-about-<topic>
Where <topic> is a lowercase, hyphen-separated keyword phrase.
Regex:
^user-asks-about-[a-z0-9]+(-[a-z0-9]+)*$
Semantics: The agent should match the topic against the user’s input using keyword or semantic similarity. The topic string is not a literal substring match; it is a hint. For example, user-asks-about-api-design should match user messages like “how should I structure my REST endpoints” even though the exact phrase “api design” does not appear.
Examples:
triggers:
- user-asks-about-testing
- user-asks-about-mcp-servers
- user-asks-about-resume-writing
- user-asks-about-git-workflow
project-has-<pattern>Matches when the project workspace contains a file or directory matching the pattern.
Syntax:
project-has-<filename-pattern>
Where <filename-pattern> is a lowercase, hyphen-separated representation of a filename. Dots in filenames are replaced with hyphens in the trigger string.
Regex:
^project-has-[a-z0-9]+(-[a-z0-9]+)*$
Semantics: The agent checks whether the project root (or workspace) contains the referenced file. The filename is reconstructed from the pattern by converting hyphens back to dots where appropriate. Agents should use reasonable heuristics for this reconstruction:
| Trigger | Expected file |
|---|---|
project-has-package-json |
package.json |
project-has-dockerfile |
Dockerfile |
project-has-pyproject-toml |
pyproject.toml |
project-has-jest-config-js |
jest.config.js |
project-has-openapi-yaml |
openapi.yaml |
project-has-cargo-toml |
Cargo.toml |
project-has-makefile |
Makefile |
Examples:
# Activate for Node.js projects
triggers:
- project-has-package-json
# Activate for Python projects
triggers:
- project-has-pyproject-toml
- project-has-setup-py
# Activate for containerized projects
triggers:
- project-has-dockerfile
- project-has-docker-compose-yml
file-type:<glob>Matches when the user is working with a file whose path matches the glob pattern.
Syntax:
file-type:<glob-pattern>
Where <glob-pattern> is a standard file glob using * and ** wildcards.
Regex:
^file-type:[^\s]+$
Semantics: The agent evaluates the glob against the currently active file, recently mentioned files, or files the user is asking about. The glob follows standard rules: * matches any characters except path separators, ** matches across directories.
Examples:
# Activate for test files
triggers:
- file-type:*.test.ts
- file-type:*.test.js
- file-type:*.spec.py
# Activate for configuration files
triggers:
- file-type:*.config.ts
- file-type:*.config.js
# Activate for specific directories
triggers:
- file-type:migrations/*.sql
- file-type:**/templates/*.html
command:<command>Matches when the user invokes a slash command or explicit action keyword.
Syntax:
command:<command-name>
Where <command-name> is a lowercase alphanumeric string with optional hyphens.
Regex:
^command:[a-z0-9]+(-[a-z0-9]+)*$
Semantics: The agent matches this trigger when the user types a slash command (e.g., /test, /deploy) or uses an equivalent invocation. The command name does not include the leading slash.
Examples:
# Activate on /test command
triggers:
- command:test
# Activate on deployment commands
triggers:
- command:deploy
- command:release
# Activate on documentation commands
triggers:
- command:docs
- command:readme
context:<keyword>Matches when the conversation context suggests a particular activity or phase.
Syntax:
context:<keyword>
Where <keyword> is a lowercase alphanumeric string with optional hyphens.
Regex:
^context:[a-z0-9]+(-[a-z0-9]+)*$
Semantics: Context triggers match against the inferred state of the conversation rather than a single message. The agent determines context from the recent conversation history, the type of work being done, or explicit mode indicators. Common contexts include phases of development, problem-solving activities, or workflow stages.
Examples:
# Activate during debugging sessions
triggers:
- context:debugging
- context:troubleshooting
# Activate during code review
triggers:
- context:code-review
- context:refactoring
# Activate during planning phases
triggers:
- context:architecture
- context:design-review
user-asks-about triggers, agents should use semantic or fuzzy matching, not exact substring matching.Triggers do not define a priority order. If an agent needs to choose between multiple matching skills, it should consider:
file-type:*.test.ts match is more specific than user-asks-about-testing).If a skill has no triggers field (or an empty list), the agent falls back to matching based on the name, description, and tags fields. Skills without triggers are not excluded from activation.
---
name: testing-patterns
description: >
Patterns and strategies for writing effective tests including unit tests,
integration tests, and end-to-end tests. Use when writing or improving tests.
license: MIT
complexity: intermediate
tags:
- testing
- tdd
- jest
- pytest
triggers:
- user-asks-about-testing
- user-asks-about-tdd
- project-has-jest-config-js
- project-has-pytest-ini
- file-type:*.test.ts
- file-type:*.test.js
- file-type:*.spec.py
- file-type:*_test.go
- command:test
- context:debugging
---
---
name: deployment-cicd
description: >
CI/CD pipeline patterns and deployment strategies for production systems.
Use when setting up or improving deployment workflows.
license: MIT
complexity: advanced
tags:
- deployment
- cicd
- github-actions
- docker
triggers:
- user-asks-about-deployment
- user-asks-about-cicd
- project-has-dockerfile
- project-has-docker-compose-yml
- file-type:.github/workflows/*.yml
- command:deploy
- command:release
- context:deployment
---
---
name: canvas-design
description: >
Create visual designs using HTML Canvas API with a curated font library.
Use when generating illustrations, diagrams, or visual compositions.
license: MIT
complexity: intermediate
tags:
- design
- canvas
- visual
triggers:
- user-asks-about-design
- user-asks-about-illustration
- command:design
- context:visual-design
---
Triggers are advisory. They are intended to improve skill discovery but do not create hard activation rules. Agents may:
Skill authors should write triggers that are specific enough to be useful but should not rely on triggers as the sole discovery mechanism. The description and tags fields remain the primary means of skill discovery.
A minimal trigger evaluator:
import re
from pathlib import Path
TRIGGER_PATTERNS = {
"user-asks-about": re.compile(r"^user-asks-about-(.+)$"),
"project-has": re.compile(r"^project-has-(.+)$"),
"file-type": re.compile(r"^file-type:(.+)$"),
"command": re.compile(r"^command:(.+)$"),
"context": re.compile(r"^context:(.+)$"),
}
def evaluate_trigger(trigger: str, context: dict) -> bool:
"""Evaluate a single trigger against the current context.
The context dict may contain:
- user_message: str
- project_root: Path
- active_file: str
- command: str or None
- conversation_context: list[str]
"""
for kind, pattern in TRIGGER_PATTERNS.items():
match = pattern.match(trigger)
if not match:
continue
value = match.group(1)
if kind == "user-asks-about":
keywords = value.replace("-", " ").split()
msg = context.get("user_message", "").lower()
return any(kw in msg for kw in keywords)
if kind == "project-has":
root = context.get("project_root")
if not root:
return False
# Reconstruct filename: hyphens to dots for known extensions
filename = _reconstruct_filename(value)
return (root / filename).exists()
if kind == "file-type":
active = context.get("active_file", "")
return Path(active).match(value)
if kind == "command":
return context.get("command") == value
if kind == "context":
ctx_keywords = context.get("conversation_context", [])
return value in ctx_keywords
return False
def _reconstruct_filename(pattern: str) -> str:
"""Convert trigger pattern back to a filename.
Heuristic: the last hyphen-separated segment that looks like a file
extension (json, toml, yaml, yml, js, ts, py, etc.) is joined with a dot.
"""
parts = pattern.split("-")
extensions = {
"json", "toml", "yaml", "yml", "js", "ts", "py", "cfg",
"ini", "xml", "lock", "sql", "md", "txt", "sh",
}
# Walk from the end to find extension boundaries
result = []
i = len(parts) - 1
while i >= 0:
if parts[i] in extensions and result:
result[-1] = parts[i] + "." + result[-1]
else:
result.append(parts[i])
i -= 1
result.reverse()
# Capitalize known filenames
name = "-".join(result)
capitalizations = {"dockerfile": "Dockerfile", "makefile": "Makefile"}
return capitalizations.get(name.lower(), name)
def check_skill_triggers(triggers: list[str], context: dict) -> bool:
"""Return True if any trigger matches (OR logic)."""
return any(evaluate_trigger(t, context) for t in triggers)
When writing triggers:
project-has-jest-config-js over project-has-package-json for a testing skill.