framework/devtools/skills/engineer-rule/SKILL.md
Guide for creating persistent AI rules (coding standards, project conventions, file-specific patterns). Use when users want to create a rule, add coding standards, set up project conventions, configure file-specific patterns, or ask about rules placement. Works across IDEs (Cursor, Claude Code, OpenCode).
npx skillsauth add korchasa/flowai engineer-ruleInstall 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 guides through creating persistent rules — instructions that automatically apply to AI agent sessions, enforcing coding standards, project conventions, and file-specific patterns.
Rules are markdown files with metadata that provide persistent context to AI agents. They differ from skills in that rules are automatically injected into every relevant session without explicit invocation.
Rules serve two purposes:
*.ts, React patterns for *.tsx)Rules work across multiple IDEs but use different file formats and locations. Before creating a rule, determine the current environment.
| Primitive | Scope | Claude Code | Cursor | OpenCode |
| :--- | :--- | :--- | :--- | :--- |
| Persistent Instructions | User | ~/.claude/CLAUDE.md | - | ~/.config/opencode/AGENTS.md<br>~/.claude/CLAUDE.md (fallback) |
| | Project | CLAUDE.md<br>.claude/rules/*.md | AGENTS.md<br>.cursor/rules/*/RULE.md<br>~~.cursor/rules/*.mdc~~ | AGENTS.md<br>CLAUDE.md (fallback)<br>opencode.json instructions |
| | Folder | subdir/CLAUDE.md<br>CLAUDE.local.md | subdir/AGENTS.md | - |
| Conditional Instructions | Project | .claude/rules/*.md | .cursor/rules/*/RULE.md<br>~~.cursor/rules/*.mdc~~ | opencode.json instructions (globs) |
| Custom Commands | User | ~/.claude/commands/*.md | ~/.cursor/commands/*.md | ~/.config/opencode/commands/*.md |
| | Project | .claude/commands/*.md<br>.claude/commands/<namespace>/*.md | .cursor/commands/*.md | .opencode/commands/*.md |
| Event Hooks | User | ~/.claude/settings.json | ~/.cursor/hooks.json | ~/.config/opencode/plugins/*.{js,ts} |
| | Project | .claude/settings.json<br>.claude/settings.local.json | .cursor/hooks.json | .opencode/plugins/*.{js,ts} |
| MCP Integration | User | settings.json<br>managed-mcp.json | ~/.cursor/mcp.json | opencode.json mcp |
| | Project | .mcp.json | .cursor/mcp.json | opencode.json mcp |
| Context Ignoring | User | .claude/settings.json | - | - |
| | Project | - | .cursorignore | .gitignore<br>.ignore<br>opencode.json watcher.ignore |
| IDE | Always-Apply Rules | Conditional Rules | Format |
|-----|-------------------|-------------------|--------|
| Cursor | .cursor/rules/*/RULE.md with alwaysApply: true | .cursor/rules/*/RULE.md with globs: | YAML frontmatter + Markdown |
| Claude Code | CLAUDE.md, .claude/rules/*.md (no paths: frontmatter) | .claude/rules/*.md with paths: (array of globs). description accepted but does not scope. globs:/alwaysApply ignored. Triggers on Read only, not Write/Edit. Subdirs discovered recursively. | YAML frontmatter (paths, optional description) + Markdown |
| OpenCode | AGENTS.md, opencode.json instructions | opencode.json instructions (globs) | AGENTS.md: Plain Markdown; opencode.json: JSON array of paths/globs/URLs |
.cursor/ directory -> Cursor.claude/ directory -> Claude Code.opencode/ directory or opencode.json -> OpenCodeBefore creating a rule, determine:
**/*.ts, backend/**/*.py)If prior conversation context exists, infer rules from what was discussed. Create multiple rules if the conversation covers distinct topics. Don't ask redundant questions if context provides answers.
If scope not specified:
If file-specific but no concrete patterns:
Directory-based rules in .cursor/rules/<rule-name>/RULE.md:
---
description: Brief description of what this rule does
globs: "**/*.ts"
alwaysApply: false
---
# Rule Title
Rule content here...
Legacy format (.cursor/rules/*.mdc) still works but is deprecated. Prefer directory format.
| Field | Type | Description |
|-------|------|-------------|
| description | string | What the rule does (used for agent discovery when alwaysApply: false) |
| globs | string | File pattern — rule applies when matching files are in context |
| alwaysApply | boolean | If true, applies to every session regardless of files |
Rules in .claude/rules/*.md (subdirectories discovered recursively). Frontmatter fields: paths (array of glob strings), description (optional, informational only — does NOT scope the rule). Cursor-specific fields (globs, alwaysApply) are silently ignored (rule becomes always-apply).
Conditional rule (loads when Claude reads a matching file):
---
paths:
- "src/**/*.ts"
---
# Rule Title
Rule content here...
Multiple glob patterns:
---
paths:
- "src/**/*.ts"
- "lib/**/*.{ts,tsx}"
- "tests/**/*.test.ts"
---
Always-apply rule: omit paths frontmatter entirely, or use CLAUDE.md (project root / subdirectory).
Limitations: paths: triggers on Read only — Write/Edit to a matching path without prior Read does NOT load the rule.
Always-apply rules in AGENTS.md (project root, plain markdown):
# Rule Title
Rule content here...
Or via opencode.json field instructions (array of paths, globs, or URLs):
{
"instructions": [
"AGENTS.md",
".cursor/rules/**/*.md",
"https://example.com/standards.md"
]
}
Global user rules: ~/.config/opencode/AGENTS.md. Falls back to ~/.claude/CLAUDE.md unless OPENCODE_DISABLE_CLAUDE_CODE_PROMPT=1.
Every rule should contain:
kebab-case (e.g., typescript-standards/RULE.md)kebab-case.md (e.g., typescript-standards.md)Run validation:
deno run -A scripts/validate_rule.ts <path/to/rule-file-or-directory>
Checklist:
description, globs, alwaysApply; Claude Code: paths required, description optional)| Category | Scope | Example Patterns | |----------|-------|-----------------| | Coding standards | Always or per-language | Error handling, naming, imports | | Architecture | Always | Layer boundaries, dependency rules | | Framework patterns | File-specific | React components, API routes | | Testing | File-specific | Test structure, mocking conventions | | Documentation | File-specific | JSDoc format, comment standards | | Security | Always | Auth patterns, input validation |
---
description: TypeScript error handling standards
globs: "**/*.ts"
alwaysApply: false
---
# Error Handling
Always use typed errors with context:
\`\`\`typescript
// BAD
try {
await fetchData();
} catch (e) {}
// GOOD
try {
await fetchData();
} catch (e) {
logger.error('Failed to fetch', { error: e });
throw new DataFetchError('Unable to retrieve data', { cause: e });
}
\`\`\`
---
paths:
- "**/*.ts"
---
# Error Handling
Always use typed errors with context:
\`\`\`typescript
// BAD
try {
await fetchData();
} catch (e) {}
// GOOD
try {
await fetchData();
} catch (e) {
logger.error('Failed to fetch', { error: e });
throw new DataFetchError('Unable to retrieve data', { cause: e });
}
\`\`\`
---
description: React component patterns
globs: "**/*.tsx"
alwaysApply: false
---
# React Patterns
- Use functional components
- Extract custom hooks for reusable logic
- Colocate styles with components
- Props interface named `{ComponentName}Props`
---
paths:
- "**/*.tsx"
- "**/*.jsx"
---
# React Patterns
- Use functional components
- Extract custom hooks for reusable logic
- Colocate styles with components
- Props interface named `{ComponentName}Props`
---
description: Core architecture rules
alwaysApply: true
---
# Architecture
- Domain logic in `src/domain/` — no framework imports
- API handlers in `src/api/` — thin, delegate to domain
- Shared types in `src/types/` — no runtime code
# Architecture
- Domain logic in `src/domain/` — no framework imports
- API handlers in `src/api/` — thin, delegate to domain
- Shared types in `src/types/` — no runtime code
tools
Delegate a task to another AI IDE's CLI (codex / claude / opencode / cursor-agent) through an isolated-context subagent. Triggers on "delegate to <ide>", "have <ide> do <task>", "execute <task> in <ide>", "offload to <ide>". For one-shot relay or fan-out comparison use `ai-ide-runner` instead.
tools
Run prompts in Claude Code, OpenCode, Cursor, or Codex CLIs from the current session — pick one IDE, fan out across several, or compare models. You are a courier that relays the other runtime's stdout verbatim, do not synthesise your own answer. Use on "run in <ide>", "compare <ide> vs <ide>", "try on <model>", "which IDE handles X better", "run across models".
tools
Recommend which LLM model to use for a task. Use when asked "which model / best LLM for X", "pick a model for this task", or for a model shortlist ranked by live leaderboard evidence (coding, reasoning, agentic, tool-use, price, speed). Live-fetches public leaderboards and ranks models with per-axis rationale and citations.
development
Produce a comprehensive Product Requirements Document (PRD). Use when the user asks to write a PRD or formalize a feature's scope, goals, and success metrics.