skills/instructions-builder/SKILL.md
Create, organise, and refine custom instruction files for GitHub Copilot using a modular, rules-based approach. Invoke this skill whenever the user wants to write Copilot instructions, add rules to an existing instructions directory, convert team conventions into instruction files, scope instructions to specific file types or directories, migrate rules from another AI tool into Copilot format, or asks how to structure a .github/copilot-instructions.md or instructions/ directory. Also invoke when someone says "create instructions for X", "write a rule for Y", "add a Copilot rule about Z", or "how should I organise my Copilot instructions".
npx skillsauth add rory-data/copilot instructions-builderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill creates and organises GitHub Copilot instruction files. These files tell Copilot how to behave in a codebase — coding conventions, architecture rules, tooling preferences, and workflow guidance.
Every instruction file is a Markdown file with YAML front matter:
---
description: "What this file governs — shown to the model as context"
applyTo: "**" # glob pattern: which files trigger this instruction
---
# Topic Name
...rules...
applyTo patterns:
"**" — load unconditionally for every interaction"**/*.py" — only when working with Python files"src/**/*.ts" — only for TypeScript files inside src/"tests/**" — only when working in the tests directory"**/*.md" — only for Markdown filesRules without a path (or with "**") load for every session. Path-scoped rules
load only when Copilot is working with matching files, keeping context lean.
instructions/ # or .github/ for repo-level
├── copilot-instructions.md # global, always-on behavioural rules
├── core/ # cross-cutting standards
│ ├── coding-style.instructions.md
│ ├── error-handling.instructions.md
│ └── security.instructions.md
├── language/ # language-specific, path-scoped
│ ├── python.instructions.md # applyTo: "**/*.py"
│ └── typescript.instructions.md # applyTo: "**/*.ts"
└── domain/ # project-specific topics
├── api-design.instructions.md
└── testing.instructions.md
Naming convention: Use <topic>.instructions.md for all instruction files.
Use descriptive names — testing.instructions.md, not test.md.
Before writing anything, interview the user:
Look at the existing instructions/ directory if one is present before proposing new files —
avoid duplicating what's already there.
Split the rules into topics. Each file should:
copilot-instructions.md or other instruction filesWhen to combine vs. split: Group tightly related rules together. Don't create separate files
for each library — group them by concern instead. For example, Python conventions for Pydantic,
SQLAlchemy, and Ruff belong in a single python.instructions.md file scoped to **/*.py, not
in pydantic.instructions.md, sqlalchemy.instructions.md, and linting.instructions.md. One
file per technology is usually too granular; one file per language or domain concern is right.
Propose an outline to the user before writing:
I'll create three files:
1. core/error-handling.instructions.md — applyTo: "**"
2. language/python.instructions.md — applyTo: "**/*.py"
3. domain/api-design.instructions.md — applyTo: "src/api/**"
Confirm the outline before writing the files.
For each file:
applyTo scope is as tight as it can be while still covering the relevant filesAfter writing, review each file's applyTo:
"**/*.py", not "**""**" (no file filter helps here)"src/components/**/*.tsx"Tighter scoping keeps context lean. Rules that always apply should genuinely need to apply everywhere.
## Error Handling
- Raise `ValueError` for invalid inputs; raise `RuntimeError` for unrecoverable states
- Never use bare `except:`; always catch specific exception types
- Use `logging.exception()` inside `except` blocks to preserve stack traces
## Error Handling
- Write clean, readable code
- Handle errors properly
- Follow best practices
---
applyTo: "**/*.py"
description: "Python-specific conventions and tooling"
---
## Imports
- Use `from __future__ import annotations` for forward references
- Group imports: stdlib → third-party → local, separated by blank lines
- Never use wildcard imports (`from module import *`)
## Repository Pattern
Always inject the repository as a dependency — never instantiate it inside a service:
```python
# CORRECT
class OrderService:
def __init__(self, orders: OrderRepository) -> None:
self.orders = orders
When converting rules from Claude Code (.claude/rules/), VS Code snippets, or
team READMEs:
Migration is an enrichment opportunity. Don't just reformat — the source file is likely terse notes or bullet points. This is your chance to add CORRECT/WRONG code examples, group rules under H2 headings, and add context that helps Copilot apply the rule correctly. A migrated file with 10 well-illustrated rules is more valuable than a reformatted copy of the original.
Claude Code frontmatter → Copilot frontmatter:
# Claude Code (.claude/rules/python.md)
---
paths:
- "**/*.py"
---
# Copilot (instructions/language/python.instructions.md)
---
description: "Python-specific conventions"
applyTo: "**/*.py"
---
Enrichment example — a terse source rule becomes a useful instruction:
# Before (terse note):
- Always parameterize SQL queries
# After (enriched instruction):
## SQL Safety
Always parameterize queries — never use f-strings or `.format()` to build SQL:
```python
# CORRECT
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# WRONG
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}") # SQL injection risk
tools
Queries, manages, and troubleshoots Apache Airflow using the af CLI. Covers listing DAGs, triggering runs, reading task logs, diagnosing failures, debugging DAG import errors, checking connections, variables, pools, and monitoring health. Also routes to sub-skills for writing DAGs, debugging, deploying, and migrating Airflow 2 to 3. Use when user mentions "Airflow", "DAG", "DAG run", "task log", "import error", "parse error", "broken DAG", or asks to "trigger a pipeline", "debug import errors", "check Airflow health", "list connections", "retry a run", or any Airflow operation. Do NOT use for warehouse/SQL analytics on Airflow metadata tables — use analyzing-data instead.
tools
Build Airflow 3.1+ plugins that embed FastAPI apps, custom UI pages, React components, middleware, macros, and operator links directly into the Airflow UI. Use this skill whenever the user wants to create an Airflow plugin, add a custom UI page or nav entry to Airflow, build FastAPI-backed endpoints inside Airflow, serve static assets from a plugin, embed a React app in the Airflow UI, add middleware to the Airflow API server, create custom operator extra links, or call the Airflow REST API from inside a plugin. Also trigger when the user mentions AirflowPlugin, fastapi_apps, external_views, react_apps, plugin registration, or embedding a web app in Airflow 3.1+. If someone is building anything custom inside Airflow 3.1+ that involves Python and a browser-facing interface, this skill almost certainly applies.
data-ai
Use when the user needs human-in-the-loop workflows in Airflow (approval/reject, form input, or human-driven branching). Covers ApprovalOperator, HITLOperator, HITLBranchOperator, HITLEntryOperator, HITLTrigger. Requires Airflow 3.1+. Does not cover AI/LLM calls (see airflow-ai).
development
Detects and fixes common code smells during review or refactoring. Invoke whenever reviewing code for quality issues, before merging a PR, when refactoring legacy code, or when the user asks about code quality, anti-patterns, or technical debt. Detects: over-abstraction, complex inheritance, large functions, tight coupling, hidden dependencies, magic numbers, boolean traps, swallowed exceptions, global state, and duplicate code. Provides specific fixes with before/after examples. Also invoke when someone says "review this code", "is this clean?", "can I improve this?", "this feels messy", or "find problems in my code".