Skills are markdown files that provide agents with specialized knowledge, workflows, and domain expertise. Grip AI ships with 15 built-in skills covering common development patterns, and supports workspace-specific overrides for project customization.
The skills system follows a three-tier loading hierarchy:
# From grip/skills/loader.py:15-19# Skills are discovered from (in priority order — later sources override earlier):# 1. grip/skills/builtin/ — built-in skills shipped with grip# 2. ~/.agents/skills/ — global shared skills used by multiple agentic tools# 3. workspace/skills/ — user-installed skills specific to this workspace
Later sources override earlier ones. A skill named “code-review” in workspace/skills/ will replace the built-in code-review skill.
Skills use markdown with optional YAML frontmatter:
---title: GitHub Expertdescription: Specialized knowledge for GitHub API and workflowscategory: automationalways_loaded: false---## OverviewThis skill provides expertise in GitHub's REST and GraphQL APIs...## Workflows### Creating Pull Requests1. Check current branch2. Push commits to remote3. Use `gh pr create` command...
# From grip/skills/loader.py:85-98def _scan_directory(self, directory: Path) -> None: """Scan a directory for skills in both flat and folder-based formats.""" # Folder-based: skill-name/SKILL.md for path in sorted(directory.glob("*/SKILL.md")): skill = self._parse_skill_file(path) if skill: self._skills[skill.name] = skill # Flat files: *.md (directly in the directory, not in subfolders) for path in sorted(directory.glob("*.md")): if path.is_file(): skill = self._parse_skill_file(path) if skill: self._skills[skill.name] = skill
# From grip/skills/loader.py:120-133def install_skill(self, content: str, filename: str) -> Path: """Save a skill file to the workspace skills directory. Returns the path of the created file. """ self._workspace_skills_dir.mkdir(parents=True, exist_ok=True) if not filename.endswith(".md"): filename = f"{filename}.md" if "/" in filename or "\\" in filename or ".." in filename: raise ValueError(f"Invalid skill filename: {filename!r}") target = self._workspace_skills_dir / filename target.write_text(content, encoding="utf-8") logger.info("Skill installed: {}", target) return target
Skills can be marked as always_loaded to automatically inject them into every agent session:
# From grip/skills/loader.py:112-118def get_always_loaded_content(self) -> str: """Return concatenated content of skills marked always_loaded.""" parts = [] for skill in self._skills.values(): if skill.always_loaded: parts.append(f"## Skill: {skill.name}\n\n{skill.content}") return "\n\n---\n\n".join(parts)
Use cases for always-loaded skills:
Project-specific coding standards
Company style guides
Security policies
Common troubleshooting steps
Be cautious with always-loaded skills — they consume token budget on every request.
---title: Code Reviewdescription: Custom review standards for this projectcategory: qualityalways_loaded: true---## Project-Specific Standards- All PRs must include tests- Maximum function length: 50 lines- Use TypeScript strict mode...
The workspace skill now overrides the built-in version