Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b64c73015c | ||
|
|
a02afe1d72 | ||
|
|
408f188262 | ||
|
|
e0fdc4e263 | ||
|
|
993775eb4d | ||
|
|
d672808990 | ||
|
|
13bdb4970c | ||
|
|
2db2ca8220 | ||
|
|
9720f75ebe | ||
|
|
e56affd8c8 | ||
|
|
518edc9a3c | ||
|
|
57ce2dd084 | ||
|
|
1bd7db87b9 | ||
|
|
41576e7664 | ||
|
|
c3e5876b7c | ||
|
|
da230d00b0 | ||
|
|
674fa7703d | ||
|
|
a9ff10d511 | ||
|
|
a61c0ed79b | ||
|
|
1f753cd190 | ||
|
|
87671ce026 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
|
||||
MAINTENANCE.md
|
||||
|
||||
walkthrough.md
|
||||
.agent/rules/
|
||||
.gemini/
|
||||
|
||||
53
CHANGELOG.md
53
CHANGELOG.md
@@ -7,6 +7,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
## [2.9.0] - 2026-01-22 - "Automation & Maintenance"
|
||||
|
||||
### Added
|
||||
|
||||
- **Automation Support**:
|
||||
- `scripts/update_readme.py`: Automated script to sync skill counts and regenerate the registry table.
|
||||
- Updated `MAINTENANCE.md` to reflect the new automated workflow.
|
||||
- **Repository Quality**:
|
||||
- `MAINTENANCE.md` is now tracked in the repository (removed from `.gitignore`).
|
||||
- Improved contribution guidelines.
|
||||
|
||||
## [2.8.0] - 2026-01-22 - "Documentation Power"
|
||||
|
||||
### Added
|
||||
|
||||
- **API Documentation Generator**: New skill to automatically generate comprehensive API documentation (`skills/api-documentation-generator`).
|
||||
- **Remotion Best Practices**: 28 modular rules for programmatic video creation (`skills/remotion-best-practices`).
|
||||
|
||||
## [2.7.0] - 2026-01-22 - "Agent Memory"
|
||||
|
||||
### Added
|
||||
|
||||
- **Agent Memory MCP**: New skill providing persistent, searchable knowledge management for AI agents (`skills/agent-memory-mcp`).
|
||||
|
||||
### Changed
|
||||
|
||||
- **Renamed Skill**: `agent-memory` was renamed to `agent-memory-mcp` to avoid naming conflicts.
|
||||
|
||||
---
|
||||
|
||||
## [2.6.0] - 2026-01-21 - "Everything Skills Edition"
|
||||
|
||||
### Added
|
||||
|
||||
- **8 Verified Skills** from [affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code):
|
||||
- `cc-skill-backend-patterns`
|
||||
- `cc-skill-clickhouse-io`
|
||||
- `cc-skill-coding-standards`
|
||||
- `cc-skill-continuous-learning`
|
||||
- `cc-skill-frontend-patterns`
|
||||
- `cc-skill-project-guidelines-example`
|
||||
- `cc-skill-security-review`
|
||||
- `cc-skill-strategic-compact`
|
||||
- **Documentation**: New `WALKTHROUGH.md` for import process details.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Skill Cleanup**: Removed 27 unwanted agents, commands, and rules from the `everything-claude-code` import to focus strictly on skills.
|
||||
- **Index**: Regenerated `skills_index.json` (Total: 233 skills).
|
||||
- **Credits**: Updated README credits and registry.
|
||||
|
||||
## [1.0.0] - 2026-01-19 - "Marketing Edition"
|
||||
|
||||
### Added
|
||||
@@ -113,7 +164,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Total skills count: ~65
|
||||
- Total skills count: **~65**
|
||||
|
||||
---
|
||||
|
||||
|
||||
36
FAQ.md
36
FAQ.md
@@ -14,7 +14,7 @@ Skills are specialized instruction files that teach AI assistants how to handle
|
||||
|
||||
---
|
||||
|
||||
### Do I need to install all 179 skills?
|
||||
### Do I need to install all 233 skills?
|
||||
|
||||
**No!** When you clone the repository, all skills are available, but your AI only loads them when you explicitly invoke them with `@skill-name` or `/skill-name`.
|
||||
|
||||
@@ -39,6 +39,7 @@ These skills work with any AI coding assistant that supports the `SKILL.md` form
|
||||
### Are these skills free to use?
|
||||
|
||||
**Yes!** This repository is licensed under MIT License, which means:
|
||||
|
||||
- ✅ Free for personal use
|
||||
- ✅ Free for commercial use
|
||||
- ✅ You can modify them
|
||||
@@ -49,6 +50,7 @@ These skills work with any AI coding assistant that supports the `SKILL.md` form
|
||||
### Do skills work offline?
|
||||
|
||||
The skill files themselves are stored locally on your computer, but your AI assistant needs an internet connection to function. So:
|
||||
|
||||
- ✅ Skills are local files
|
||||
- ❌ AI assistant needs internet
|
||||
|
||||
@@ -65,6 +67,7 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skill
|
||||
```
|
||||
|
||||
**Tool-specific paths:**
|
||||
|
||||
- Claude Code: `.claude/skills/` or `.agent/skills/`
|
||||
- Gemini CLI: `.gemini/skills/` or `.agent/skills/`
|
||||
- Cursor: `.cursor/skills/` or project root
|
||||
@@ -78,6 +81,7 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skill
|
||||
|
||||
**Option 1: Global Installation** (recommended)
|
||||
Install once in your home directory, works for all projects:
|
||||
|
||||
```bash
|
||||
cd ~
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
@@ -85,6 +89,7 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skill
|
||||
|
||||
**Option 2: Per-Project Installation**
|
||||
Install in each project directory:
|
||||
|
||||
```bash
|
||||
cd /path/to/your/project
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
@@ -133,6 +138,7 @@ Use the `@` symbol followed by the skill name:
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```
|
||||
@brainstorming help me design a todo app
|
||||
@stripe-integration add subscription billing
|
||||
@@ -146,14 +152,16 @@ Some tools also support `/skill-name` syntax.
|
||||
### How do I know which skill to use?
|
||||
|
||||
**Method 1: Browse the README**
|
||||
Check the [Full Skill Registry](README.md#full-skill-registry-179179) organized by category
|
||||
Check the [Full Skill Registry](README.md#full-skill-registry-233233) organized by category
|
||||
|
||||
**Method 2: Search by keyword**
|
||||
|
||||
```bash
|
||||
ls skills/ | grep "keyword"
|
||||
```
|
||||
|
||||
**Method 3: Ask your AI**
|
||||
|
||||
```
|
||||
What skills are available for [topic]?
|
||||
```
|
||||
@@ -179,16 +187,19 @@ What skills are available for [topic]?
|
||||
**Troubleshooting steps:**
|
||||
|
||||
1. **Check installation path**
|
||||
|
||||
```bash
|
||||
ls .agent/skills/
|
||||
```
|
||||
|
||||
2. **Verify skill exists**
|
||||
|
||||
```bash
|
||||
ls .agent/skills/skill-name/
|
||||
```
|
||||
|
||||
3. **Check SKILL.md exists**
|
||||
|
||||
```bash
|
||||
cat .agent/skills/skill-name/SKILL.md
|
||||
```
|
||||
@@ -247,6 +258,7 @@ Check out [CONTRIBUTING.md](CONTRIBUTING.md) for step-by-step instructions.
|
||||
### What makes a good skill?
|
||||
|
||||
A good skill:
|
||||
|
||||
- ✅ Solves a specific problem
|
||||
- ✅ Has clear, actionable instructions
|
||||
- ✅ Includes examples
|
||||
@@ -260,11 +272,13 @@ See [SKILL_ANATOMY.md](docs/SKILL_ANATOMY.md) for details.
|
||||
### How long does it take for my contribution to be reviewed?
|
||||
|
||||
Review times vary, but typically:
|
||||
|
||||
- **Simple fixes** (typos, docs): 1-3 days
|
||||
- **New skills**: 3-7 days
|
||||
- **Major changes**: 1-2 weeks
|
||||
|
||||
You can speed this up by:
|
||||
|
||||
- Following the contribution guidelines
|
||||
- Writing clear commit messages
|
||||
- Testing your changes
|
||||
@@ -286,12 +300,14 @@ The AI primarily uses `SKILL.md`, while developers read `README.md`.
|
||||
### Can I use scripts or code in my skill?
|
||||
|
||||
**Yes!** Skills can include:
|
||||
|
||||
- `scripts/` - Helper scripts
|
||||
- `examples/` - Example code
|
||||
- `templates/` - Code templates
|
||||
- `references/` - Documentation
|
||||
|
||||
Reference them in your `SKILL.md`:
|
||||
|
||||
```markdown
|
||||
Run the setup script:
|
||||
\`\`\`bash
|
||||
@@ -304,6 +320,7 @@ bash scripts/setup.sh
|
||||
### What programming languages can skills cover?
|
||||
|
||||
**Any language!** Current skills cover:
|
||||
|
||||
- JavaScript/TypeScript
|
||||
- Python
|
||||
- Go
|
||||
@@ -338,6 +355,7 @@ python3 scripts/validate_skills.py
|
||||
```
|
||||
|
||||
This checks:
|
||||
|
||||
- ✅ SKILL.md exists
|
||||
- ✅ Frontmatter is valid
|
||||
- ✅ Name matches folder name
|
||||
@@ -350,16 +368,19 @@ This checks:
|
||||
### Which skills should I try first?
|
||||
|
||||
**For beginners:**
|
||||
|
||||
- `@brainstorming` - Design before coding
|
||||
- `@systematic-debugging` - Fix bugs methodically
|
||||
- `@git-pushing` - Commit with good messages
|
||||
|
||||
**For developers:**
|
||||
|
||||
- `@test-driven-development` - Write tests first
|
||||
- `@react-best-practices` - Modern React patterns
|
||||
- `@senior-fullstack` - Full-stack development
|
||||
|
||||
**For security:**
|
||||
|
||||
- `@ethical-hacking-methodology` - Security basics
|
||||
- `@burp-suite-testing` - Web app testing
|
||||
|
||||
@@ -377,6 +398,7 @@ This checks:
|
||||
6. **Iterate** - Improve based on feedback
|
||||
|
||||
**Recommended skills to study:**
|
||||
|
||||
- `skills/brainstorming/SKILL.md` - Clear structure
|
||||
- `skills/systematic-debugging/SKILL.md` - Comprehensive
|
||||
- `skills/git-pushing/SKILL.md` - Simple and focused
|
||||
@@ -386,6 +408,7 @@ This checks:
|
||||
### Are there any skills for learning AI/ML?
|
||||
|
||||
**Yes!** Check out:
|
||||
|
||||
- `@rag-engineer` - RAG systems
|
||||
- `@prompt-engineering` - Prompt design
|
||||
- `@langgraph` - Multi-agent systems
|
||||
@@ -435,11 +458,13 @@ We'll update it quickly!
|
||||
### Can I modify skills for my own use?
|
||||
|
||||
**Yes!** The MIT License allows you to:
|
||||
|
||||
- ✅ Modify skills for your needs
|
||||
- ✅ Create private versions
|
||||
- ✅ Customize for your team
|
||||
|
||||
**To modify:**
|
||||
|
||||
1. Copy the skill to a new location
|
||||
2. Edit the SKILL.md file
|
||||
3. Use your modified version
|
||||
@@ -452,7 +477,7 @@ We'll update it quickly!
|
||||
|
||||
### How many skills are there?
|
||||
|
||||
**179 skills** across 10+ categories as of the latest update.
|
||||
**233 skills** across 10+ categories as of the latest update.
|
||||
|
||||
---
|
||||
|
||||
@@ -463,6 +488,7 @@ We'll update it quickly!
|
||||
- **Updates**: When best practices change
|
||||
|
||||
**Stay updated:**
|
||||
|
||||
```bash
|
||||
cd .agent/skills
|
||||
git pull origin main
|
||||
@@ -473,6 +499,7 @@ git pull origin main
|
||||
### Who maintains this repository?
|
||||
|
||||
This is a community-driven project with contributions from:
|
||||
|
||||
- Original creators
|
||||
- Open source contributors
|
||||
- AI coding assistant users worldwide
|
||||
@@ -504,6 +531,7 @@ See [Credits & Sources](README.md#credits--sources) for attribution.
|
||||
### Can I use these skills commercially?
|
||||
|
||||
**Yes!** The MIT License permits commercial use. You can:
|
||||
|
||||
- ✅ Use in commercial projects
|
||||
- ✅ Use in client work
|
||||
- ✅ Include in paid products
|
||||
@@ -523,6 +551,6 @@ See [Credits & Sources](README.md#credits--sources) for attribution.
|
||||
|
||||
---
|
||||
|
||||
**Question not answered?**
|
||||
**Question not answered?**
|
||||
|
||||
[Open a discussion](https://github.com/sickn33/antigravity-awesome-skills/discussions) and we'll help you out! 🙌
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## 🤔 What Are "Skills"?
|
||||
|
||||
Think of skills as **specialized instruction manuals** for AI coding assistants.
|
||||
Think of skills as **specialized instruction manuals** for AI coding assistants.
|
||||
|
||||
**Simple analogy:** Just like you might hire different experts (a designer, a security expert, a marketer), these skills let your AI assistant become an expert in specific areas when you need them.
|
||||
|
||||
@@ -14,7 +14,7 @@ Think of skills as **specialized instruction manuals** for AI coding assistants.
|
||||
|
||||
## 📦 What's Inside This Repository?
|
||||
|
||||
This repo contains **179 ready-to-use skills** organized in the `skills/` folder. Each skill is a folder with at least one file: `SKILL.md`
|
||||
This repo contains **233 ready-to-use skills** organized in the `skills/` folder. Each skill is a folder with at least one file: `SKILL.md`
|
||||
|
||||
```
|
||||
skills/
|
||||
@@ -32,6 +32,7 @@ skills/
|
||||
## How Do Skills Work?
|
||||
|
||||
### Step 1: Install Skills
|
||||
|
||||
Copy the skills to your AI tool's directory:
|
||||
|
||||
```bash
|
||||
@@ -40,6 +41,7 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skill
|
||||
```
|
||||
|
||||
### Step 2: Use a Skill
|
||||
|
||||
In your AI chat, mention the skill:
|
||||
|
||||
```
|
||||
@@ -53,50 +55,65 @@ or
|
||||
```
|
||||
|
||||
### Step 3: The AI Becomes an Expert
|
||||
|
||||
The AI loads that skill's knowledge and helps you with specialized expertise!
|
||||
|
||||
---
|
||||
|
||||
## Which AI Tools Work With This?
|
||||
|
||||
| Tool | Works? | Installation Path |
|
||||
|------|--------|-------------------|
|
||||
| **Claude Code** | ✅ Yes | `.claude/skills/` or `.agent/skills/` |
|
||||
| **Gemini CLI** | ✅ Yes | `.gemini/skills/` or `.agent/skills/` |
|
||||
| **Cursor** | ✅ Yes | `.cursor/skills/` |
|
||||
| **GitHub Copilot** | ⚠️ Partial | Copy to `.github/copilot/` |
|
||||
| **Antigravity IDE** | ✅ Yes | `.agent/skills/` |
|
||||
| Tool | Works? | Installation Path |
|
||||
| ------------------- | ---------- | ------------------------------------- |
|
||||
| **Claude Code** | ✅ Yes | `.claude/skills/` or `.agent/skills/` |
|
||||
| **Gemini CLI** | ✅ Yes | `.gemini/skills/` or `.agent/skills/` |
|
||||
| **Cursor** | ✅ Yes | `.cursor/skills/` |
|
||||
| **GitHub Copilot** | ⚠️ Partial | Copy to `.github/copilot/` |
|
||||
| **Antigravity IDE** | ✅ Yes | `.agent/skills/` |
|
||||
|
||||
---
|
||||
|
||||
## Skill Categories (Simplified)
|
||||
|
||||
### **Creative & Design** (10 skills)
|
||||
|
||||
Make beautiful things: UI design, art, themes, web components
|
||||
|
||||
- Try: `@frontend-design`, `@canvas-design`, `@ui-ux-pro-max`
|
||||
|
||||
### **Development** (25 skills)
|
||||
|
||||
Write better code: testing, debugging, React patterns, architecture
|
||||
|
||||
- Try: `@test-driven-development`, `@systematic-debugging`, `@react-best-practices`
|
||||
|
||||
### **Security** (50 skills)
|
||||
|
||||
Ethical hacking and penetration testing tools
|
||||
|
||||
- Try: `@ethical-hacking-methodology`, `@burp-suite-testing`
|
||||
|
||||
### **AI & Agents** (30 skills)
|
||||
|
||||
Build AI apps: RAG, LangGraph, prompt engineering, voice agents
|
||||
|
||||
- Try: `@rag-engineer`, `@prompt-engineering`, `@langgraph`
|
||||
|
||||
### **Documents** (4 skills)
|
||||
|
||||
Work with Word, Excel, PowerPoint, PDF files
|
||||
|
||||
- Try: `@docx-official`, `@xlsx-official`, `@pdf-official`
|
||||
|
||||
### **Marketing** (23 skills)
|
||||
|
||||
Grow your product: SEO, copywriting, ads, email campaigns
|
||||
|
||||
- Try: `@copywriting`, `@seo-audit`, `@page-cro`
|
||||
|
||||
### **Integrations** (25 skills)
|
||||
|
||||
Connect to services: Stripe, Firebase, Twilio, Discord, Slack
|
||||
|
||||
- Try: `@stripe-integration`, `@firebase`, `@clerk-auth`
|
||||
|
||||
---
|
||||
@@ -108,6 +125,7 @@ Let's try the **brainstorming** skill:
|
||||
1. **Open your AI assistant** (Claude Code, Cursor, etc.)
|
||||
|
||||
2. **Type this:**
|
||||
|
||||
```
|
||||
@brainstorming I want to build a simple weather app
|
||||
```
|
||||
@@ -125,10 +143,13 @@ Let's try the **brainstorming** skill:
|
||||
## How to Find the Right Skill
|
||||
|
||||
### Method 1: Browse by Category
|
||||
Check the [Full Skill Registry](README.md#full-skill-registry-179179) in the main README
|
||||
|
||||
Check the [Full Skill Registry](README.md#full-skill-registry-233233) in the main README
|
||||
|
||||
### Method 2: Search by Keyword
|
||||
|
||||
Use your file explorer or terminal:
|
||||
|
||||
```bash
|
||||
# Find skills related to "testing"
|
||||
ls skills/ | grep test
|
||||
@@ -138,6 +159,7 @@ ls skills/ | grep auth
|
||||
```
|
||||
|
||||
### Method 3: Look at the Index
|
||||
|
||||
Check `skills_index.json` for a machine-readable list
|
||||
|
||||
---
|
||||
@@ -147,33 +169,41 @@ Check `skills_index.json` for a machine-readable list
|
||||
Great! Here's how:
|
||||
|
||||
### Option 1: Improve Documentation
|
||||
|
||||
- Make READMEs clearer
|
||||
- Add more examples
|
||||
- Fix typos or confusing parts
|
||||
|
||||
### Option 2: Create a New Skill
|
||||
|
||||
See our [CONTRIBUTING.md](CONTRIBUTING.md) for step-by-step instructions
|
||||
|
||||
### Option 3: Report Issues
|
||||
|
||||
Found something confusing? [Open an issue](https://github.com/sickn33/antigravity-awesome-skills/issues)
|
||||
|
||||
---
|
||||
|
||||
## ❓ Common Questions
|
||||
|
||||
### Q: Do I need to install all 179 skills?
|
||||
### Q: Do I need to install all 233 skills?
|
||||
|
||||
**A:** No! Clone the whole repo, and your AI will only load skills when you use them.
|
||||
|
||||
### Q: Can I create my own skills?
|
||||
|
||||
**A:** Yes! Check out the `@skill-creator` skill or read [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
### Q: What if my AI tool isn't listed?
|
||||
|
||||
**A:** If it supports the `SKILL.md` format, try `.agent/skills/` - it's the universal path.
|
||||
|
||||
### Q: Are these skills free?
|
||||
|
||||
**A:** Yes! MIT License. Use them however you want.
|
||||
|
||||
### Q: Do skills work offline?
|
||||
|
||||
**A:** The skill files are local, but your AI assistant needs internet to function.
|
||||
|
||||
---
|
||||
|
||||
54
MAINTENANCE.md
Normal file
54
MAINTENANCE.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Repository Maintenance Protocol
|
||||
|
||||
To ensure consistency and quality, the following steps MUST be performed for **every single change** involving skills or documentation.
|
||||
|
||||
## 1. Skill Creation & Modification
|
||||
|
||||
- [ ] **Check Duplicates**: Before adding a skill, check `skills_index.json` or `ls skills/` to ensure it doesn't exist.
|
||||
- [ ] **Folder Structure**: Each skill must have its own folder in `skills/<skill-name>`.
|
||||
- [ ] **SKILL.md**: Every skill directory MUST contain a `SKILL.md` file with valid frontmatter:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: Skill Name
|
||||
description: Brief description.
|
||||
---
|
||||
```
|
||||
|
||||
## 2. Validation & Indexing (CRITICAL)
|
||||
|
||||
Running the scripts is **MANDATORY** after any change to `skills/`.
|
||||
|
||||
- [ ] **Validate Skills**: Run the validation script to check for formatting errors.
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_skills.py
|
||||
```
|
||||
|
||||
- [ ] **Generate Index**: Update `skills_index.json`. This is the source of truth for the agent.
|
||||
|
||||
```bash
|
||||
python3 scripts/generate_index.py
|
||||
```
|
||||
|
||||
## 3. Documentation Updates
|
||||
|
||||
- [ ] **Update README**: Run the automation script to sync counts and the registry table.
|
||||
|
||||
```bash
|
||||
python3 scripts/update_readme.py
|
||||
```
|
||||
|
||||
- [ ] **Credits & Sources**: If the skill was imported from a community repo, add a credit link in `# Credits & Sources` manually if needed.
|
||||
- Example: `- **[repo-name](url)**: Source for [skill-name].`
|
||||
|
||||
## 4. Git Operations
|
||||
|
||||
- [ ] **Check Status**: `git status` to see what changed.
|
||||
- [ ] **Add All Files**: Ensure new skill folders are added (`git add skills/`).
|
||||
- [ ] **Commit**: Use a descriptive Conventional Commit message (e.g., `feat: add new security skills`, `docs: update readme count`).
|
||||
- [ ] **Push**: `git push` to origin. **NEVER FORGET THIS.**
|
||||
|
||||
## 5. Agent Artifacts (Internal)
|
||||
|
||||
- [ ] **Walkthrough**: Update `walkthrough.md` in the brain/artifact directory to reflect the session's achievements.
|
||||
478
README.md
478
README.md
@@ -1,6 +1,6 @@
|
||||
# 🌌 Antigravity Awesome Skills: 224+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
|
||||
# 🌌 Antigravity Awesome Skills: 235+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
|
||||
|
||||
> **The Ultimate Collection of 224+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode**
|
||||
> **The Ultimate Collection of 235+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode**
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://claude.ai)
|
||||
@@ -11,7 +11,7 @@
|
||||
[](https://github.com/opencode-ai/opencode)
|
||||
[](https://github.com/anthropics/antigravity)
|
||||
|
||||
**Antigravity Awesome Skills** is a curated, battle-tested library of **224 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
|
||||
**Antigravity Awesome Skills** is a curated, battle-tested library of **235 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
|
||||
|
||||
- 🟣 **Claude Code** (Anthropic CLI)
|
||||
- 🔵 **Gemini CLI** (Google DeepMind)
|
||||
@@ -55,7 +55,7 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skill
|
||||
@brainstorming help me design a todo app
|
||||
```
|
||||
|
||||
That's it! Your AI assistant now has 224 specialized skills. 🎉
|
||||
That's it! Your AI assistant now has 235 specialized skills. 🎉
|
||||
|
||||
**Additional Resources:**
|
||||
|
||||
@@ -95,11 +95,11 @@ The repository is organized into several key areas of expertise:
|
||||
| :-------------------------- | :----------- | :--------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **🛸 Autonomous & Agentic** | **~8** | Loki Mode (Startup-in-a-box), Subagent Driven Dev, Dispatching Parallel Agents, Planning With Files, Skill Creator/Developer |
|
||||
| **🔌 Integrations & APIs** | **~25** | Stripe, Firebase, Supabase, Vercel, Clerk Auth, Twilio, Discord Bot, Slack Bot, GraphQL, AWS Serverless |
|
||||
| **🛡️ Cybersecurity** | **~50** | Ethical Hacking, Metasploit, Burp Suite, SQLMap, Active Directory, AWS/Cloud Pentesting, OWASP Top 100, Red Team Tools |
|
||||
| **🛡️ Cybersecurity** | **~51** | Ethical Hacking, Metasploit, Burp Suite, SQLMap, Active Directory, AWS/Cloud Pentesting, OWASP Top 100, Red Team Tools |
|
||||
| **🎨 Creative & Design** | **~10** | UI/UX Pro Max, Frontend Design, Canvas, Algorithmic Art, Theme Factory, D3 Viz, Web Artifacts |
|
||||
| **🛠️ Development** | **~25** | TDD, Systematic Debugging, React Patterns, Backend/Frontend Guidelines, Senior Fullstack, Software Architecture |
|
||||
| **🛠️ Development** | **~33** | TDD, Systematic Debugging, React Patterns, Backend/Frontend Guidelines, Senior Fullstack, Software Architecture |
|
||||
| **🏗️ Infrastructure & Git** | **~8** | Linux Shell Scripting, Git Worktrees, Git Pushing, Conventional Commits, File Organization, GitHub Workflow Automation |
|
||||
| **🤖 AI Agents & LLM** | **~30** | LangGraph, CrewAI, Langfuse, RAG Engineer, Prompt Engineer, Voice Agents, Browser Automation, Agent Memory Systems |
|
||||
| **🤖 AI Agents & LLM** | **~31** | LangGraph, CrewAI, Langfuse, RAG Engineer, Prompt Engineer, Voice Agents, Browser Automation, Agent Memory Systems |
|
||||
| **🔄 Workflow & Planning** | **~6** | Writing Plans, Executing Plans, Concise Planning, Verification Before Completion, Code Review (Requesting/Receiving) |
|
||||
| **📄 Document Processing** | **~4** | DOCX (Official), PDF (Official), PPTX (Official), XLSX (Official) |
|
||||
| **🧪 Testing & QA** | **~4** | Webapp Testing, Playwright Automation, Test Fixing, Testing Patterns |
|
||||
@@ -109,232 +109,247 @@ The repository is organized into several key areas of expertise:
|
||||
|
||||
---
|
||||
|
||||
## Full Skill Registry (224/224)
|
||||
|
||||
Below is the complete list of available skills. Each skill folder contains a `SKILL.md` that can be imported into Antigravity or Claude Code.
|
||||
## Full Skill Registry (235/235)
|
||||
|
||||
> [!NOTE] > **Document Skills**: We provide both **community** and **official Anthropic** versions for DOCX, PDF, PPTX, and XLSX. Locally, the official versions are used by default (via symlinks). In the repository, both versions are available for flexibility.
|
||||
|
||||
| Skill Name | Description | Path |
|
||||
| :-------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------- |
|
||||
| **3D Web Experience** | Expert in building 3D experiences for the web - Three.js, React Three Fiber, Spline, WebGL. | `skills/3d-web-experience` |
|
||||
| **A/B Test Setup** | Plan and implement A/B tests with proper experiment design, statistical significance, and test analysis. | `skills/ab-test-setup` |
|
||||
| **Active Directory Attacks** | This skill should be used when the user asks to "attack Active Directory", "exploit AD", "Kerberoasting", "DCSync", "pass-the-hash", "BloodHound enumeration", "Golden Ticket", "Silver Ticket", "AS-REP roasting", "NTLM relay", or needs guidance on Windows domain penetration testing. | `skills/active-directory-attacks` |
|
||||
| **Address GitHub Comments** | Use when you need to address review or issue comments on an open GitHub Pull Request using the gh CLI. | `skills/address-github-comments` |
|
||||
| **Agent Evaluation** | Testing and benchmarking LLM agents including behavioral testing, capability assessment, reliability metrics. | `skills/agent-evaluation` |
|
||||
| **Agent Manager Skill** | Use when you need to manage multiple local CLI agents via tmux sessions (start/stop/monitor/assign) with cron-friendly scheduling. | `skills/agent-manager-skill` |
|
||||
| **Agent Memory Systems** | Memory architecture for agents: short-term, long-term (vector stores), and cognitive architectures. | `skills/agent-memory-systems` |
|
||||
| **Agent Tool Builder** | Tool design from schema to error handling. JSON Schema best practices, validation, and MCP. | `skills/agent-tool-builder` |
|
||||
| **AI Agents Architect** | Expert in autonomous AI agents. Tool use, memory systems, planning strategies, multi-agent orchestration. | `skills/ai-agents-architect` |
|
||||
| **AI Product** | LLM integration patterns, RAG architecture, prompt engineering, AI UX, and cost optimization. | `skills/ai-product` |
|
||||
| **AI Wrapper Product** | Building products that wrap AI APIs into focused tools. Prompt engineering, cost management. | `skills/ai-wrapper-product` |
|
||||
| **Algolia Search** | Algolia search implementation, indexing strategies, React InstantSearch, relevance tuning. | `skills/algolia-search` |
|
||||
| **Algorithmic Art** | Creating algorithmic art using p5. | `skills/algorithmic-art` |
|
||||
| **Analytics Tracking** | Set up analytics tracking with GA4, GTM, and custom event implementations for marketing measurement. | `skills/analytics-tracking` |
|
||||
| **API Fuzzing for Bug Bounty** | This skill should be used when the user asks to "test API security", "fuzz APIs", "find IDOR vulnerabilities", "test REST API", "test GraphQL", "API penetration testing", "bug bounty API testing", or needs guidance on API security assessment techniques. | `skills/api-fuzzing-bug-bounty` |
|
||||
| **API Patterns** | API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning. | `skills/api-patterns` |
|
||||
| **App Builder** | Main application building orchestrator. Creates full-stack applications from natural language requests. | `skills/app-builder` |
|
||||
| **App Store Optimization** | Complete App Store Optimization (ASO) toolkit for researching, optimizing, and tracking mobile app performance on Apple App Store and Google Play Store. | `skills/app-store-optimization` |
|
||||
| **Architecture** | Architectural decision-making framework. Requirements analysis, trade-off evaluation, ADR documentation. | `skills/architecture` |
|
||||
| **Autonomous Agent Patterns** | "Design patterns for building autonomous coding agents. | `skills/autonomous-agent-patterns` |
|
||||
| **Autonomous Agents** | AI systems that independently decompose goals, plan actions, execute tools. ReAct, reflection. | `skills/autonomous-agents` |
|
||||
| **AWS Penetration Testing** | This skill should be used when the user asks to "pentest AWS", "test AWS security", "enumerate IAM", "exploit cloud infrastructure", "AWS privilege escalation", "S3 bucket testing", "metadata SSRF", "Lambda exploitation", or needs guidance on Amazon Web Services security assessment. | `skills/aws-penetration-testing` |
|
||||
| **AWS Serverless** | Serverless on AWS. Lambda, API Gateway, DynamoDB, SQS/SNS, SAM/CDK deployment. | `skills/aws-serverless` |
|
||||
| **Azure Functions** | Azure Functions patterns. Isolated worker model, Durable Functions, cold start optimization. | `skills/azure-functions` |
|
||||
| **Backend Guidelines** | Comprehensive backend development guide for Node. | `skills/backend-dev-guidelines` |
|
||||
| **Bash Linux** | Bash/Linux terminal patterns. Critical commands, piping, error handling, scripting. | `skills/bash-linux` |
|
||||
| **Behavioral Modes** | AI operational modes (brainstorm, implement, debug, review, teach, ship, orchestrate). | `skills/behavioral-modes` |
|
||||
| **BlockRun** | Agent wallet for LLM micropayments. Use when user needs capabilities Claude lacks (image generation, real-time X/Twitter data) or explicitly requests external models ("blockrun", "use grok", "use gpt", "dall-e", "deepseek"). | `skills/blockrun` |
|
||||
| **Brainstorming** | "You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. | `skills/brainstorming` |
|
||||
| **Brand Guidelines (Anthropic)** | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. | `skills/brand-guidelines-anthropic` |
|
||||
| **Brand Guidelines (Community)** | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. | `skills/brand-guidelines-community` |
|
||||
| **Broken Authentication Testing** | This skill should be used when the user asks to "test for broken authentication vulnerabilities", "assess session management security", "perform credential stuffing tests", "evaluate password policies", "test for session fixation", or "identify authentication bypass flaws". | `skills/broken-authentication` |
|
||||
| **Browser Automation** | Browser automation with Playwright and Puppeteer. Testing, scraping, agentic control. | `skills/browser-automation` |
|
||||
| **Browser Extension Builder** | Building browser extensions - Chrome, Firefox. Manifest v3, content scripts, monetization. | `skills/browser-extension-builder` |
|
||||
| **BullMQ Specialist** | BullMQ for Redis-backed job queues, background processing in Node.js/TypeScript. | `skills/bullmq-specialist` |
|
||||
| **Bun Development** | "Modern JavaScript/TypeScript development with Bun runtime. | `skills/bun-development` |
|
||||
| **Burp Suite Web Application Testing** | This skill should be used when the user asks to "intercept HTTP traffic", "modify web requests", "use Burp Suite for testing", "perform web vulnerability scanning", "test with Burp Repeater", "analyze HTTP history", or "configure proxy for web testing". | `skills/burp-suite-testing` |
|
||||
| **Canvas Design** | Create beautiful visual art in . | `skills/canvas-design` |
|
||||
| **Claude Code Guide** | Master guide for using Claude Code effectively. | `skills/claude-code-guide` |
|
||||
| **Claude D3.js** | Creating interactive data visualisations using d3. | `skills/claude-d3js-skill` |
|
||||
| **Clean Code** | Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments. | `skills/clean-code` |
|
||||
| **Clerk Auth** | Clerk auth implementation, middleware, organizations, webhooks, user sync. | `skills/clerk-auth` |
|
||||
| **Cloud Penetration Testing** | This skill should be used when the user asks to "perform cloud penetration testing", "assess Azure or AWS or GCP security", "enumerate cloud resources", "exploit cloud misconfigurations", "test O365 security", "extract secrets from cloud environments", or "audit cloud infrastructure". | `skills/cloud-penetration-testing` |
|
||||
| **Code Review Checklist** | Code review guidelines covering code quality, security, and best practices. | `skills/code-review-checklist` |
|
||||
| **Competitor Alternatives** | Create compelling competitor comparison and alternative pages for SEO and conversions. | `skills/competitor-alternatives` |
|
||||
| **Computer Use Agents** | AI agents that interact with computers like humans. Screen control, sandboxing. | `skills/computer-use-agents` |
|
||||
| **Concise Planning** | Use when a user asks for a plan for a coding task, to generate a clear, actionable, and atomic checklist. | `skills/concise-planning` |
|
||||
| **Content Creator** | Create SEO-optimized marketing content with consistent brand voice. | `skills/content-creator` |
|
||||
| **Context Window Management** | Managing LLM context windows. Summarization, trimming, routing. | `skills/context-window-management` |
|
||||
| **Conversation Memory** | Persistent memory for LLM conversations. Short-term, long-term, entity-based memory. | `skills/conversation-memory` |
|
||||
| **Copy Editing** | Edit and polish existing marketing copy with a systematic seven-sweeps framework. | `skills/copy-editing` |
|
||||
| **Copywriting** | Write compelling marketing copy for homepages, landing pages, pricing pages, and feature pages. | `skills/copywriting` |
|
||||
| **Core Components** | Core component library and design system patterns. | `skills/core-components` |
|
||||
| **CrewAI** | Role-based multi-agent framework. Agent design, task definition, crew orchestration. | `skills/crewai` |
|
||||
| **Cross-Site Scripting and HTML Injection Testing** | This skill should be used when the user asks to "test for XSS vulnerabilities", "perform cross-site scripting attacks", "identify HTML injection flaws", "exploit client-side injection vulnerabilities", "steal cookies via XSS", or "bypass content security policies". | `skills/xss-html-injection` |
|
||||
| **Database Design** | Database design principles. Schema design, indexing strategy, ORM selection, serverless databases. | `skills/database-design` |
|
||||
| **Deployment Procedures** | Production deployment principles. Safe deployment workflows, rollback strategies, and verification. | `skills/deployment-procedures` |
|
||||
| **Discord Bot Architect** | Production Discord bots. Discord.js, Pycord, slash commands, sharding. | `skills/discord-bot-architect` |
|
||||
| **Dispatching Parallel Agents** | Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. | `skills/dispatching-parallel-agents` |
|
||||
| **Doc Co-authoring** | Guide users through a structured workflow for co-authoring documentation. | `skills/doc-coauthoring` |
|
||||
| **Docker Expert** | Docker containerization expert. Multi-stage builds, image optimization, container security, Docker Compose. | `skills/docker-expert` |
|
||||
| **Documentation Templates** | Documentation templates and structure guidelines. README, API docs, code comments. | `skills/documentation-templates` |
|
||||
| **DOCX (Official)** | "Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. | `skills/docx-official` |
|
||||
| **Email Sequence** | Create and optimize email sequences, drip campaigns, and lifecycle email programs. | `skills/email-sequence` |
|
||||
| **Email Systems** | Transactional email, marketing automation, deliverability, infrastructure. | `skills/email-systems` |
|
||||
| **Ethical Hacking Methodology** | This skill should be used when the user asks to "learn ethical hacking", "understand penetration testing lifecycle", "perform reconnaissance", "conduct security scanning", "exploit vulnerabilities", or "write penetration test reports". | `skills/ethical-hacking-methodology` |
|
||||
| **Executing Plans** | Use when you have a written implementation plan to execute in a separate session with review checkpoints. | `skills/executing-plans` |
|
||||
| **File Organizer** | Intelligently organizes files and folders by understanding context, finding duplicates, and suggesting better organizational structures. | `skills/file-organizer` |
|
||||
| **File Path Traversal Testing** | This skill should be used when the user asks to "test for directory traversal", "exploit path traversal vulnerabilities", "read arbitrary files through web applications", "find LFI vulnerabilities", or "access files outside web root". | `skills/file-path-traversal` |
|
||||
| **File Uploads** | File uploads and cloud storage. S3, Cloudflare R2, presigned URLs. | `skills/file-uploads` |
|
||||
| **Finishing Dev Branch** | Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup. | `skills/finishing-a-development-branch` |
|
||||
| **Firebase** | Firebase Auth, Firestore, Realtime Database, Cloud Functions, Storage. | `skills/firebase` |
|
||||
| **Form CRO** | Optimize lead capture forms, contact forms, demo request forms for higher conversion rates. | `skills/form-cro` |
|
||||
| **Free Tool Strategy** | Plan and build free tools for marketing, lead generation, and SEO value. | `skills/free-tool-strategy` |
|
||||
| **Frontend Design** | Create distinctive, production-grade frontend interfaces with high design quality. | `skills/frontend-design` |
|
||||
| **Frontend Guidelines** | Frontend development guidelines for React/TypeScript applications. | `skills/frontend-dev-guidelines` |
|
||||
| **Game Development** | Game development orchestrator. Routes to platform-specific skills based on project needs. | `skills/game-development` |
|
||||
| **GCP Cloud Run** | Serverless on GCP. Cloud Run services and functions, Pub/Sub. | `skills/gcp-cloud-run` |
|
||||
| **GEO Fundamentals** | Generative Engine Optimization for AI search engines (ChatGPT, Claude, Perplexity). | `skills/geo-fundamentals` |
|
||||
| **Git Pushing** | Stage, commit, and push git changes with conventional commit messages. | `skills/git-pushing` |
|
||||
| **GitHub Workflow Automation** | "Automate GitHub workflows with AI assistance. | `skills/github-workflow-automation` |
|
||||
| **GraphQL** | Schema design, resolvers, DataLoader, federation, Apollo/urql integration. | `skills/graphql` |
|
||||
| **HTML Injection Testing** | This skill should be used when the user asks to "test for HTML injection", "inject HTML into web pages", "perform HTML injection attacks", "deface web applications", or "test content injection vulnerabilities". | `skills/html-injection-testing` |
|
||||
| **HubSpot Integration** | HubSpot CRM integration. OAuth, CRM objects, webhooks, custom objects. | `skills/hubspot-integration` |
|
||||
| **i18n Localization** | Internationalization and localization patterns. Detecting hardcoded strings, managing translations. | `skills/i18n-localization` |
|
||||
| **IDOR Vulnerability Testing** | This skill should be used when the user asks to "test for insecure direct object references," "find IDOR vulnerabilities," "exploit broken access control," "enumerate user IDs or object references," or "bypass authorization to access other users' data. | `skills/idor-testing` |
|
||||
| **Inngest** | Inngest for serverless background jobs, event-driven workflows. | `skills/inngest` |
|
||||
| **Interactive Portfolio** | Building portfolios that land jobs. Developer, designer portfolios. | `skills/interactive-portfolio` |
|
||||
| **Internal Comms (Anthropic)** | A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. | `skills/internal-comms-anthropic` |
|
||||
| **Internal Comms (Community)** | A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. | `skills/internal-comms-community` |
|
||||
| **JavaScript Mastery** | "Comprehensive JavaScript reference covering 33+ essential concepts every developer should know. | `skills/javascript-mastery` |
|
||||
| **Kaizen** | Guide for continuous improvement, error proofing, and standardization. | `skills/kaizen` |
|
||||
| **Langfuse** | Open-source LLM observability. Tracing, prompt management, evaluation. | `skills/langfuse` |
|
||||
| **LangGraph** | Stateful, multi-actor AI applications. Graph construction, persistence. | `skills/langgraph` |
|
||||
| **Launch Strategy** | Plan product launches, feature announcements, and go-to-market strategies. | `skills/launch-strategy` |
|
||||
| **Lint and Validate** | Automatic quality control, linting, and static analysis procedures. | `skills/lint-and-validate` |
|
||||
| **Linux Privilege Escalation** | This skill should be used when the user asks to "escalate privileges on Linux", "find privesc vectors on Linux systems", "exploit sudo misconfigurations", "abuse SUID binaries", "exploit cron jobs for root access", "enumerate Linux systems for privilege escalation", or "gain root access from low-privilege shell". | `skills/linux-privilege-escalation` |
|
||||
| **Linux Shell Scripting** | This skill should be used when the user asks to "create bash scripts", "automate Linux tasks", "monitor system resources", "backup files", "manage users", or "write production shell scripts". | `skills/linux-shell-scripting` |
|
||||
| **LLM App Patterns** | "Production-ready patterns for building LLM applications. | `skills/llm-app-patterns` |
|
||||
| **Loki Mode** | Multi-agent autonomous startup system for Claude Code. | `skills/loki-mode` |
|
||||
| **Marketing Ideas** | 140 proven SaaS marketing ideas and strategies organized by category. | `skills/marketing-ideas` |
|
||||
| **Marketing Psychology** | 70+ mental models and psychological principles for marketing and persuasion. | `skills/marketing-psychology` |
|
||||
| **MCP Builder** | Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. | `skills/mcp-builder` |
|
||||
| **Metasploit Framework** | This skill should be used when the user asks to "use Metasploit for penetration testing", "exploit vulnerabilities with msfconsole", "create payloads with msfvenom", "perform post-exploitation", "use auxiliary modules for scanning", or "develop custom exploits". | `skills/metasploit-framework` |
|
||||
| **Micro-SaaS Launcher** | Launching small SaaS products fast. Idea validation, MVP, pricing. | `skills/micro-saas-launcher` |
|
||||
| **Mobile Design** | Mobile-first design thinking for iOS and Android apps. Touch interaction, performance patterns. | `skills/mobile-design` |
|
||||
| **Moodle External API Development** | Create custom external web service APIs for Moodle LMS. Use when implementing web services for course management, user tracking, quiz operations, or custom plugin functionality. Covers parameter validation, database operations, error handling, service registration, and Moodle coding standards. | `skills/moodle-external-api-development` |
|
||||
| **Neon Postgres** | Neon serverless Postgres, branching, connection pooling, Prisma integration. | `skills/neon-postgres` |
|
||||
| **NestJS Expert** | Nest.js framework expert. Module architecture, dependency injection, middleware, guards, interceptors. | `skills/nestjs-expert` |
|
||||
| **Network 101** | This skill should be used when the user asks to "set up a web server", "configure HTTP or HTTPS", "perform SNMP enumeration", "configure SMB shares", "test network services", or needs guidance on configuring and testing network services for penetration testing labs. | `skills/network-101` |
|
||||
| **Next.js Best Practices** | Next.js App Router principles. Server Components, data fetching, routing patterns. | `skills/nextjs-best-practices` |
|
||||
| **Next.js Supabase Auth** | Supabase Auth with Next.js App Router. Auth middleware. | `skills/nextjs-supabase-auth` |
|
||||
| **Node.js Best Practices** | Node.js development principles. Framework selection, async patterns, security, architecture. | `skills/nodejs-best-practices` |
|
||||
| **NotebookLM** | Use this skill to query your Google NotebookLM notebooks directly from Claude Code for source-grounded, citation-backed answers from Gemini. | `skills/notebooklm` |
|
||||
| **Notion Template Business** | Building and selling Notion templates. Design, pricing, marketing. | `skills/notion-template-business` |
|
||||
| **Onboarding CRO** | Optimize post-signup onboarding, user activation, and time-to-value. | `skills/onboarding-cro` |
|
||||
| **Page CRO** | Conversion rate optimization for marketing pages - homepages, landing pages, pricing pages. | `skills/page-cro` |
|
||||
| **Paid Ads** | Create and optimize paid ad campaigns on Google Ads, Meta, LinkedIn, and other platforms. | `skills/paid-ads` |
|
||||
| **Parallel Agents** | Multi-agent orchestration patterns. Use when multiple independent tasks can run with different domain expertise. | `skills/parallel-agents` |
|
||||
| **Paywall Upgrade CRO** | Optimize in-app paywalls, upgrade screens, and freemium conversion moments. | `skills/paywall-upgrade-cro` |
|
||||
| **PDF (Official)** | Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. | `skills/pdf-official` |
|
||||
| **Pentest Checklist** | This skill should be used when the user asks to "plan a penetration test", "create a security assessment checklist", "prepare for penetration testing", "define pentest scope", "follow security testing best practices", or needs a structured methodology for penetration testing engagements. | `skills/pentest-checklist` |
|
||||
| **Pentest Commands** | This skill should be used when the user asks to "run pentest commands", "scan with nmap", "use metasploit exploits", "crack passwords with hydra or john", "scan web vulnerabilities with nikto", "enumerate networks", or needs essential penetration testing command references. | `skills/pentest-commands` |
|
||||
| **Performance Profiling** | Performance profiling principles. Measurement, analysis, and optimization techniques. | `skills/performance-profiling` |
|
||||
| **Personal Tool Builder** | Building custom tools. Rapid prototyping, local-first apps, CLI tools. | `skills/personal-tool-builder` |
|
||||
| **Plaid Fintech** | Plaid API for banking. Link token flows, transactions, ACH. | `skills/plaid-fintech` |
|
||||
| **Plan Writing** | Structured task planning with clear breakdowns, dependencies, and verification criteria. | `skills/plan-writing` |
|
||||
| **Planning With Files** | Implements Manus-style file-based planning for complex tasks. | `skills/planning-with-files` |
|
||||
| **Playwright Automation** | Complete browser automation with Playwright. | `skills/playwright-skill` |
|
||||
| **Popup CRO** | Create and optimize popups, modals, and overlays for conversion. | `skills/popup-cro` |
|
||||
| **PowerShell Windows** | PowerShell Windows patterns. Critical pitfalls, operator syntax, error handling. | `skills/powershell-windows` |
|
||||
| **PPTX (Official)** | "Presentation creation, editing, and analysis. | `skills/pptx-official` |
|
||||
| **Pricing Strategy** | Design pricing, packaging, and monetization strategy for SaaS products. | `skills/pricing-strategy` |
|
||||
| **Prisma Expert** | Prisma ORM expert for schema design, migrations, query optimization, relations modeling. | `skills/prisma-expert` |
|
||||
| **Privilege Escalation Methods** | This skill should be used when the user asks to "escalate privileges", "get root access", "become administrator", "privesc techniques", "abuse sudo", "exploit SUID binaries", "Kerberoasting", "pass-the-ticket", "token impersonation", or needs guidance on post-exploitation privilege escalation for Linux or Windows systems. | `skills/privilege-escalation-methods` |
|
||||
| **Product Toolkit** | Comprehensive toolkit for product managers including RICE prioritization, customer interview analysis, PRD templates, discovery frameworks, and go-to-market strategies. | `skills/product-manager-toolkit` |
|
||||
| **Programmatic SEO** | Build SEO-driven pages at scale using templates and data. | `skills/programmatic-seo` |
|
||||
| **Prompt Caching** | Caching strategies for LLM prompts. Anthropic caching, CAG. | `skills/prompt-caching` |
|
||||
| **Prompt Engineer** | Designing prompts for LLM applications. Structure, evaluation. | `skills/prompt-engineer` |
|
||||
| **Prompt Engineering** | Expert guide on prompt engineering patterns, best practices, and optimization techniques. | `skills/prompt-engineering` |
|
||||
| **Prompt Library** | "Curated collection of high-quality prompts for various use cases. | `skills/prompt-library` |
|
||||
| **Python Patterns** | Python development principles. Framework selection, async patterns, type hints, project structure. | `skills/python-patterns` |
|
||||
| **RAG Engineer** | Building RAG systems. Embedding models, vector databases, chunking. | `skills/rag-engineer` |
|
||||
| **RAG Implementation** | RAG patterns. Chunking, embeddings, vector stores. | `skills/rag-implementation` |
|
||||
| **React Best Practices** | React and Next. | `skills/react-best-practices` |
|
||||
| **React Patterns** | Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices. | `skills/react-patterns` |
|
||||
| **React UI Patterns** | Modern React UI patterns for loading states, error handling, and data fetching. | `skills/react-ui-patterns` |
|
||||
| **Research Engineer** | Academic Research Engineer persona with scientific rigor, zero hallucinations, and optimal language selection for high-precision engineering tasks. | `skills/research-engineer` |
|
||||
| **Receiving Code Review** | Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation. | `skills/receiving-code-review` |
|
||||
| **Red Team Tactics** | Red team tactics principles based on MITRE ATT&CK. Attack phases, detection evasion, reporting. | `skills/red-team-tactics` |
|
||||
| **Red Team Tools and Methodology** | This skill should be used when the user asks to "follow red team methodology", "perform bug bounty hunting", "automate reconnaissance", "hunt for XSS vulnerabilities", "enumerate subdomains", or needs security researcher techniques and tool configurations from top bug bounty hunters. | `skills/red-team-tools` |
|
||||
| **Referral Program** | Design referral programs, affiliate programs, and word-of-mouth strategies. | `skills/referral-program` |
|
||||
| **Requesting Code Review** | Use when completing tasks, implementing major features, or before merging to verify work meets requirements. | `skills/requesting-code-review` |
|
||||
| **Salesforce Development** | Salesforce integration, Apex development, Lightning components. | `skills/salesforce-development` |
|
||||
| **Schema Markup** | Add structured data and JSON-LD schema markup for SEO and rich snippets. | `skills/schema-markup` |
|
||||
| **Scroll Experience** | GSAP/Framer scroll-driven storytelling. Parallax effects. | `skills/scroll-experience` |
|
||||
| **Security Scanning Tools** | This skill should be used when the user asks to "perform vulnerability scanning", "scan networks for open ports", "assess web application security", "scan wireless networks", "detect malware", "check cloud security", or "evaluate system compliance". | `skills/scanning-tools` |
|
||||
| **Segment CDP** | Segment customer data platform. Event tracking, identity resolution. | `skills/segment-cdp` |
|
||||
| **Senior Architect** | Comprehensive software architecture skill for designing scalable, maintainable systems using ReactJS, NextJS, NodeJS, Express, React Native, Swift, Kotlin, Flutter, Postgres, GraphQL, Go, Python. | `skills/senior-architect` |
|
||||
| **Senior Fullstack** | Comprehensive fullstack development skill for building complete web applications with React, Next. | `skills/senior-fullstack` |
|
||||
| **SEO Audit** | Audit technical and on-page SEO issues for better search rankings. | `skills/seo-audit` |
|
||||
| **SEO Fundamentals** | SEO fundamentals, E-E-A-T, Core Web Vitals, and Google algorithm principles. | `skills/seo-fundamentals` |
|
||||
| **Server Management** | Server management principles. Process management, monitoring strategy, and scaling decisions. | `skills/server-management` |
|
||||
| **Shodan Reconnaissance and Pentesting** | This skill should be used when the user asks to "search for exposed devices on the internet," "perform Shodan reconnaissance," "find vulnerable services using Shodan," "scan IP ranges with Shodan," or "discover IoT devices and open ports. | `skills/shodan-reconnaissance` |
|
||||
| **Shopify Apps** | Building Shopify apps. App Bridge, Polaris, webhooks. | `skills/shopify-apps` |
|
||||
| **Shopify Development** | Build Shopify apps, extensions, themes using GraphQL Admin API, Shopify CLI, Polaris UI, and Liquid. Use when user asks about "shopify app", "checkout extension", "shopify theme", "liquid template", "polaris", "shopify graphql", "shopify webhook", or "metafields". | `skills/shopify-development` |
|
||||
| **Signup Flow CRO** | Optimize signup, registration, and trial activation flows for higher conversions. | `skills/signup-flow-cro` |
|
||||
| **Skill Creator** | Guide for creating effective skills. | `skills/skill-creator` |
|
||||
| **Skill Developer** | Create and manage Claude Code skills following Anthropic best practices. | `skills/skill-developer` |
|
||||
| **Slack Bot Builder** | Production Slack bots. Bolt framework, slash commands, modals. | `skills/slack-bot-builder` |
|
||||
| **Slack GIF Creator** | Knowledge and utilities for creating animated GIFs optimized for Slack. | `skills/slack-gif-creator` |
|
||||
| **SMTP Penetration Testing** | This skill should be used when the user asks to "perform SMTP penetration testing", "enumerate email users", "test for open mail relays", "grab SMTP banners", "brute force email credentials", or "assess mail server security". | `skills/smtp-penetration-testing` |
|
||||
| **Social Content** | Create and schedule social media content for LinkedIn, Twitter/X, and other platforms. | `skills/social-content` |
|
||||
| **Software Architecture** | Guide for quality focused software architecture. | `skills/software-architecture` |
|
||||
| **SQL Injection Testing** | This skill should be used when the user asks to "test for SQL injection vulnerabilities", "perform SQLi attacks", "bypass authentication using SQL injection", "extract database information through injection", "detect SQL injection flaws", or "exploit database query vulnerabilities". | `skills/sql-injection-testing` |
|
||||
| **SQLMap Database Penetration Testing** | This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap," "dump tables and columns from a vulnerable database," or "perform automated database penetration testing. | `skills/sqlmap-database-pentesting` |
|
||||
| **SSH Penetration Testing** | This skill should be used when the user asks to "pentest SSH services", "enumerate SSH configurations", "brute force SSH credentials", "exploit SSH vulnerabilities", "perform SSH tunneling", or "audit SSH security". | `skills/ssh-penetration-testing` |
|
||||
| **Stripe Integration** | Stripe patterns. Checkout, subscriptions, payment intents, webhooks. | `skills/stripe-integration` |
|
||||
| **Subagent Driven Dev** | Use when executing implementation plans with independent tasks in the current session. | `skills/subagent-driven-development` |
|
||||
| **Systematic Debugging** | Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes. | `skills/systematic-debugging` |
|
||||
| **Tailwind Patterns** | Tailwind CSS v4 principles. CSS-first configuration, container queries, design token architecture. | `skills/tailwind-patterns` |
|
||||
| **TDD** | Use when implementing any feature or bugfix, before writing implementation code. | `skills/test-driven-development` |
|
||||
| **TDD Workflow** | Test-Driven Development workflow principles. RED-GREEN-REFACTOR cycle. | `skills/tdd-workflow` |
|
||||
| **Telegram Bot Builder** | Building Telegram bots. Bot API, inline mode, payments, Mini Apps. | `skills/telegram-bot-builder` |
|
||||
| **Telegram Mini App** | TON Connect, Telegram Mini Apps, wallet integration. | `skills/telegram-mini-app` |
|
||||
| **Test Fixing** | Run tests and systematically fix all failing tests using smart error grouping. | `skills/test-fixing` |
|
||||
| **Testing Patterns** | Jest testing patterns, factory functions, mocking strategies, and TDD workflow. | `skills/testing-patterns` |
|
||||
| **Theme Factory** | Toolkit for styling artifacts with a theme. | `skills/theme-factory` |
|
||||
| **Top 100 Vulnerabilities** | This skill should be used when the user asks to "identify web application vulnerabilities", "explain common security flaws", "understand vulnerability categories", "learn about injection attacks", "review access control weaknesses", "analyze API security issues", "assess security misconfigurations", "understand client-side vulnerabilities", "examine mobile and IoT security flaws", or "reference the OWASP-aligned vulnerability taxonomy". | `skills/top-web-vulnerabilities` |
|
||||
| **Trigger.dev** | Trigger.dev for serverless background jobs. Long-running tasks. | `skills/trigger-dev` |
|
||||
| **Twilio Communications** | Twilio for SMS, voice, video. Programmable messaging, OTP. | `skills/twilio-communications` |
|
||||
| **TypeScript Expert** | TypeScript expert with deep knowledge of type-level programming, performance optimization, migration strategies. | `skills/typescript-expert` |
|
||||
| **UI/UX Pro Max** | "UI/UX design intelligence. | `skills/ui-ux-pro-max` |
|
||||
| **Upstash QStash** | Upstash QStash for serverless message queues. | `skills/upstash-qstash` |
|
||||
| **Using Git Worktrees** | Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification. | `skills/using-git-worktrees` |
|
||||
| **Using Superpowers** | Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions. | `skills/using-superpowers` |
|
||||
| **Vercel Deployment** | Vercel deployment. Edge functions, preview deployments. | `skills/vercel-deployment` |
|
||||
| **Verification Before Completion** | Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always. | `skills/verification-before-completion` |
|
||||
| **Viral Generator Builder** | Building shareable generators that go viral. | `skills/viral-generator-builder` |
|
||||
| **Voice Agents** | Voice-based AI assistants. Speech-to-text, real-time conversation. | `skills/voice-agents` |
|
||||
| **Voice AI Development** | Voice AI patterns. Wake words, streaming ASR, emotional TTS. | `skills/voice-ai-development` |
|
||||
| **Vulnerability Scanner** | Advanced vulnerability analysis principles. OWASP 2025, Supply Chain Security, attack surface mapping. | `skills/vulnerability-scanner` |
|
||||
| **Web Artifacts** | Suite of tools for creating elaborate, multi-component claude. | `skills/web-artifacts-builder` |
|
||||
| **Web Design Guidelines** | Review UI code for Web Interface Guidelines compliance. | `skills/web-design-guidelines` |
|
||||
| **Webapp Testing** | Toolkit for interacting with and testing local web applications using Playwright. | `skills/webapp-testing` |
|
||||
| **Windows Privilege Escalation** | This skill should be used when the user asks to "escalate privileges on Windows," "find Windows privesc vectors," "enumerate Windows for privilege escalation," "exploit Windows misconfigurations," or "perform post-exploitation privilege escalation. | `skills/windows-privilege-escalation` |
|
||||
| **Wireshark Network Traffic Analysis** | This skill should be used when the user asks to "analyze network traffic with Wireshark", "capture packets for troubleshooting", "filter PCAP files", "follow TCP/UDP streams", "detect network anomalies", "investigate suspicious traffic", or "perform protocol analysis". | `skills/wireshark-analysis` |
|
||||
| **WordPress Penetration Testing** | This skill should be used when the user asks to "pentest WordPress sites", "scan WordPress for vulnerabilities", "enumerate WordPress users, themes, or plugins", "exploit WordPress vulnerabilities", or "use WPScan". | `skills/wordpress-penetration-testing` |
|
||||
| **Workflow Automation** | "Design and implement automated workflows combining visual logic with custom code. | `skills/workflow-automation` |
|
||||
| **Writing Plans** | Use when you have a spec or requirements for a multi-step task, before touching code. | `skills/writing-plans` |
|
||||
| **Writing Skills** | Use when creating new skills, editing existing skills, or verifying skills work before deployment. | `skills/writing-skills` |
|
||||
| **XLSX (Official)** | "Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. | `skills/xlsx-official` |
|
||||
| **Zapier/Make Patterns** | No-code automation. Zapier, Make, n8n workflows. | `skills/zapier-make-patterns` |
|
||||
|
||||
> [!TIP]
|
||||
> Use the `validate_skills.py` script in the `scripts/` directory to ensure all skills are properly formatted and ready for use.
|
||||
|
||||
---
|
||||
| Skill Name | Description | Path |
|
||||
| :--- | :--- | :--- |
|
||||
| **2d-games** | 2D game development principles. Sprites, tilemaps, physics, camera. | `skills/game-development/2d-games` |
|
||||
| **3d-games** | 3D game development principles. Rendering, shaders, physics, cameras. | `skills/game-development/3d-games` |
|
||||
| **3d-web-experience** | "Expert in building 3D experiences for the web - Three.js, React Three Fiber, Spline, WebGL, and interactive 3D scenes. Covers product configurators, 3D portfolios, immersive websites, and bringing depth to web experiences. Use when: 3D website, three.js, WebGL, react three fiber, 3D experience." | `skills/3d-web-experience` |
|
||||
| **API Fuzzing for Bug Bounty** | This skill should be used when the user asks to "test API security", "fuzz APIs", "find IDOR vulnerabilities", "test REST API", "test GraphQL", "API penetration testing", "bug bounty API testing", or needs guidance on API security assessment techniques. | `skills/api-fuzzing-bug-bounty` |
|
||||
| **AWS Penetration Testing** | This skill should be used when the user asks to "pentest AWS", "test AWS security", "enumerate IAM", "exploit cloud infrastructure", "AWS privilege escalation", "S3 bucket testing", "metadata SSRF", "Lambda exploitation", or needs guidance on Amazon Web Services security assessment. | `skills/aws-penetration-testing` |
|
||||
| **Active Directory Attacks** | This skill should be used when the user asks to "attack Active Directory", "exploit AD", "Kerberoasting", "DCSync", "pass-the-hash", "BloodHound enumeration", "Golden Ticket", "Silver Ticket", "AS-REP roasting", "NTLM relay", or needs guidance on Windows domain penetration testing. | `skills/active-directory-attacks` |
|
||||
| **Broken Authentication Testing** | This skill should be used when the user asks to "test for broken authentication vulnerabilities", "assess session management security", "perform credential stuffing tests", "evaluate password policies", "test for session fixation", or "identify authentication bypass flaws". It provides comprehensive techniques for identifying authentication and session management weaknesses in web applications. | `skills/broken-authentication` |
|
||||
| **Burp Suite Web Application Testing** | This skill should be used when the user asks to "intercept HTTP traffic", "modify web requests", "use Burp Suite for testing", "perform web vulnerability scanning", "test with Burp Repeater", "analyze HTTP history", or "configure proxy for web testing". It provides comprehensive guidance for using Burp Suite's core features for web application security testing. | `skills/burp-suite-testing` |
|
||||
| **Claude Code Guide** | Master guide for using Claude Code effectively. Includes configuration templates, prompting strategies "Thinking" keywords, debugging techniques, and best practices for interacting with the agent. | `skills/claude-code-guide` |
|
||||
| **Cloud Penetration Testing** | This skill should be used when the user asks to "perform cloud penetration testing", "assess Azure or AWS or GCP security", "enumerate cloud resources", "exploit cloud misconfigurations", "test O365 security", "extract secrets from cloud environments", or "audit cloud infrastructure". It provides comprehensive techniques for security assessment across major cloud platforms. | `skills/cloud-penetration-testing` |
|
||||
| **Cross-Site Scripting and HTML Injection Testing** | This skill should be used when the user asks to "test for XSS vulnerabilities", "perform cross-site scripting attacks", "identify HTML injection flaws", "exploit client-side injection vulnerabilities", "steal cookies via XSS", or "bypass content security policies". It provides comprehensive techniques for detecting, exploiting, and understanding XSS and HTML injection attack vectors in web applications. | `skills/xss-html-injection` |
|
||||
| **Ethical Hacking Methodology** | This skill should be used when the user asks to "learn ethical hacking", "understand penetration testing lifecycle", "perform reconnaissance", "conduct security scanning", "exploit vulnerabilities", or "write penetration test reports". It provides comprehensive ethical hacking methodology and techniques. | `skills/ethical-hacking-methodology` |
|
||||
| **File Path Traversal Testing** | This skill should be used when the user asks to "test for directory traversal", "exploit path traversal vulnerabilities", "read arbitrary files through web applications", "find LFI vulnerabilities", or "access files outside web root". It provides comprehensive file path traversal attack and testing methodologies. | `skills/file-path-traversal` |
|
||||
| **HTML Injection Testing** | This skill should be used when the user asks to "test for HTML injection", "inject HTML into web pages", "perform HTML injection attacks", "deface web applications", or "test content injection vulnerabilities". It provides comprehensive HTML injection attack techniques and testing methodologies. | `skills/html-injection-testing` |
|
||||
| **IDOR Vulnerability Testing** | This skill should be used when the user asks to "test for insecure direct object references," "find IDOR vulnerabilities," "exploit broken access control," "enumerate user IDs or object references," or "bypass authorization to access other users' data." It provides comprehensive guidance for detecting, exploiting, and remediating IDOR vulnerabilities in web applications. | `skills/idor-testing` |
|
||||
| **Linux Privilege Escalation** | This skill should be used when the user asks to "escalate privileges on Linux", "find privesc vectors on Linux systems", "exploit sudo misconfigurations", "abuse SUID binaries", "exploit cron jobs for root access", "enumerate Linux systems for privilege escalation", or "gain root access from low-privilege shell". It provides comprehensive techniques for identifying and exploiting privilege escalation paths on Linux systems. | `skills/linux-privilege-escalation` |
|
||||
| **Linux Production Shell Scripts** | This skill should be used when the user asks to "create bash scripts", "automate Linux tasks", "monitor system resources", "backup files", "manage users", or "write production shell scripts". It provides ready-to-use shell script templates for system administration. | `skills/linux-shell-scripting` |
|
||||
| **Metasploit Framework** | This skill should be used when the user asks to "use Metasploit for penetration testing", "exploit vulnerabilities with msfconsole", "create payloads with msfvenom", "perform post-exploitation", "use auxiliary modules for scanning", or "develop custom exploits". It provides comprehensive guidance for leveraging the Metasploit Framework in security assessments. | `skills/metasploit-framework` |
|
||||
| **Network 101** | This skill should be used when the user asks to "set up a web server", "configure HTTP or HTTPS", "perform SNMP enumeration", "configure SMB shares", "test network services", or needs guidance on configuring and testing network services for penetration testing labs. | `skills/network-101` |
|
||||
| **Pentest Checklist** | This skill should be used when the user asks to "plan a penetration test", "create a security assessment checklist", "prepare for penetration testing", "define pentest scope", "follow security testing best practices", or needs a structured methodology for penetration testing engagements. | `skills/pentest-checklist` |
|
||||
| **Pentest Commands** | This skill should be used when the user asks to "run pentest commands", "scan with nmap", "use metasploit exploits", "crack passwords with hydra or john", "scan web vulnerabilities with nikto", "enumerate networks", or needs essential penetration testing command references. | `skills/pentest-commands` |
|
||||
| **Privilege Escalation Methods** | This skill should be used when the user asks to "escalate privileges", "get root access", "become administrator", "privesc techniques", "abuse sudo", "exploit SUID binaries", "Kerberoasting", "pass-the-ticket", "token impersonation", or needs guidance on post-exploitation privilege escalation for Linux or Windows systems. | `skills/privilege-escalation-methods` |
|
||||
| **Red Team Tools and Methodology** | This skill should be used when the user asks to "follow red team methodology", "perform bug bounty hunting", "automate reconnaissance", "hunt for XSS vulnerabilities", "enumerate subdomains", or needs security researcher techniques and tool configurations from top bug bounty hunters. | `skills/red-team-tools` |
|
||||
| **SMTP Penetration Testing** | This skill should be used when the user asks to "perform SMTP penetration testing", "enumerate email users", "test for open mail relays", "grab SMTP banners", "brute force email credentials", or "assess mail server security". It provides comprehensive techniques for testing SMTP server security. | `skills/smtp-penetration-testing` |
|
||||
| **SQL Injection Testing** | This skill should be used when the user asks to "test for SQL injection vulnerabilities", "perform SQLi attacks", "bypass authentication using SQL injection", "extract database information through injection", "detect SQL injection flaws", or "exploit database query vulnerabilities". It provides comprehensive techniques for identifying, exploiting, and understanding SQL injection attack vectors across different database systems. | `skills/sql-injection-testing` |
|
||||
| **SQLMap Database Penetration Testing** | This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap," "dump tables and columns from a vulnerable database," or "perform automated database penetration testing." It provides comprehensive guidance for using SQLMap to detect and exploit SQL injection vulnerabilities. | `skills/sqlmap-database-pentesting` |
|
||||
| **SSH Penetration Testing** | This skill should be used when the user asks to "pentest SSH services", "enumerate SSH configurations", "brute force SSH credentials", "exploit SSH vulnerabilities", "perform SSH tunneling", or "audit SSH security". It provides comprehensive SSH penetration testing methodologies and techniques. | `skills/ssh-penetration-testing` |
|
||||
| **Security Scanning Tools** | This skill should be used when the user asks to "perform vulnerability scanning", "scan networks for open ports", "assess web application security", "scan wireless networks", "detect malware", "check cloud security", or "evaluate system compliance". It provides comprehensive guidance on security scanning tools and methodologies. | `skills/scanning-tools` |
|
||||
| **Shodan Reconnaissance and Pentesting** | This skill should be used when the user asks to "search for exposed devices on the internet," "perform Shodan reconnaissance," "find vulnerable services using Shodan," "scan IP ranges with Shodan," or "discover IoT devices and open ports." It provides comprehensive guidance for using Shodan's search engine, CLI, and API for penetration testing reconnaissance. | `skills/shodan-reconnaissance` |
|
||||
| **Top 100 Web Vulnerabilities Reference** | This skill should be used when the user asks to "identify web application vulnerabilities", "explain common security flaws", "understand vulnerability categories", "learn about injection attacks", "review access control weaknesses", "analyze API security issues", "assess security misconfigurations", "understand client-side vulnerabilities", "examine mobile and IoT security flaws", or "reference the OWASP-aligned vulnerability taxonomy". Use this skill to provide comprehensive vulnerability definitions, root causes, impacts, and mitigation strategies across all major web security categories. | `skills/top-web-vulnerabilities` |
|
||||
| **Windows Privilege Escalation** | This skill should be used when the user asks to "escalate privileges on Windows," "find Windows privesc vectors," "enumerate Windows for privilege escalation," "exploit Windows misconfigurations," or "perform post-exploitation privilege escalation." It provides comprehensive guidance for discovering and exploiting privilege escalation vulnerabilities in Windows environments. | `skills/windows-privilege-escalation` |
|
||||
| **Wireshark Network Traffic Analysis** | This skill should be used when the user asks to "analyze network traffic with Wireshark", "capture packets for troubleshooting", "filter PCAP files", "follow TCP/UDP streams", "detect network anomalies", "investigate suspicious traffic", or "perform protocol analysis". It provides comprehensive techniques for network packet capture, filtering, and analysis using Wireshark. | `skills/wireshark-analysis` |
|
||||
| **WordPress Penetration Testing** | This skill should be used when the user asks to "pentest WordPress sites", "scan WordPress for vulnerabilities", "enumerate WordPress users, themes, or plugins", "exploit WordPress vulnerabilities", or "use WPScan". It provides comprehensive WordPress security assessment methodologies. | `skills/wordpress-penetration-testing` |
|
||||
| **ab-test-setup** | When the user wants to plan, design, or implement an A/B test or experiment. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," or "hypothesis." For tracking implementation, see analytics-tracking. | `skills/ab-test-setup` |
|
||||
| **address-github-comments** | Use when you need to address review or issue comments on an open GitHub Pull Request using the gh CLI. | `skills/address-github-comments` |
|
||||
| **agent-evaluation** | "Testing and benchmarking LLM agents including behavioral testing, capability assessment, reliability metrics, and production monitoring—where even top agents achieve less than 50% on real-world benchmarks Use when: agent testing, agent evaluation, benchmark agents, agent reliability, test agent." | `skills/agent-evaluation` |
|
||||
| **agent-manager-skill** | Manage multiple local CLI agents via tmux sessions (start/stop/monitor/assign) with cron-friendly scheduling. | `skills/agent-manager-skill` |
|
||||
| **agent-memory-mcp** | A hybrid memory system that provides persistent, searchable knowledge management for AI agents (Architecture, Patterns, Decisions). | `skills/agent-memory-mcp` |
|
||||
| **agent-memory-systems** | "Memory is the cornerstone of intelligent agents. Without it, every interaction starts from zero. This skill covers the architecture of agent memory: short-term (context window), long-term (vector stores), and the cognitive architectures that organize them. Key insight: Memory isn't just storage - it's retrieval. A million stored facts mean nothing if you can't find the right one. Chunking, embedding, and retrieval strategies determine whether your agent remembers or forgets. The field is fragm" | `skills/agent-memory-systems` |
|
||||
| **agent-tool-builder** | "Tools are how AI agents interact with the world. A well-designed tool is the difference between an agent that works and one that hallucinates, fails silently, or costs 10x more tokens than necessary. This skill covers tool design from schema to error handling. JSON Schema best practices, description writing that actually helps the LLM, validation, and the emerging MCP standard that's becoming the lingua franca for AI tools. Key insight: Tool descriptions are more important than tool implementa" | `skills/agent-tool-builder` |
|
||||
| **ai-agents-architect** | "Expert in designing and building autonomous AI agents. Masters tool use, memory systems, planning strategies, and multi-agent orchestration. Use when: build agent, AI agent, autonomous agent, tool use, function calling." | `skills/ai-agents-architect` |
|
||||
| **ai-product** | "Every product will be AI-powered. The question is whether you'll build it right or ship a demo that falls apart in production. This skill covers LLM integration patterns, RAG architecture, prompt engineering that scales, AI UX that users trust, and cost optimization that doesn't bankrupt you. Use when: keywords, file_patterns, code_patterns." | `skills/ai-product` |
|
||||
| **ai-wrapper-product** | "Expert in building products that wrap AI APIs (OpenAI, Anthropic, etc.) into focused tools people will pay for. Not just 'ChatGPT but different' - products that solve specific problems with AI. Covers prompt engineering for products, cost management, rate limiting, and building defensible AI businesses. Use when: AI wrapper, GPT product, AI tool, wrap AI, AI SaaS." | `skills/ai-wrapper-product` |
|
||||
| **algolia-search** | "Expert patterns for Algolia search implementation, indexing strategies, React InstantSearch, and relevance tuning Use when: adding search to, algolia, instantsearch, search api, search functionality." | `skills/algolia-search` |
|
||||
| **algorithmic-art** | Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations. | `skills/algorithmic-art` |
|
||||
| **analytics-tracking** | When the user wants to set up, improve, or audit analytics tracking and measurement. Also use when the user mentions "set up tracking," "GA4," "Google Analytics," "conversion tracking," "event tracking," "UTM parameters," "tag manager," "GTM," "analytics implementation," or "tracking plan." For A/B test measurement, see ab-test-setup. | `skills/analytics-tracking` |
|
||||
| **api-documentation-generator** | "Generate comprehensive, developer-friendly API documentation from code, including endpoints, parameters, examples, and best practices" | `skills/api-documentation-generator` |
|
||||
| **api-patterns** | API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning, pagination. | `skills/api-patterns` |
|
||||
| **app-builder** | Main application building orchestrator. Creates full-stack applications from natural language requests. Determines project type, selects tech stack, coordinates agents. | `skills/app-builder` |
|
||||
| **app-store-optimization** | Complete App Store Optimization (ASO) toolkit for researching, optimizing, and tracking mobile app performance on Apple App Store and Google Play Store | `skills/app-store-optimization` |
|
||||
| **architecture** | Architectural decision-making framework. Requirements analysis, trade-off evaluation, ADR documentation. Use when making architecture decisions or analyzing system design. | `skills/architecture` |
|
||||
| **autonomous-agent-patterns** | "Design patterns for building autonomous coding agents. Covers tool integration, permission systems, browser automation, and human-in-the-loop workflows. Use when building AI agents, designing tool APIs, implementing permission systems, or creating autonomous coding assistants." | `skills/autonomous-agent-patterns` |
|
||||
| **autonomous-agents** | "Autonomous agents are AI systems that can independently decompose goals, plan actions, execute tools, and self-correct without constant human guidance. The challenge isn't making them capable - it's making them reliable. Every extra decision multiplies failure probability. This skill covers agent loops (ReAct, Plan-Execute), goal decomposition, reflection patterns, and production reliability. Key insight: compounding error rates kill autonomous agents. A 95% success rate per step drops to 60% b" | `skills/autonomous-agents` |
|
||||
| **aws-serverless** | "Specialized skill for building production-ready serverless applications on AWS. Covers Lambda functions, API Gateway, DynamoDB, SQS/SNS event-driven patterns, SAM/CDK deployment, and cold start optimization." | `skills/aws-serverless` |
|
||||
| **azure-functions** | "Expert patterns for Azure Functions development including isolated worker model, Durable Functions orchestration, cold start optimization, and production patterns. Covers .NET, Python, and Node.js programming models. Use when: azure function, azure functions, durable functions, azure serverless, function app." | `skills/azure-functions` |
|
||||
| **backend-dev-guidelines** | Comprehensive backend development guide for Node.js/Express/TypeScript microservices. Use when creating routes, controllers, services, repositories, middleware, or working with Express APIs, Prisma database access, Sentry error tracking, Zod validation, unifiedConfig, dependency injection, or async patterns. Covers layered architecture (routes → controllers → services → repositories), BaseController pattern, error handling, performance monitoring, testing strategies, and migration from legacy patterns. | `skills/backend-dev-guidelines` |
|
||||
| **backend-patterns** | Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes. | `skills/cc-skill-backend-patterns` |
|
||||
| **bash-linux** | Bash/Linux terminal patterns. Critical commands, piping, error handling, scripting. Use when working on macOS or Linux systems. | `skills/bash-linux` |
|
||||
| **behavioral-modes** | AI operational modes (brainstorm, implement, debug, review, teach, ship, orchestrate). Use to adapt behavior based on task type. | `skills/behavioral-modes` |
|
||||
| **blockrun** | Use when user needs capabilities Claude lacks (image generation, real-time X/Twitter data) or explicitly requests external models ("blockrun", "use grok", "use gpt", "dall-e", "deepseek") | `skills/blockrun` |
|
||||
| **brainstorming** | "You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation." | `skills/brainstorming` |
|
||||
| **brand-guidelines** | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply. | `skills/brand-guidelines-community` |
|
||||
| **brand-guidelines** | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply. | `skills/brand-guidelines-anthropic` |
|
||||
| **browser-automation** | "Browser automation powers web testing, scraping, and AI agent interactions. The difference between a flaky script and a reliable system comes down to understanding selectors, waiting strategies, and anti-detection patterns. This skill covers Playwright (recommended) and Puppeteer, with patterns for testing, scraping, and agentic browser control. Key insight: Playwright won the framework war. Unless you need Puppeteer's stealth ecosystem or are Chrome-only, Playwright is the better choice in 202" | `skills/browser-automation` |
|
||||
| **browser-extension-builder** | "Expert in building browser extensions that solve real problems - Chrome, Firefox, and cross-browser extensions. Covers extension architecture, manifest v3, content scripts, popup UIs, monetization strategies, and Chrome Web Store publishing. Use when: browser extension, chrome extension, firefox addon, extension, manifest v3." | `skills/browser-extension-builder` |
|
||||
| **bullmq-specialist** | "BullMQ expert for Redis-backed job queues, background processing, and reliable async execution in Node.js/TypeScript applications. Use when: bullmq, bull queue, redis queue, background job, job queue." | `skills/bullmq-specialist` |
|
||||
| **bun-development** | "Modern JavaScript/TypeScript development with Bun runtime. Covers package management, bundling, testing, and migration from Node.js. Use when working with Bun, optimizing JS/TS development speed, or migrating from Node.js to Bun." | `skills/bun-development` |
|
||||
| **canvas-design** | Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations. | `skills/canvas-design` |
|
||||
| **cc-skill-continuous-learning** | Development skill from everything-claude-code | `skills/cc-skill-continuous-learning` |
|
||||
| **cc-skill-project-guidelines-example** | Project Guidelines Skill (Example) | `skills/cc-skill-project-guidelines-example` |
|
||||
| **cc-skill-strategic-compact** | Development skill from everything-claude-code | `skills/cc-skill-strategic-compact` |
|
||||
| **clean-code** | Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments | `skills/clean-code` |
|
||||
| **clerk-auth** | "Expert patterns for Clerk auth implementation, middleware, organizations, webhooks, and user sync Use when: adding authentication, clerk auth, user authentication, sign in, sign up." | `skills/clerk-auth` |
|
||||
| **clickhouse-io** | ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads. | `skills/cc-skill-clickhouse-io` |
|
||||
| **code-review-checklist** | Code review guidelines covering code quality, security, and best practices. | `skills/code-review-checklist` |
|
||||
| **coding-standards** | Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development. | `skills/cc-skill-coding-standards` |
|
||||
| **competitor-alternatives** | "When the user wants to create competitor comparison or alternative pages for SEO and sales enablement. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' or 'competitive landing pages.' Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. Emphasizes deep research, modular content architecture, and varied section types beyond feature tables." | `skills/competitor-alternatives` |
|
||||
| **computer-use-agents** | "Build AI agents that interact with computers like humans do - viewing screens, moving cursors, clicking buttons, and typing text. Covers Anthropic's Computer Use, OpenAI's Operator/CUA, and open-source alternatives. Critical focus on sandboxing, security, and handling the unique challenges of vision-based control. Use when: computer use, desktop automation agent, screen control AI, vision-based agent, GUI automation." | `skills/computer-use-agents` |
|
||||
| **concise-planning** | Use when a user asks for a plan for a coding task, to generate a clear, actionable, and atomic checklist. | `skills/concise-planning` |
|
||||
| **content-creator** | Create SEO-optimized marketing content with consistent brand voice. Includes brand voice analyzer, SEO optimizer, content frameworks, and social media templates. Use when writing blog posts, creating social media content, analyzing brand voice, optimizing SEO, planning content calendars, or when user mentions content creation, brand voice, SEO optimization, social media marketing, or content strategy. | `skills/content-creator` |
|
||||
| **context-window-management** | "Strategies for managing LLM context windows including summarization, trimming, routing, and avoiding context rot Use when: context window, token limit, context management, context engineering, long context." | `skills/context-window-management` |
|
||||
| **conversation-memory** | "Persistent memory systems for LLM conversations including short-term, long-term, and entity-based memory Use when: conversation memory, remember, memory persistence, long-term memory, chat history." | `skills/conversation-memory` |
|
||||
| **copy-editing** | "When the user wants to edit, review, or improve existing marketing copy. Also use when the user mentions 'edit this copy,' 'review my copy,' 'copy feedback,' 'proofread,' 'polish this,' 'make this better,' or 'copy sweep.' This skill provides a systematic approach to editing marketing copy through multiple focused passes." | `skills/copy-editing` |
|
||||
| **copywriting** | When the user wants to write, rewrite, or improve marketing copy for any page — including homepage, landing pages, pricing pages, feature pages, about pages, or product pages. Also use when the user says "write copy for," "improve this copy," "rewrite this page," "marketing copy," "headline help," or "CTA copy." For email copy, see email-sequence. For popup copy, see popup-cro. | `skills/copywriting` |
|
||||
| **core-components** | Core component library and design system patterns. Use when building UI, using design tokens, or working with the component library. | `skills/core-components` |
|
||||
| **crewai** | "Expert in CrewAI - the leading role-based multi-agent framework used by 60% of Fortune 500 companies. Covers agent design with roles and goals, task definition, crew orchestration, process types (sequential, hierarchical, parallel), memory systems, and flows for complex workflows. Essential for building collaborative AI agent teams. Use when: crewai, multi-agent team, agent roles, crew of agents, role-based agents." | `skills/crewai` |
|
||||
| **d3-viz** | Creating interactive data visualisations using d3.js. This skill should be used when creating custom charts, graphs, network diagrams, geographic visualisations, or any complex SVG-based data visualisation that requires fine-grained control over visual elements, transitions, or interactions. Use this for bespoke visualisations beyond standard charting libraries, whether in React, Vue, Svelte, vanilla JavaScript, or any other environment. | `skills/claude-d3js-skill` |
|
||||
| **database-design** | Database design principles and decision-making. Schema design, indexing strategy, ORM selection, serverless databases. | `skills/database-design` |
|
||||
| **deployment-procedures** | Production deployment principles and decision-making. Safe deployment workflows, rollback strategies, and verification. Teaches thinking, not scripts. | `skills/deployment-procedures` |
|
||||
| **discord-bot-architect** | "Specialized skill for building production-ready Discord bots. Covers Discord.js (JavaScript) and Pycord (Python), gateway intents, slash commands, interactive components, rate limiting, and sharding." | `skills/discord-bot-architect` |
|
||||
| **dispatching-parallel-agents** | Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies | `skills/dispatching-parallel-agents` |
|
||||
| **doc-coauthoring** | Guide users through a structured workflow for co-authoring documentation. Use when user wants to write documentation, proposals, technical specs, decision docs, or similar structured content. This workflow helps users efficiently transfer context, refine content through iteration, and verify the doc works for readers. Trigger when user mentions writing docs, creating proposals, drafting specs, or similar documentation tasks. | `skills/doc-coauthoring` |
|
||||
| **docker-expert** | Docker containerization expert with deep knowledge of multi-stage builds, image optimization, container security, Docker Compose orchestration, and production deployment patterns. Use PROACTIVELY for Dockerfile optimization, container issues, image size problems, security hardening, networking, and orchestration challenges. | `skills/docker-expert` |
|
||||
| **documentation-templates** | Documentation templates and structure guidelines. README, API docs, code comments, and AI-friendly documentation. | `skills/documentation-templates` |
|
||||
| **docx** | "Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks" | `skills/docx-official` |
|
||||
| **email-sequence** | When the user wants to create or optimize an email sequence, drip campaign, automated email flow, or lifecycle email program. Also use when the user mentions "email sequence," "drip campaign," "nurture sequence," "onboarding emails," "welcome sequence," "re-engagement emails," "email automation," or "lifecycle emails." For in-app onboarding, see onboarding-cro. | `skills/email-sequence` |
|
||||
| **email-systems** | "Email has the highest ROI of any marketing channel. $36 for every $1 spent. Yet most startups treat it as an afterthought - bulk blasts, no personalization, landing in spam folders. This skill covers transactional email that works, marketing automation that converts, deliverability that reaches inboxes, and the infrastructure decisions that scale. Use when: keywords, file_patterns, code_patterns." | `skills/email-systems` |
|
||||
| **executing-plans** | Use when you have a written implementation plan to execute in a separate session with review checkpoints | `skills/executing-plans` |
|
||||
| **file-organizer** | Intelligently organizes files and folders by understanding context, finding duplicates, and suggesting better organizational structures. Use when user wants to clean up directories, organize downloads, remove duplicates, or restructure projects. | `skills/file-organizer` |
|
||||
| **file-uploads** | "Expert at handling file uploads and cloud storage. Covers S3, Cloudflare R2, presigned URLs, multipart uploads, and image optimization. Knows how to handle large files without blocking. Use when: file upload, S3, R2, presigned URL, multipart." | `skills/file-uploads` |
|
||||
| **finishing-a-development-branch** | Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup | `skills/finishing-a-development-branch` |
|
||||
| **firebase** | "Firebase gives you a complete backend in minutes - auth, database, storage, functions, hosting. But the ease of setup hides real complexity. Security rules are your last line of defense, and they're often wrong. Firestore queries are limited, and you learn this after you've designed your data model. This skill covers Firebase Authentication, Firestore, Realtime Database, Cloud Functions, Cloud Storage, and Firebase Hosting. Key insight: Firebase is optimized for read-heavy, denormalized data. I" | `skills/firebase` |
|
||||
| **form-cro** | When the user wants to optimize any form that is NOT signup/registration — including lead capture forms, contact forms, demo request forms, application forms, survey forms, or checkout forms. Also use when the user mentions "form optimization," "lead form conversions," "form friction," "form fields," "form completion rate," or "contact form." For signup/registration forms, see signup-flow-cro. For popups containing forms, see popup-cro. | `skills/form-cro` |
|
||||
| **free-tool-strategy** | When the user wants to plan, evaluate, or build a free tool for marketing purposes — lead generation, SEO value, or brand awareness. Also use when the user mentions "engineering as marketing," "free tool," "marketing tool," "calculator," "generator," "interactive tool," "lead gen tool," "build a tool for leads," or "free resource." This skill bridges engineering and marketing — useful for founders and technical marketers. | `skills/free-tool-strategy` |
|
||||
| **frontend-design** | Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics. | `skills/frontend-design` |
|
||||
| **frontend-dev-guidelines** | Frontend development guidelines for React/TypeScript applications. Modern patterns including Suspense, lazy loading, useSuspenseQuery, file organization with features directory, MUI v7 styling, TanStack Router, performance optimization, and TypeScript best practices. Use when creating components, pages, features, fetching data, styling, routing, or working with frontend code. | `skills/frontend-dev-guidelines` |
|
||||
| **frontend-patterns** | Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices. | `skills/cc-skill-frontend-patterns` |
|
||||
| **game-art** | Game art principles. Visual style selection, asset pipeline, animation workflow. | `skills/game-development/game-art` |
|
||||
| **game-audio** | Game audio principles. Sound design, music integration, adaptive audio systems. | `skills/game-development/game-audio` |
|
||||
| **game-design** | Game design principles. GDD structure, balancing, player psychology, progression. | `skills/game-development/game-design` |
|
||||
| **game-development** | Game development orchestrator. Routes to platform-specific skills based on project needs. | `skills/game-development` |
|
||||
| **gcp-cloud-run** | "Specialized skill for building production-ready serverless applications on GCP. Covers Cloud Run services (containerized), Cloud Run Functions (event-driven), cold start optimization, and event-driven architecture with Pub/Sub." | `skills/gcp-cloud-run` |
|
||||
| **geo-fundamentals** | Generative Engine Optimization for AI search engines (ChatGPT, Claude, Perplexity). | `skills/geo-fundamentals` |
|
||||
| **git-pushing** | Stage, commit, and push git changes with conventional commit messages. Use when user wants to commit and push changes, mentions pushing to remote, or asks to save and push their work. Also activates when user says "push changes", "commit and push", "push this", "push to github", or similar git workflow requests. | `skills/git-pushing` |
|
||||
| **github-workflow-automation** | "Automate GitHub workflows with AI assistance. Includes PR reviews, issue triage, CI/CD integration, and Git operations. Use when automating GitHub workflows, setting up PR review automation, creating GitHub Actions, or triaging issues." | `skills/github-workflow-automation` |
|
||||
| **graphql** | "GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully." | `skills/graphql` |
|
||||
| **hubspot-integration** | "Expert patterns for HubSpot CRM integration including OAuth authentication, CRM objects, associations, batch operations, webhooks, and custom objects. Covers Node.js and Python SDKs. Use when: hubspot, hubspot api, hubspot crm, hubspot integration, contacts api." | `skills/hubspot-integration` |
|
||||
| **i18n-localization** | Internationalization and localization patterns. Detecting hardcoded strings, managing translations, locale files, RTL support. | `skills/i18n-localization` |
|
||||
| **inngest** | "Inngest expert for serverless-first background jobs, event-driven workflows, and durable execution without managing queues or workers. Use when: inngest, serverless background job, event-driven workflow, step function, durable execution." | `skills/inngest` |
|
||||
| **interactive-portfolio** | "Expert in building portfolios that actually land jobs and clients - not just showing work, but creating memorable experiences. Covers developer portfolios, designer portfolios, creative portfolios, and portfolios that convert visitors into opportunities. Use when: portfolio, personal website, showcase work, developer portfolio, designer portfolio." | `skills/interactive-portfolio` |
|
||||
| **internal-comms** | A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.). | `skills/internal-comms-anthropic` |
|
||||
| **internal-comms** | A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.). | `skills/internal-comms-community` |
|
||||
| **javascript-mastery** | "Comprehensive JavaScript reference covering 33+ essential concepts every developer should know. From fundamentals like primitives and closures to advanced patterns like async/await and functional programming. Use when explaining JS concepts, debugging JavaScript issues, or teaching JavaScript fundamentals." | `skills/javascript-mastery` |
|
||||
| **kaizen** | Guide for continuous improvement, error proofing, and standardization. Use this skill when the user wants to improve code quality, refactor, or discuss process improvements. | `skills/kaizen` |
|
||||
| **langfuse** | "Expert in Langfuse - the open-source LLM observability platform. Covers tracing, prompt management, evaluation, datasets, and integration with LangChain, LlamaIndex, and OpenAI. Essential for debugging, monitoring, and improving LLM applications in production. Use when: langfuse, llm observability, llm tracing, prompt management, llm evaluation." | `skills/langfuse` |
|
||||
| **langgraph** | "Expert in LangGraph - the production-grade framework for building stateful, multi-actor AI applications. Covers graph construction, state management, cycles and branches, persistence with checkpointers, human-in-the-loop patterns, and the ReAct agent pattern. Used in production at LinkedIn, Uber, and 400+ companies. This is LangChain's recommended approach for building agents. Use when: langgraph, langchain agent, stateful agent, agent graph, react agent." | `skills/langgraph` |
|
||||
| **launch-strategy** | "When the user wants to plan a product launch, feature announcement, or release strategy. Also use when the user mentions 'launch,' 'Product Hunt,' 'feature release,' 'announcement,' 'go-to-market,' 'beta launch,' 'early access,' 'waitlist,' or 'product update.' This skill covers phased launches, channel strategy, and ongoing launch momentum." | `skills/launch-strategy` |
|
||||
| **lint-and-validate** | Automatic quality control, linting, and static analysis procedures. Use after every code modification to ensure syntax correctness and project standards. Triggers onKeywords: lint, format, check, validate, types, static analysis. | `skills/lint-and-validate` |
|
||||
| **llm-app-patterns** | "Production-ready patterns for building LLM applications. Covers RAG pipelines, agent architectures, prompt IDEs, and LLMOps monitoring. Use when designing AI applications, implementing RAG, building agents, or setting up LLM observability." | `skills/llm-app-patterns` |
|
||||
| **loki-mode** | Multi-agent autonomous startup system for Claude Code. Triggers on "Loki Mode". Orchestrates 100+ specialized agents across engineering, QA, DevOps, security, data/ML, business operations, marketing, HR, and customer success. Takes PRD to fully deployed, revenue-generating product with zero human intervention. Features Task tool for subagent dispatch, parallel code review with 3 specialized reviewers, severity-based issue triage, distributed task queue with dead letter handling, automatic deployment to cloud providers, A/B testing, customer feedback loops, incident response, circuit breakers, and self-healing. Handles rate limits via distributed state checkpoints and auto-resume with exponential backoff. Requires --dangerously-skip-permissions flag. | `skills/loki-mode` |
|
||||
| **marketing-ideas** | "When the user needs marketing ideas, inspiration, or strategies for their SaaS or software product. Also use when the user asks for 'marketing ideas,' 'growth ideas,' 'how to market,' 'marketing strategies,' 'marketing tactics,' 'ways to promote,' or 'ideas to grow.' This skill provides 140 proven marketing approaches organized by category." | `skills/marketing-ideas` |
|
||||
| **marketing-psychology** | "When the user wants to apply psychological principles, mental models, or behavioral science to marketing. Also use when the user mentions 'psychology,' 'mental models,' 'cognitive bias,' 'persuasion,' 'behavioral science,' 'why people buy,' 'decision-making,' or 'consumer behavior.' This skill provides 70+ mental models organized for marketing application." | `skills/marketing-psychology` |
|
||||
| **mcp-builder** | Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK). | `skills/mcp-builder` |
|
||||
| **micro-saas-launcher** | "Expert in launching small, focused SaaS products fast - the indie hacker approach to building profitable software. Covers idea validation, MVP development, pricing, launch strategies, and growing to sustainable revenue. Ship in weeks, not months. Use when: micro saas, indie hacker, small saas, side project, saas mvp." | `skills/micro-saas-launcher` |
|
||||
| **mobile-design** | Mobile-first design thinking and decision-making for iOS and Android apps. Touch interaction, performance patterns, platform conventions. Teaches principles, not fixed values. Use when building React Native, Flutter, or native mobile apps. | `skills/mobile-design` |
|
||||
| **mobile-games** | Mobile game development principles. Touch input, battery, performance, app stores. | `skills/game-development/mobile-games` |
|
||||
| **moodle-external-api-development** | Create custom external web service APIs for Moodle LMS. Use when implementing web services for course management, user tracking, quiz operations, or custom plugin functionality. Covers parameter validation, database operations, error handling, service registration, and Moodle coding standards. | `skills/moodle-external-api-development` |
|
||||
| **multiplayer** | Multiplayer game development principles. Architecture, networking, synchronization. | `skills/game-development/multiplayer` |
|
||||
| **neon-postgres** | "Expert patterns for Neon serverless Postgres, branching, connection pooling, and Prisma/Drizzle integration Use when: neon database, serverless postgres, database branching, neon postgres, postgres serverless." | `skills/neon-postgres` |
|
||||
| **nestjs-expert** | Nest.js framework expert specializing in module architecture, dependency injection, middleware, guards, interceptors, testing with Jest/Supertest, TypeORM/Mongoose integration, and Passport.js authentication. Use PROACTIVELY for any Nest.js application issues including architecture decisions, testing strategies, performance optimization, or debugging complex dependency injection problems. If a specialized expert is a better fit, I will recommend switching and stop. | `skills/nestjs-expert` |
|
||||
| **nextjs-best-practices** | Next.js App Router principles. Server Components, data fetching, routing patterns. | `skills/nextjs-best-practices` |
|
||||
| **nextjs-supabase-auth** | "Expert integration of Supabase Auth with Next.js App Router Use when: supabase auth next, authentication next.js, login supabase, auth middleware, protected route." | `skills/nextjs-supabase-auth` |
|
||||
| **nodejs-best-practices** | Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying. | `skills/nodejs-best-practices` |
|
||||
| **notebooklm** | Use this skill to query your Google NotebookLM notebooks directly from Claude Code for source-grounded, citation-backed answers from Gemini. Browser automation, library management, persistent auth. Drastically reduced hallucinations through document-only responses. | `skills/notebooklm` |
|
||||
| **notion-template-business** | "Expert in building and selling Notion templates as a business - not just making templates, but building a sustainable digital product business. Covers template design, pricing, marketplaces, marketing, and scaling to real revenue. Use when: notion template, sell templates, digital product, notion business, gumroad." | `skills/notion-template-business` |
|
||||
| **onboarding-cro** | When the user wants to optimize post-signup onboarding, user activation, first-run experience, or time-to-value. Also use when the user mentions "onboarding flow," "activation rate," "user activation," "first-run experience," "empty states," "onboarding checklist," "aha moment," or "new user experience." For signup/registration optimization, see signup-flow-cro. For ongoing email sequences, see email-sequence. | `skills/onboarding-cro` |
|
||||
| **page-cro** | When the user wants to optimize, improve, or increase conversions on any marketing page — including homepage, landing pages, pricing pages, feature pages, or blog posts. Also use when the user says "CRO," "conversion rate optimization," "this page isn't converting," "improve conversions," or "why isn't this page working." For signup/registration flows, see signup-flow-cro. For post-signup activation, see onboarding-cro. For forms outside of signup, see form-cro. For popups/modals, see popup-cro. | `skills/page-cro` |
|
||||
| **paid-ads** | "When the user wants help with paid advertising campaigns on Google Ads, Meta (Facebook/Instagram), LinkedIn, Twitter/X, or other ad platforms. Also use when the user mentions 'PPC,' 'paid media,' 'ad copy,' 'ad creative,' 'ROAS,' 'CPA,' 'ad campaign,' 'retargeting,' or 'audience targeting.' This skill covers campaign strategy, ad creation, audience targeting, and optimization." | `skills/paid-ads` |
|
||||
| **parallel-agents** | Multi-agent orchestration patterns. Use when multiple independent tasks can run with different domain expertise or when comprehensive analysis requires multiple perspectives. | `skills/parallel-agents` |
|
||||
| **paywall-upgrade-cro** | When the user wants to create or optimize in-app paywalls, upgrade screens, upsell modals, or feature gates. Also use when the user mentions "paywall," "upgrade screen," "upgrade modal," "upsell," "feature gate," "convert free to paid," "freemium conversion," "trial expiration screen," "limit reached screen," "plan upgrade prompt," or "in-app pricing." Distinct from public pricing pages (see page-cro) — this skill focuses on in-product upgrade moments where the user has already experienced value. | `skills/paywall-upgrade-cro` |
|
||||
| **pc-games** | PC and console game development principles. Engine selection, platform features, optimization strategies. | `skills/game-development/pc-games` |
|
||||
| **pdf** | Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. When Claude needs to fill in a PDF form or programmatically process, generate, or analyze PDF documents at scale. | `skills/pdf-official` |
|
||||
| **performance-profiling** | Performance profiling principles. Measurement, analysis, and optimization techniques. | `skills/performance-profiling` |
|
||||
| **personal-tool-builder** | "Expert in building custom tools that solve your own problems first. The best products often start as personal tools - scratch your own itch, build for yourself, then discover others have the same itch. Covers rapid prototyping, local-first apps, CLI tools, scripts that grow into products, and the art of dogfooding. Use when: build a tool, personal tool, scratch my itch, solve my problem, CLI tool." | `skills/personal-tool-builder` |
|
||||
| **plaid-fintech** | "Expert patterns for Plaid API integration including Link token flows, transactions sync, identity verification, Auth for ACH, balance checks, webhook handling, and fintech compliance best practices. Use when: plaid, bank account linking, bank connection, ach, account aggregation." | `skills/plaid-fintech` |
|
||||
| **plan-writing** | Structured task planning with clear breakdowns, dependencies, and verification criteria. Use when implementing features, refactoring, or any multi-step work. | `skills/plan-writing` |
|
||||
| **planning-with-files** | Implements Manus-style file-based planning for complex tasks. Creates task_plan.md, findings.md, and progress.md. Use when starting complex multi-step tasks, research projects, or any task requiring >5 tool calls. | `skills/planning-with-files` |
|
||||
| **playwright-skill** | Complete browser automation with Playwright. Auto-detects dev servers, writes clean test scripts to /tmp. Test pages, fill forms, take screenshots, check responsive design, validate UX, test login flows, check links, automate any browser task. Use when user wants to test websites, automate browser interactions, validate web functionality, or perform any browser-based testing. | `skills/playwright-skill` |
|
||||
| **popup-cro** | When the user wants to create or optimize popups, modals, overlays, slide-ins, or banners for conversion purposes. Also use when the user mentions "exit intent," "popup conversions," "modal optimization," "lead capture popup," "email popup," "announcement banner," or "overlay." For forms outside of popups, see form-cro. For general page conversion optimization, see page-cro. | `skills/popup-cro` |
|
||||
| **powershell-windows** | PowerShell Windows patterns. Critical pitfalls, operator syntax, error handling. | `skills/powershell-windows` |
|
||||
| **pptx** | "Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks" | `skills/pptx-official` |
|
||||
| **pricing-strategy** | "When the user wants help with pricing decisions, packaging, or monetization strategy. Also use when the user mentions 'pricing,' 'pricing tiers,' 'freemium,' 'free trial,' 'packaging,' 'price increase,' 'value metric,' 'Van Westendorp,' 'willingness to pay,' or 'monetization.' This skill covers pricing research, tier structure, and packaging strategy." | `skills/pricing-strategy` |
|
||||
| **prisma-expert** | Prisma ORM expert for schema design, migrations, query optimization, relations modeling, and database operations. Use PROACTIVELY for Prisma schema issues, migration problems, query performance, relation design, or database connection issues. | `skills/prisma-expert` |
|
||||
| **product-manager-toolkit** | Comprehensive toolkit for product managers including RICE prioritization, customer interview analysis, PRD templates, discovery frameworks, and go-to-market strategies. Use for feature prioritization, user research synthesis, requirement documentation, and product strategy development. | `skills/product-manager-toolkit` |
|
||||
| **programmatic-seo** | When the user wants to create SEO-driven pages at scale using templates and data. Also use when the user mentions "programmatic SEO," "template pages," "pages at scale," "directory pages," "location pages," "[keyword] + [city] pages," "comparison pages," "integration pages," or "building many pages for SEO." For auditing existing SEO issues, see seo-audit. | `skills/programmatic-seo` |
|
||||
| **prompt-caching** | "Caching strategies for LLM prompts including Anthropic prompt caching, response caching, and CAG (Cache Augmented Generation) Use when: prompt caching, cache prompt, response cache, cag, cache augmented." | `skills/prompt-caching` |
|
||||
| **prompt-engineer** | "Expert in designing effective prompts for LLM-powered applications. Masters prompt structure, context management, output formatting, and prompt evaluation. Use when: prompt engineering, system prompt, few-shot, chain of thought, prompt design." | `skills/prompt-engineer` |
|
||||
| **prompt-engineering** | Expert guide on prompt engineering patterns, best practices, and optimization techniques. Use when user wants to improve prompts, learn prompting strategies, or debug agent behavior. | `skills/prompt-engineering` |
|
||||
| **prompt-library** | "Curated collection of high-quality prompts for various use cases. Includes role-based prompts, task-specific templates, and prompt refinement techniques. Use when user needs prompt templates, role-play prompts, or ready-to-use prompt examples for coding, writing, analysis, or creative tasks." | `skills/prompt-library` |
|
||||
| **python-patterns** | Python development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying. | `skills/python-patterns` |
|
||||
| **rag-engineer** | "Expert in building Retrieval-Augmented Generation systems. Masters embedding models, vector databases, chunking strategies, and retrieval optimization for LLM applications. Use when: building RAG, vector search, embeddings, semantic search, document retrieval." | `skills/rag-engineer` |
|
||||
| **rag-implementation** | "Retrieval-Augmented Generation patterns including chunking, embeddings, vector stores, and retrieval optimization Use when: rag, retrieval augmented, vector search, embeddings, semantic search." | `skills/rag-implementation` |
|
||||
| **react-patterns** | Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices. | `skills/react-patterns` |
|
||||
| **react-ui-patterns** | Modern React UI patterns for loading states, error handling, and data fetching. Use when building UI components, handling async data, or managing UI states. | `skills/react-ui-patterns` |
|
||||
| **receiving-code-review** | Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation | `skills/receiving-code-review` |
|
||||
| **red-team-tactics** | Red team tactics principles based on MITRE ATT&CK. Attack phases, detection evasion, reporting. | `skills/red-team-tactics` |
|
||||
| **referral-program** | "When the user wants to create, optimize, or analyze a referral program, affiliate program, or word-of-mouth strategy. Also use when the user mentions 'referral,' 'affiliate,' 'ambassador,' 'word of mouth,' 'viral loop,' 'refer a friend,' or 'partner program.' This skill covers program design, incentive structure, and growth optimization." | `skills/referral-program` |
|
||||
| **remotion-best-practices** | Best practices for Remotion - Video creation in React | `skills/remotion-best-practices` |
|
||||
| **requesting-code-review** | Use when completing tasks, implementing major features, or before merging to verify work meets requirements | `skills/requesting-code-review` |
|
||||
| **research-engineer** | "An uncompromising Academic Research Engineer. Operates with absolute scientific rigor, objective criticism, and zero flair. Focuses on theoretical correctness, formal verification, and optimal implementation across any required technology." | `skills/research-engineer` |
|
||||
| **salesforce-development** | "Expert patterns for Salesforce platform development including Lightning Web Components (LWC), Apex triggers and classes, REST/Bulk APIs, Connected Apps, and Salesforce DX with scratch orgs and 2nd generation packages (2GP). Use when: salesforce, sfdc, apex, lwc, lightning web components." | `skills/salesforce-development` |
|
||||
| **schema-markup** | When the user wants to add, fix, or optimize schema markup and structured data on their site. Also use when the user mentions "schema markup," "structured data," "JSON-LD," "rich snippets," "schema.org," "FAQ schema," "product schema," "review schema," or "breadcrumb schema." For broader SEO issues, see seo-audit. | `skills/schema-markup` |
|
||||
| **scroll-experience** | "Expert in building immersive scroll-driven experiences - parallax storytelling, scroll animations, interactive narratives, and cinematic web experiences. Like NY Times interactives, Apple product pages, and award-winning web experiences. Makes websites feel like experiences, not just pages. Use when: scroll animation, parallax, scroll storytelling, interactive story, cinematic website." | `skills/scroll-experience` |
|
||||
| **security-review** | Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns. | `skills/cc-skill-security-review` |
|
||||
| **segment-cdp** | "Expert patterns for Segment Customer Data Platform including Analytics.js, server-side tracking, tracking plans with Protocols, identity resolution, destinations configuration, and data governance best practices. Use when: segment, analytics.js, customer data platform, cdp, tracking plan." | `skills/segment-cdp` |
|
||||
| **senior-architect** | Comprehensive software architecture skill for designing scalable, maintainable systems using ReactJS, NextJS, NodeJS, Express, React Native, Swift, Kotlin, Flutter, Postgres, GraphQL, Go, Python. Includes architecture diagram generation, system design patterns, tech stack decision frameworks, and dependency analysis. Use when designing system architecture, making technical decisions, creating architecture diagrams, evaluating trade-offs, or defining integration patterns. | `skills/senior-architect` |
|
||||
| **senior-fullstack** | Comprehensive fullstack development skill for building complete web applications with React, Next.js, Node.js, GraphQL, and PostgreSQL. Includes project scaffolding, code quality analysis, architecture patterns, and complete tech stack guidance. Use when building new projects, analyzing code quality, implementing design patterns, or setting up development workflows. | `skills/senior-fullstack` |
|
||||
| **seo-audit** | When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," or "SEO health check." For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema-markup. | `skills/seo-audit` |
|
||||
| **seo-fundamentals** | SEO fundamentals, E-E-A-T, Core Web Vitals, and Google algorithm principles. | `skills/seo-fundamentals` |
|
||||
| **server-management** | Server management principles and decision-making. Process management, monitoring strategy, and scaling decisions. Teaches thinking, not commands. | `skills/server-management` |
|
||||
| **shopify-apps** | "Expert patterns for Shopify app development including Remix/React Router apps, embedded apps with App Bridge, webhook handling, GraphQL Admin API, Polaris components, billing, and app extensions. Use when: shopify app, shopify, embedded app, polaris, app bridge." | `skills/shopify-apps` |
|
||||
| **shopify-development** | \| | `skills/shopify-development` |
|
||||
| **signup-flow-cro** | When the user wants to optimize signup, registration, account creation, or trial activation flows. Also use when the user mentions "signup conversions," "registration friction," "signup form optimization," "free trial signup," "reduce signup dropoff," or "account creation flow." For post-signup onboarding, see onboarding-cro. For lead capture forms (not account creation), see form-cro. | `skills/signup-flow-cro` |
|
||||
| **skill-creator** | Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations. | `skills/skill-creator` |
|
||||
| **skill-developer** | Create and manage Claude Code skills following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns, file paths, content patterns), enforcement levels (block, suggest, warn), hook mechanisms (UserPromptSubmit, PreToolUse), session tracking, and the 500-line rule. | `skills/skill-developer` |
|
||||
| **slack-bot-builder** | "Build Slack apps using the Bolt framework across Python, JavaScript, and Java. Covers Block Kit for rich UIs, interactive components, slash commands, event handling, OAuth installation flows, and Workflow Builder integration. Focus on best practices for production-ready Slack apps. Use when: slack bot, slack app, bolt framework, block kit, slash command." | `skills/slack-bot-builder` |
|
||||
| **slack-gif-creator** | Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a GIF of X doing Y for Slack." | `skills/slack-gif-creator` |
|
||||
| **social-content** | "When the user wants help creating, scheduling, or optimizing social media content for LinkedIn, Twitter/X, Instagram, TikTok, Facebook, or other platforms. Also use when the user mentions 'LinkedIn post,' 'Twitter thread,' 'social media,' 'content calendar,' 'social scheduling,' 'engagement,' or 'viral content.' This skill covers content creation, repurposing, and platform-specific strategies." | `skills/social-content` |
|
||||
| **software-architecture** | Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code, in any case that relates to software development. | `skills/software-architecture` |
|
||||
| **stripe-integration** | "Get paid from day one. Payments, subscriptions, billing portal, webhooks, metered billing, Stripe Connect. The complete guide to implementing Stripe correctly, including all the edge cases that will bite you at 3am. This isn't just API calls - it's the full payment system: handling failures, managing subscriptions, dealing with dunning, and keeping revenue flowing. Use when: stripe, payments, subscription, billing, checkout." | `skills/stripe-integration` |
|
||||
| **subagent-driven-development** | Use when executing implementation plans with independent tasks in the current session | `skills/subagent-driven-development` |
|
||||
| **systematic-debugging** | Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes | `skills/systematic-debugging` |
|
||||
| **tailwind-patterns** | Tailwind CSS v4 principles. CSS-first configuration, container queries, modern patterns, design token architecture. | `skills/tailwind-patterns` |
|
||||
| **tdd-workflow** | Test-Driven Development workflow principles. RED-GREEN-REFACTOR cycle. | `skills/tdd-workflow` |
|
||||
| **telegram-bot-builder** | "Expert in building Telegram bots that solve real problems - from simple automation to complex AI-powered bots. Covers bot architecture, the Telegram Bot API, user experience, monetization strategies, and scaling bots to thousands of users. Use when: telegram bot, bot api, telegram automation, chat bot telegram, tg bot." | `skills/telegram-bot-builder` |
|
||||
| **telegram-mini-app** | "Expert in building Telegram Mini Apps (TWA) - web apps that run inside Telegram with native-like experience. Covers the TON ecosystem, Telegram Web App API, payments, user authentication, and building viral mini apps that monetize. Use when: telegram mini app, TWA, telegram web app, TON app, mini app." | `skills/telegram-mini-app` |
|
||||
| **templates** | Project scaffolding templates for new applications. Use when creating new projects from scratch. Contains 12 templates for various tech stacks. | `skills/app-builder/templates` |
|
||||
| **test-driven-development** | Use when implementing any feature or bugfix, before writing implementation code | `skills/test-driven-development` |
|
||||
| **test-fixing** | Run tests and systematically fix all failing tests using smart error grouping. Use when user asks to fix failing tests, mentions test failures, runs test suite and failures occur, or requests to make tests pass. | `skills/test-fixing` |
|
||||
| **testing-patterns** | Jest testing patterns, factory functions, mocking strategies, and TDD workflow. Use when writing unit tests, creating test factories, or following TDD red-green-refactor cycle. | `skills/testing-patterns` |
|
||||
| **theme-factory** | Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly. | `skills/theme-factory` |
|
||||
| **trigger-dev** | "Trigger.dev expert for background jobs, AI workflows, and reliable async execution with excellent developer experience and TypeScript-first design. Use when: trigger.dev, trigger dev, background task, ai background job, long running task." | `skills/trigger-dev` |
|
||||
| **twilio-communications** | "Build communication features with Twilio: SMS messaging, voice calls, WhatsApp Business API, and user verification (2FA). Covers the full spectrum from simple notifications to complex IVR systems and multi-channel authentication. Critical focus on compliance, rate limits, and error handling. Use when: twilio, send SMS, text message, voice call, phone verification." | `skills/twilio-communications` |
|
||||
| **typescript-expert** | >- | `skills/typescript-expert` |
|
||||
| **ui-ux-pro-max** | "UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 9 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples." | `skills/ui-ux-pro-max` |
|
||||
| **upstash-qstash** | "Upstash QStash expert for serverless message queues, scheduled jobs, and reliable HTTP-based task delivery without managing infrastructure. Use when: qstash, upstash queue, serverless cron, scheduled http, message queue serverless." | `skills/upstash-qstash` |
|
||||
| **using-git-worktrees** | Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification | `skills/using-git-worktrees` |
|
||||
| **using-superpowers** | Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions | `skills/using-superpowers` |
|
||||
| **vercel-deployment** | "Expert knowledge for deploying to Vercel with Next.js Use when: vercel, deploy, deployment, hosting, production." | `skills/vercel-deployment` |
|
||||
| **vercel-react-best-practices** | React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements. | `skills/react-best-practices` |
|
||||
| **verification-before-completion** | Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always | `skills/verification-before-completion` |
|
||||
| **viral-generator-builder** | "Expert in building shareable generator tools that go viral - name generators, quiz makers, avatar creators, personality tests, and calculator tools. Covers the psychology of sharing, viral mechanics, and building tools people can't resist sharing with friends. Use when: generator tool, quiz maker, name generator, avatar creator, viral tool." | `skills/viral-generator-builder` |
|
||||
| **voice-agents** | "Voice agents represent the frontier of AI interaction - humans speaking naturally with AI systems. The challenge isn't just speech recognition and synthesis, it's achieving natural conversation flow with sub-800ms latency while handling interruptions, background noise, and emotional nuance. This skill covers two architectures: speech-to-speech (OpenAI Realtime API, lowest latency, most natural) and pipeline (STT→LLM→TTS, more control, easier to debug). Key insight: latency is the constraint. Hu" | `skills/voice-agents` |
|
||||
| **voice-ai-development** | "Expert in building voice AI applications - from real-time voice agents to voice-enabled apps. Covers OpenAI Realtime API, Vapi for voice agents, Deepgram for transcription, ElevenLabs for synthesis, LiveKit for real-time infrastructure, and WebRTC fundamentals. Knows how to build low-latency, production-ready voice experiences. Use when: voice ai, voice agent, speech to text, text to speech, realtime voice." | `skills/voice-ai-development` |
|
||||
| **vr-ar** | VR/AR development principles. Comfort, interaction, performance requirements. | `skills/game-development/vr-ar` |
|
||||
| **vulnerability-scanner** | Advanced vulnerability analysis principles. OWASP 2025, Supply Chain Security, attack surface mapping, risk prioritization. | `skills/vulnerability-scanner` |
|
||||
| **web-artifacts-builder** | Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts. | `skills/web-artifacts-builder` |
|
||||
| **web-design-guidelines** | Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices". | `skills/web-design-guidelines` |
|
||||
| **web-games** | Web browser game development principles. Framework selection, WebGPU, optimization, PWA. | `skills/game-development/web-games` |
|
||||
| **webapp-testing** | Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. | `skills/webapp-testing` |
|
||||
| **workflow-automation** | "Workflow automation is the infrastructure that makes AI agents reliable. Without durable execution, a network hiccup during a 10-step payment flow means lost money and angry customers. With it, workflows resume exactly where they left off. This skill covers the platforms (n8n, Temporal, Inngest) and patterns (sequential, parallel, orchestrator-worker) that turn brittle scripts into production-grade automation. Key insight: The platforms make different tradeoffs. n8n optimizes for accessibility" | `skills/workflow-automation` |
|
||||
| **writing-plans** | Use when you have a spec or requirements for a multi-step task, before touching code | `skills/writing-plans` |
|
||||
| **writing-skills** | Use when creating new skills, editing existing skills, or verifying skills work before deployment | `skills/writing-skills` |
|
||||
| **xlsx** | "Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas" | `skills/xlsx-official` |
|
||||
| **zapier-make-patterns** | "No-code automation democratizes workflow building. Zapier and Make (formerly Integromat) let non-developers automate business processes without writing code. But no-code doesn't mean no-complexity - these platforms have their own patterns, pitfalls, and breaking points. This skill covers when to use which platform, how to build reliable automations, and when to graduate to code-based solutions. Key insight: Zapier optimizes for simplicity and integrations (7000+ apps), Make optimizes for power " | `skills/zapier-make-patterns` |
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -378,6 +393,7 @@ This collection would not be possible without the incredible work of the Claude
|
||||
|
||||
- **[anthropics/skills](https://github.com/anthropics/skills)**: Official Anthropic skills repository - Document manipulation (DOCX, PDF, PPTX, XLSX), Brand Guidelines, Internal Communications.
|
||||
- **[anthropics/claude-cookbooks](https://github.com/anthropics/claude-cookbooks)**: Official notebooks and recipes for building with Claude.
|
||||
- **[remotion-dev/skills](https://github.com/remotion-dev/skills)**: Official Remotion skills - Video creation in React with 28 modular rules.
|
||||
- **[vercel-labs/agent-skills](https://github.com/vercel-labs/agent-skills)**: Vercel Labs official skills - React Best Practices, Web Design Guidelines.
|
||||
- **[openai/skills](https://github.com/openai/skills)**: OpenAI Codex skills catalog - Agent skills, Skill Creator, Concise Planning.
|
||||
|
||||
@@ -395,6 +411,8 @@ This collection would not be possible without the incredible work of the Claude
|
||||
- **[vibeforge1111/vibeship-spawner-skills](https://github.com/vibeforge1111/vibeship-spawner-skills)**: AI Agents, Integrations, Maker Tools (57 skills, Apache 2.0).
|
||||
- **[coreyhaines31/marketingskills](https://github.com/coreyhaines31/marketingskills)**: Marketing skills for CRO, copywriting, SEO, paid ads, and growth (23 skills, MIT).
|
||||
- **[vudovn/antigravity-kit](https://github.com/vudovn/antigravity-kit)**: AI Agent templates with Skills, Agents, and Workflows (33 skills, MIT).
|
||||
- **[affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code)**: Complete Claude Code configuration collection from Anthropic hackathon winner - skills only (8 skills, MIT).
|
||||
- **[webzler/agentMemory](https://github.com/webzler/agentMemory)**: Source for the agent-memory-mcp skill.
|
||||
|
||||
### Inspirations
|
||||
|
||||
|
||||
125
scripts/update_readme.py
Normal file
125
scripts/update_readme.py
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
||||
def update_readme():
|
||||
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
readme_path = os.path.join(base_dir, "README.md")
|
||||
index_path = os.path.join(base_dir, "skills_index.json")
|
||||
|
||||
print(f"📖 Reading skills index from: {index_path}")
|
||||
with open(index_path, 'r', encoding='utf-8') as f:
|
||||
skills = json.load(f)
|
||||
|
||||
total_skills = len(skills)
|
||||
print(f"🔢 Total skills found: {total_skills}")
|
||||
|
||||
print(f"📝 Updating README at: {readme_path}")
|
||||
with open(readme_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# 1. Update Title Count
|
||||
# Pattern: # 🌌 Antigravity Awesome Skills: [NUM]+ Agentic Skills
|
||||
content = re.sub(
|
||||
r'(# 🌌 Antigravity Awesome Skills: )\d+(\+ Agentic Skills)',
|
||||
f'\\g<1>{total_skills}\\g<2>',
|
||||
content
|
||||
)
|
||||
|
||||
# 2. Update Blockquote Count
|
||||
# Pattern: Collection of [NUM]+ Universal
|
||||
content = re.sub(
|
||||
r'(Collection of )\d+(\+ Universal)',
|
||||
f'\\g<1>{total_skills}\\g<2>',
|
||||
content
|
||||
)
|
||||
|
||||
# 3. Update Intro Text Count
|
||||
# Pattern: library of **[NUM] high-performance skills**
|
||||
content = re.sub(
|
||||
r'(library of \*\*)\d+( high-performance skills\*\*)',
|
||||
f'\\g<1>{total_skills}\\g<2>',
|
||||
content
|
||||
)
|
||||
|
||||
# 4. Update Registry Header Count
|
||||
# Pattern: ## Full Skill Registry ([NUM]/[NUM])
|
||||
content = re.sub(
|
||||
r'(## Full Skill Registry \()\d+/\d+(\))',
|
||||
f'\\g<1>{total_skills}/{total_skills}\\g<2>',
|
||||
content
|
||||
)
|
||||
|
||||
# 5. Generate New Registry Table
|
||||
print("🔄 Generating new registry table...")
|
||||
|
||||
# Store the Note block to preserve it
|
||||
note_pattern = r'(> \[!NOTE\].*?)\n\n\| Skill Name'
|
||||
note_match = re.search(note_pattern, content, re.DOTALL)
|
||||
note_block = ""
|
||||
if note_match:
|
||||
note_block = note_match.group(1)
|
||||
else:
|
||||
# Fallback default note if not found (though it should be there)
|
||||
note_block = "> [!NOTE] > **Document Skills**: We provide both **community** and **official Anthropic** versions for DOCX, PDF, PPTX, and XLSX. Locally, the official versions are used by default (via symlinks). In the repository, both versions are available for flexibility."
|
||||
|
||||
table_header = "| Skill Name | Description | Path |\n| :--- | :--- | :--- |"
|
||||
table_rows = []
|
||||
|
||||
for skill in skills:
|
||||
name = skill.get('name', 'Unknown')
|
||||
desc = skill.get('description', '').replace('\n', ' ').strip()
|
||||
path = skill.get('path', '')
|
||||
|
||||
# Escape pipes in description to strictly avoid breaking the table
|
||||
desc = desc.replace('|', '\|')
|
||||
|
||||
row = f"| **{name}** | {desc} | `{path}` |"
|
||||
table_rows.append(row)
|
||||
|
||||
new_table_section = f"{note_block}\n\n{table_header}\n" + "\n".join(table_rows)
|
||||
|
||||
# Replace the old table section
|
||||
# We look for the start of the section and the end (which is either the next H2 or EOF)
|
||||
# The section starts after "## Full Skill Registry (X/X)"
|
||||
|
||||
# First, find the header position
|
||||
header_pattern = r'## Full Skill Registry \(\d+/\d+\)'
|
||||
header_match = re.search(header_pattern, content)
|
||||
|
||||
if not header_match:
|
||||
print("❌ Could not find 'Full Skill Registry' header.")
|
||||
return
|
||||
|
||||
start_pos = header_match.end()
|
||||
|
||||
# Find the next section (## ...) or end of file
|
||||
next_section_match = re.search(r'\n## ', content[start_pos:])
|
||||
|
||||
if next_section_match:
|
||||
end_pos = start_pos + next_section_match.start()
|
||||
# Keep everything after the table
|
||||
rest_of_file = content[end_pos:]
|
||||
else:
|
||||
# Table goes to end of file
|
||||
rest_of_file = ""
|
||||
|
||||
# Check for text between Header and Table (usually just newlines or the Note)
|
||||
# We replace everything from Header End to Next Section with our New Table Section
|
||||
# but we need to supply the pre-table Note which we extracted/re-generated above.
|
||||
|
||||
# Simplification: We construct the top part (before header), add header, add new table section, add rest.
|
||||
|
||||
before_header = content[:header_match.start()]
|
||||
new_header = f"## Full Skill Registry ({total_skills}/{total_skills})"
|
||||
|
||||
new_content = f"{before_header}{new_header}\n\n{new_table_section}\n{rest_of_file}"
|
||||
|
||||
with open(readme_path, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
|
||||
print("✅ README.md updated successfully.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
update_readme()
|
||||
256
skills/README.md
256
skills/README.md
@@ -1,89 +1,201 @@
|
||||
# Antigravity Skills
|
||||
# Skills Directory
|
||||
|
||||
通过模块化的 **Skills** 定义,赋予 Agent 在特定领域的专业能力(如全栈开发、复杂逻辑规划、多媒体处理等),让 Agent 能够像人类专家一样系统性地解决复杂问题。
|
||||
**Welcome to the skills folder!** This is where all 179+ specialized AI skills live.
|
||||
|
||||
## 📂 目录结构
|
||||
## 🤔 What Are Skills?
|
||||
|
||||
Skills are specialized instruction sets that teach AI assistants how to handle specific tasks. Think of them as expert knowledge modules that your AI can load on-demand.
|
||||
|
||||
**Simple analogy:** Just like you might consult different experts (a designer, a security expert, a marketer), skills let your AI become an expert in different areas when you need them.
|
||||
|
||||
---
|
||||
|
||||
## 📂 Folder Structure
|
||||
|
||||
Each skill lives in its own folder with this structure:
|
||||
|
||||
```
|
||||
.
|
||||
├── .agent/
|
||||
│ └── skills/ # Antigravity Skills 技能库
|
||||
│ ├── skill-name/ # 独立技能目录
|
||||
│ │ ├── SKILL.md # 技能核心定义与Prompt(必须)
|
||||
│ │ ├── scripts/ # 技能依赖的脚本(可选)
|
||||
│ │ ├── examples/ # 技能使用示例(可选)
|
||||
│ │ └── resources/ # 技能依赖的模板与资源(可选)
|
||||
├── skill-guide/ # 用户手册与文档指南
|
||||
│ └── Antigravity_Skills_Manual_CN.md # 中文使用手册
|
||||
└── README.md
|
||||
skills/
|
||||
├── skill-name/ # Individual skill folder
|
||||
│ ├── SKILL.md # Main skill definition (required)
|
||||
│ ├── scripts/ # Helper scripts (optional)
|
||||
│ ├── examples/ # Usage examples (optional)
|
||||
│ └── resources/ # Templates & resources (optional)
|
||||
```
|
||||
|
||||
## 📖 快速开始
|
||||
1. 将`.agent/`目录复制到你的工作区:
|
||||
**Key point:** Only `SKILL.md` is required. Everything else is optional!
|
||||
|
||||
---
|
||||
|
||||
## How to Use Skills
|
||||
|
||||
### Step 1: Make sure skills are installed
|
||||
Skills should be in your `.agent/skills/` directory (or `.claude/skills/`, `.gemini/skills/`, etc.)
|
||||
|
||||
### Step 2: Invoke a skill in your AI chat
|
||||
Use the `@` symbol followed by the skill name:
|
||||
|
||||
```
|
||||
@brainstorming help me design a todo app
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
@stripe-integration add payment processing to my app
|
||||
```
|
||||
|
||||
### Step 3: The AI becomes an expert
|
||||
The AI loads that skill's knowledge and helps you with specialized expertise!
|
||||
|
||||
---
|
||||
|
||||
## Skill Categories
|
||||
|
||||
### Creative & Design
|
||||
Skills for visual design, UI/UX, and artistic creation:
|
||||
- `@algorithmic-art` - Create algorithmic art with p5.js
|
||||
- `@canvas-design` - Design posters and artwork (PNG/PDF output)
|
||||
- `@frontend-design` - Build production-grade frontend interfaces
|
||||
- `@ui-ux-pro-max` - Professional UI/UX design with color, fonts, layouts
|
||||
- `@web-artifacts-builder` - Build modern web apps (React, Tailwind, Shadcn/ui)
|
||||
- `@theme-factory` - Generate themes for documents and presentations
|
||||
- `@brand-guidelines` - Apply Anthropic brand design standards
|
||||
- `@slack-gif-creator` - Create high-quality GIFs for Slack
|
||||
|
||||
### Development & Engineering
|
||||
Skills for coding, testing, debugging, and code review:
|
||||
- `@test-driven-development` - Write tests before implementation (TDD)
|
||||
- `@systematic-debugging` - Debug systematically, not randomly
|
||||
- `@webapp-testing` - Test web apps with Playwright
|
||||
- `@receiving-code-review` - Handle code review feedback properly
|
||||
- `@requesting-code-review` - Request code reviews before merging
|
||||
- `@finishing-a-development-branch` - Complete dev branches (merge, PR, cleanup)
|
||||
- `@subagent-driven-development` - Coordinate multiple AI agents for parallel tasks
|
||||
|
||||
### Documentation & Office
|
||||
Skills for working with documents and office files:
|
||||
- `@doc-coauthoring` - Collaborate on structured documents
|
||||
- `@docx` - Create, edit, and analyze Word documents
|
||||
- `@xlsx` - Work with Excel spreadsheets (formulas, charts)
|
||||
- `@pptx` - Create and modify PowerPoint presentations
|
||||
- `@pdf` - Handle PDFs (extract text, merge, split, fill forms)
|
||||
- `@internal-comms` - Draft internal communications (reports, announcements)
|
||||
- `@notebooklm` - Query Google NotebookLM notebooks
|
||||
|
||||
### Planning & Workflow
|
||||
Skills for task planning and workflow optimization:
|
||||
- `@brainstorming` - Brainstorm and design before coding
|
||||
- `@writing-plans` - Write detailed implementation plans
|
||||
- `@planning-with-files` - File-based planning system (Manus-style)
|
||||
- `@executing-plans` - Execute plans with checkpoints and reviews
|
||||
- `@using-git-worktrees` - Create isolated Git worktrees for parallel work
|
||||
- `@verification-before-completion` - Verify work before claiming completion
|
||||
- `@using-superpowers` - Discover and use advanced skills
|
||||
|
||||
### System Extension
|
||||
Skills for extending AI capabilities:
|
||||
- `@mcp-builder` - Build MCP (Model Context Protocol) servers
|
||||
- `@skill-creator` - Create new skills or update existing ones
|
||||
- `@writing-skills` - Tools for writing and validating skill files
|
||||
- `@dispatching-parallel-agents` - Distribute tasks to multiple agents
|
||||
|
||||
---
|
||||
|
||||
## Finding Skills
|
||||
|
||||
### Method 1: Browse this folder
|
||||
```bash
|
||||
cp -r .agent/ /path/to/your/workspace/
|
||||
ls skills/
|
||||
```
|
||||
2. **调用 Skill**: 在对话框输入 `@[skill-name]` 或 `/skill-name`来进行调用,例如:
|
||||
```text
|
||||
/canvas-design 帮我设计一张关于“Deep Learning”的博客封面,风格要素雅、科技感,尺寸 16:9
|
||||
|
||||
### Method 2: Search by keyword
|
||||
```bash
|
||||
ls skills/ | grep "keyword"
|
||||
```
|
||||
3. **查看手册**: 详细的使用案例和参数说明请查阅 [skill-guide/Antigravity_Skills_Manual_CN.md](skill-guide/Antigravity_Skills_Manual_CN.md)。
|
||||
4. **环境依赖**: 部分 Skill (如 PDF, XLSX) 依赖 Python 环境,请确保 `.venv` 处于激活状态或系统已安装相应库。
|
||||
|
||||
### Method 3: Check the main README
|
||||
See the [main README](../README.md) for the complete list of all 179+ skills organized by category.
|
||||
|
||||
## 🚀 已集成的 Skills
|
||||
---
|
||||
|
||||
### 🎨 创意与设计 (Creative & Design)
|
||||
这些技能专注于视觉表现、UI/UX 设计和艺术创作。
|
||||
- **`@[algorithmic-art]`**: 使用 p5.js 代码创作算法艺术、生成艺术
|
||||
- **`@[canvas-design]`**: 基于设计哲学创建海报、艺术作品(输出 PNG/PDF)
|
||||
- **`@[frontend-design]`**: 创建高质量、生产级的各种前端界面和 Web 组件
|
||||
- **`@[ui-ux-pro-max]`**: 专业的 UI/UX 设计智能,提供配色、字体、布局等全套设计方案
|
||||
- **`@[web-artifacts-builder]`**: 构建复杂、现代化的 Web 应用(基于 React, Tailwind, Shadcn/ui)
|
||||
- **`@[theme-factory]`**: 为文档、幻灯片、HTML 等生成配套的主题风格
|
||||
- **`@[brand-guidelines]`**: 应用 Anthropic 官方品牌设计规范(颜色、排版等)
|
||||
- **`@[slack-gif-creator]`**: 制作专用于 Slack 的高质量 GIF 动图
|
||||
## 💡 Popular Skills to Try
|
||||
|
||||
### 🛠️ 开发与工程 (Development & Engineering)
|
||||
这些技能涵盖了编码、测试、调试和代码审查的全生命周期。
|
||||
- **`@[test-driven-development]`**: 测试驱动开发(TDD),在编写实现代码前先编写测试
|
||||
- **`@[systematic-debugging]`**: 系统化调试,用于解决 Bug、测试失败或异常行为
|
||||
- **`@[webapp-testing]`**: 使用 Playwright 对本地 Web 应用进行交互测试和验证
|
||||
- **`@[receiving-code-review]`**: 处理代码审查反馈,进行技术验证而非盲目修改
|
||||
- **`@[requesting-code-review]`**: 主动发起代码审查,在合并或完成任务前验证代码质量
|
||||
- **`@[finishing-a-development-branch]`**: 引导开发分支的收尾工作(合并、PR、清理等)
|
||||
- **`@[subagent-driven-development]`**: 协调多个子 Agent 并行执行独立的开发任务
|
||||
**For beginners:**
|
||||
- `@brainstorming` - Design before coding
|
||||
- `@systematic-debugging` - Fix bugs methodically
|
||||
- `@git-pushing` - Commit with good messages
|
||||
|
||||
### 📄 文档与办公 (Documentation & Office)
|
||||
这些技能用于处理各种格式的专业文档和办公需求。
|
||||
- **`@[doc-coauthoring]`**: 引导用户进行结构化文档(提案、技术规范等)的协作编写
|
||||
- **`@[docx]`**: 创建、编辑和分析 Word 文档
|
||||
- **`@[xlsx]`**: 创建、编辑和分析 Excel 电子表格(支持公式、图表)
|
||||
- **`@[pptx]`**: 创建和修改 PowerPoint 演示文稿
|
||||
- **`@[pdf]`**: 处理 PDF 文档,包括提取文本、表格,合并/拆分及填写表单
|
||||
- **`@[internal-comms]`**: 起草各类企业内部沟通文档(周报、通告、FAQ 等)
|
||||
- **`@[notebooklm]`**: 查询 Google NotebookLM 笔记本,提供基于文档的确切答案
|
||||
**For developers:**
|
||||
- `@test-driven-development` - Write tests first
|
||||
- `@react-best-practices` - Modern React patterns
|
||||
- `@senior-fullstack` - Full-stack development
|
||||
|
||||
### 📅 计划与流程 (Planning & Workflow)
|
||||
这些技能帮助优化工作流、任务规划和执行效率。
|
||||
- **`@[brainstorming]`**: 在开始任何工作前进行头脑风暴,明确需求和设计
|
||||
- **`@[writing-plans]`**: 为复杂的多步骤任务编写详细的执行计划(Spec)
|
||||
- **`@[planning-with-files]`**: 适用于复杂任务的文件式规划系统(Manus-style)
|
||||
- **`@[executing-plans]`**: 执行已有的实施计划,包含检查点和审查机制
|
||||
- **`@[using-git-worktrees]`**: 创建隔离的 Git 工作树,用于并行开发或任务切换
|
||||
- **`@[verification-before-completion]`**: 在声明任务完成前运行验证命令,确保证据确凿
|
||||
- **`@[using-superpowers]`**: 引导用户发现和使用这些高级技能
|
||||
**For security:**
|
||||
- `@ethical-hacking-methodology` - Security basics
|
||||
- `@burp-suite-testing` - Web app security testing
|
||||
|
||||
### 🧩 系统扩展 (System Extension)
|
||||
这些技能允许我扩展自身的能力边界。
|
||||
- **`@[mcp-builder]`**: 构建 MCP (Model Context Protocol) 服务器,连接外部工具和数据
|
||||
- **`@[skill-creator]`**: 创建新技能或更新现有技能,扩展我的知识库和工作流
|
||||
- **`@[writing-skills]`**: 辅助编写、编辑和验证技能文件的工具集
|
||||
- **`@[dispatching-parallel-agents]`**: 分发并行任务给多个 Agent 处理
|
||||
---
|
||||
|
||||
## 📚 参考文档
|
||||
- [Anthropic Skills](https://github.com/anthropic/skills)
|
||||
- [UI/UX Pro Max Skills](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill)
|
||||
- [Superpowers](https://github.com/obra/superpowers)
|
||||
- [Planning with Files](https://github.com/OthmanAdi/planning-with-files)
|
||||
- [NotebookLM](https://github.com/PleasePrompto/notebooklm-skill)
|
||||
## Creating Your Own Skill
|
||||
|
||||
Want to create a new skill? Check out:
|
||||
1. [CONTRIBUTING.md](../CONTRIBUTING.md) - How to contribute
|
||||
2. [docs/SKILL_ANATOMY.md](../docs/SKILL_ANATOMY.md) - Skill structure guide
|
||||
3. `@skill-creator` - Use this skill to create new skills!
|
||||
|
||||
**Basic structure:**
|
||||
```markdown
|
||||
---
|
||||
name: my-skill-name
|
||||
description: "What this skill does"
|
||||
---
|
||||
|
||||
# Skill Title
|
||||
|
||||
## Overview
|
||||
[What this skill does]
|
||||
|
||||
## When to Use
|
||||
- Use when [scenario]
|
||||
|
||||
## Instructions
|
||||
[Step-by-step guide]
|
||||
|
||||
## Examples
|
||||
[Code examples]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
- **[Getting Started](../GETTING_STARTED.md)** - Quick start guide
|
||||
- **[Examples](../docs/EXAMPLES.md)** - Real-world usage examples
|
||||
- **[FAQ](../FAQ.md)** - Common questions
|
||||
- **[Visual Guide](../docs/VISUAL_GUIDE.md)** - Diagrams and flowcharts
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Contributing
|
||||
|
||||
Found a skill that needs improvement? Want to add a new skill?
|
||||
|
||||
1. Read [CONTRIBUTING.md](../CONTRIBUTING.md)
|
||||
2. Study existing skills in this folder
|
||||
3. Create your skill following the structure
|
||||
4. Submit a Pull Request
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Anthropic Skills](https://github.com/anthropic/skills) - Official Anthropic skills
|
||||
- [UI/UX Pro Max Skills](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) - Design skills
|
||||
- [Superpowers](https://github.com/obra/superpowers) - Original superpowers collection
|
||||
- [Planning with Files](https://github.com/OthmanAdi/planning-with-files) - Planning patterns
|
||||
- [NotebookLM](https://github.com/PleasePrompto/notebooklm-skill) - NotebookLM integration
|
||||
|
||||
---
|
||||
|
||||
**Need help?** Check the [FAQ](../FAQ.md) or open an issue on GitHub!
|
||||
|
||||
82
skills/agent-memory-mcp/SKILL.md
Normal file
82
skills/agent-memory-mcp/SKILL.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: agent-memory-mcp
|
||||
author: Amit Rathiesh
|
||||
description: A hybrid memory system that provides persistent, searchable knowledge management for AI agents (Architecture, Patterns, Decisions).
|
||||
---
|
||||
|
||||
# Agent Memory Skill
|
||||
|
||||
This skill provides a persistent, searchable memory bank that automatically syncs with project documentation. It runs as an MCP server to allow reading/writing/searching of long-term memories.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (v18+)
|
||||
|
||||
## Setup
|
||||
|
||||
1. **Clone the Repository**:
|
||||
Clone the `agentMemory` project into your agent's workspace or a parallel directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/webzler/agentMemory.git .agent/skills/agent-memory
|
||||
```
|
||||
|
||||
2. **Install Dependencies**:
|
||||
|
||||
```bash
|
||||
cd .agent/skills/agent-memory
|
||||
npm install
|
||||
npm run compile
|
||||
```
|
||||
|
||||
3. **Start the MCP Server**:
|
||||
Use the helper script to activate the memory bank for your current project:
|
||||
|
||||
```bash
|
||||
npm run start-server <project_id> <absolute_path_to_target_workspace>
|
||||
```
|
||||
|
||||
_Example for current directory:_
|
||||
|
||||
```bash
|
||||
npm run start-server my-project $(pwd)
|
||||
```
|
||||
|
||||
## Capabilities (MCP Tools)
|
||||
|
||||
### `memory_search`
|
||||
|
||||
Search for memories by query, type, or tags.
|
||||
|
||||
- **Args**: `query` (string), `type?` (string), `tags?` (string[])
|
||||
- **Usage**: "Find all authentication patterns" -> `memory_search({ query: "authentication", type: "pattern" })`
|
||||
|
||||
### `memory_write`
|
||||
|
||||
Record new knowledge or decisions.
|
||||
|
||||
- **Args**: `key` (string), `type` (string), `content` (string), `tags?` (string[])
|
||||
- **Usage**: "Save this architecture decision" -> `memory_write({ key: "auth-v1", type: "decision", content: "..." })`
|
||||
|
||||
### `memory_read`
|
||||
|
||||
Retrieve specific memory content by key.
|
||||
|
||||
- **Args**: `key` (string)
|
||||
- **Usage**: "Get the auth design" -> `memory_read({ key: "auth-v1" })`
|
||||
|
||||
### `memory_stats`
|
||||
|
||||
View analytics on memory usage.
|
||||
|
||||
- **Usage**: "Show memory statistics" -> `memory_stats({})`
|
||||
|
||||
## Dashboard
|
||||
|
||||
This skill includes a standalone dashboard to visualize memory usage.
|
||||
|
||||
```bash
|
||||
npm run start-dashboard <absolute_path_to_target_workspace>
|
||||
```
|
||||
|
||||
Access at: `http://localhost:3333`
|
||||
484
skills/api-documentation-generator/SKILL.md
Normal file
484
skills/api-documentation-generator/SKILL.md
Normal file
@@ -0,0 +1,484 @@
|
||||
---
|
||||
name: api-documentation-generator
|
||||
description: "Generate comprehensive, developer-friendly API documentation from code, including endpoints, parameters, examples, and best practices"
|
||||
---
|
||||
|
||||
# API Documentation Generator
|
||||
|
||||
## Overview
|
||||
|
||||
Automatically generate clear, comprehensive API documentation from your codebase. This skill helps you create professional documentation that includes endpoint descriptions, request/response examples, authentication details, error handling, and usage guidelines.
|
||||
|
||||
Perfect for REST APIs, GraphQL APIs, and WebSocket APIs.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Use when you need to document a new API
|
||||
- Use when updating existing API documentation
|
||||
- Use when your API lacks clear documentation
|
||||
- Use when onboarding new developers to your API
|
||||
- Use when preparing API documentation for external users
|
||||
- Use when creating OpenAPI/Swagger specifications
|
||||
|
||||
## How It Works
|
||||
|
||||
### Step 1: Analyze the API Structure
|
||||
|
||||
First, I'll examine your API codebase to understand:
|
||||
- Available endpoints and routes
|
||||
- HTTP methods (GET, POST, PUT, DELETE, etc.)
|
||||
- Request parameters and body structure
|
||||
- Response formats and status codes
|
||||
- Authentication and authorization requirements
|
||||
- Error handling patterns
|
||||
|
||||
### Step 2: Generate Endpoint Documentation
|
||||
|
||||
For each endpoint, I'll create documentation including:
|
||||
|
||||
**Endpoint Details:**
|
||||
- HTTP method and URL path
|
||||
- Brief description of what it does
|
||||
- Authentication requirements
|
||||
- Rate limiting information (if applicable)
|
||||
|
||||
**Request Specification:**
|
||||
- Path parameters
|
||||
- Query parameters
|
||||
- Request headers
|
||||
- Request body schema (with types and validation rules)
|
||||
|
||||
**Response Specification:**
|
||||
- Success response (status code + body structure)
|
||||
- Error responses (all possible error codes)
|
||||
- Response headers
|
||||
|
||||
**Code Examples:**
|
||||
- cURL command
|
||||
- JavaScript/TypeScript (fetch/axios)
|
||||
- Python (requests)
|
||||
- Other languages as needed
|
||||
|
||||
### Step 3: Add Usage Guidelines
|
||||
|
||||
I'll include:
|
||||
- Getting started guide
|
||||
- Authentication setup
|
||||
- Common use cases
|
||||
- Best practices
|
||||
- Rate limiting details
|
||||
- Pagination patterns
|
||||
- Filtering and sorting options
|
||||
|
||||
### Step 4: Document Error Handling
|
||||
|
||||
Clear error documentation including:
|
||||
- All possible error codes
|
||||
- Error message formats
|
||||
- Troubleshooting guide
|
||||
- Common error scenarios and solutions
|
||||
|
||||
### Step 5: Create Interactive Examples
|
||||
|
||||
Where possible, I'll provide:
|
||||
- Postman collection
|
||||
- OpenAPI/Swagger specification
|
||||
- Interactive code examples
|
||||
- Sample responses
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: REST API Endpoint Documentation
|
||||
|
||||
```markdown
|
||||
## Create User
|
||||
|
||||
Creates a new user account.
|
||||
|
||||
**Endpoint:** `POST /api/v1/users`
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Request Body:**
|
||||
\`\`\`json
|
||||
{
|
||||
"email": "user@example.com", // Required: Valid email address
|
||||
"password": "SecurePass123!", // Required: Min 8 chars, 1 uppercase, 1 number
|
||||
"name": "John Doe", // Required: 2-50 characters
|
||||
"role": "user" // Optional: "user" or "admin" (default: "user")
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Success Response (201 Created):**
|
||||
\`\`\`json
|
||||
{
|
||||
"id": "usr_1234567890",
|
||||
"email": "user@example.com",
|
||||
"name": "John Doe",
|
||||
"role": "user",
|
||||
"createdAt": "2026-01-20T10:30:00Z",
|
||||
"emailVerified": false
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
- `400 Bad Request` - Invalid input data
|
||||
\`\`\`json
|
||||
{
|
||||
"error": "VALIDATION_ERROR",
|
||||
"message": "Invalid email format",
|
||||
"field": "email"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
- `409 Conflict` - Email already exists
|
||||
\`\`\`json
|
||||
{
|
||||
"error": "EMAIL_EXISTS",
|
||||
"message": "An account with this email already exists"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
- `401 Unauthorized` - Missing or invalid authentication token
|
||||
|
||||
**Example Request (cURL):**
|
||||
\`\`\`bash
|
||||
curl -X POST https://api.example.com/api/v1/users \
|
||||
-H "Authorization: Bearer YOUR_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"email": "user@example.com",
|
||||
"password": "SecurePass123!",
|
||||
"name": "John Doe"
|
||||
}'
|
||||
\`\`\`
|
||||
|
||||
**Example Request (JavaScript):**
|
||||
\`\`\`javascript
|
||||
const response = await fetch('https://api.example.com/api/v1/users', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: 'user@example.com',
|
||||
password: 'SecurePass123!',
|
||||
name: 'John Doe'
|
||||
})
|
||||
});
|
||||
|
||||
const user = await response.json();
|
||||
console.log(user);
|
||||
\`\`\`
|
||||
|
||||
**Example Request (Python):**
|
||||
\`\`\`python
|
||||
import requests
|
||||
|
||||
response = requests.post(
|
||||
'https://api.example.com/api/v1/users',
|
||||
headers={
|
||||
'Authorization': f'Bearer {token}',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
json={
|
||||
'email': 'user@example.com',
|
||||
'password': 'SecurePass123!',
|
||||
'name': 'John Doe'
|
||||
}
|
||||
)
|
||||
|
||||
user = response.json()
|
||||
print(user)
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Example 2: GraphQL API Documentation
|
||||
|
||||
```markdown
|
||||
## User Query
|
||||
|
||||
Fetch user information by ID.
|
||||
|
||||
**Query:**
|
||||
\`\`\`graphql
|
||||
query GetUser($id: ID!) {
|
||||
user(id: $id) {
|
||||
id
|
||||
email
|
||||
name
|
||||
role
|
||||
createdAt
|
||||
posts {
|
||||
id
|
||||
title
|
||||
publishedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Variables:**
|
||||
\`\`\`json
|
||||
{
|
||||
"id": "usr_1234567890"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Response:**
|
||||
\`\`\`json
|
||||
{
|
||||
"data": {
|
||||
"user": {
|
||||
"id": "usr_1234567890",
|
||||
"email": "user@example.com",
|
||||
"name": "John Doe",
|
||||
"role": "user",
|
||||
"createdAt": "2026-01-20T10:30:00Z",
|
||||
"posts": [
|
||||
{
|
||||
"id": "post_123",
|
||||
"title": "My First Post",
|
||||
"publishedAt": "2026-01-21T14:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Errors:**
|
||||
\`\`\`json
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"message": "User not found",
|
||||
"extensions": {
|
||||
"code": "USER_NOT_FOUND",
|
||||
"userId": "usr_1234567890"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Example 3: Authentication Documentation
|
||||
|
||||
```markdown
|
||||
## Authentication
|
||||
|
||||
All API requests require authentication using Bearer tokens.
|
||||
|
||||
### Getting a Token
|
||||
|
||||
**Endpoint:** `POST /api/v1/auth/login`
|
||||
|
||||
**Request:**
|
||||
\`\`\`json
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "your-password"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Response:**
|
||||
\`\`\`json
|
||||
{
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"expiresIn": 3600,
|
||||
"refreshToken": "refresh_token_here"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
### Using the Token
|
||||
|
||||
Include the token in the Authorization header:
|
||||
|
||||
\`\`\`
|
||||
Authorization: Bearer YOUR_TOKEN
|
||||
\`\`\`
|
||||
|
||||
### Token Expiration
|
||||
|
||||
Tokens expire after 1 hour. Use the refresh token to get a new access token:
|
||||
|
||||
**Endpoint:** `POST /api/v1/auth/refresh`
|
||||
|
||||
**Request:**
|
||||
\`\`\`json
|
||||
{
|
||||
"refreshToken": "refresh_token_here"
|
||||
}
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ Do This
|
||||
|
||||
- **Be Consistent** - Use the same format for all endpoints
|
||||
- **Include Examples** - Provide working code examples in multiple languages
|
||||
- **Document Errors** - List all possible error codes and their meanings
|
||||
- **Show Real Data** - Use realistic example data, not "foo" and "bar"
|
||||
- **Explain Parameters** - Describe what each parameter does and its constraints
|
||||
- **Version Your API** - Include version numbers in URLs (/api/v1/)
|
||||
- **Add Timestamps** - Show when documentation was last updated
|
||||
- **Link Related Endpoints** - Help users discover related functionality
|
||||
- **Include Rate Limits** - Document any rate limiting policies
|
||||
- **Provide Postman Collection** - Make it easy to test your API
|
||||
|
||||
### ❌ Don't Do This
|
||||
|
||||
- **Don't Skip Error Cases** - Users need to know what can go wrong
|
||||
- **Don't Use Vague Descriptions** - "Gets data" is not helpful
|
||||
- **Don't Forget Authentication** - Always document auth requirements
|
||||
- **Don't Ignore Edge Cases** - Document pagination, filtering, sorting
|
||||
- **Don't Leave Examples Broken** - Test all code examples
|
||||
- **Don't Use Outdated Info** - Keep documentation in sync with code
|
||||
- **Don't Overcomplicate** - Keep it simple and scannable
|
||||
- **Don't Forget Response Headers** - Document important headers
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
### Recommended Sections
|
||||
|
||||
1. **Introduction**
|
||||
- What the API does
|
||||
- Base URL
|
||||
- API version
|
||||
- Support contact
|
||||
|
||||
2. **Authentication**
|
||||
- How to authenticate
|
||||
- Token management
|
||||
- Security best practices
|
||||
|
||||
3. **Quick Start**
|
||||
- Simple example to get started
|
||||
- Common use case walkthrough
|
||||
|
||||
4. **Endpoints**
|
||||
- Organized by resource
|
||||
- Full details for each endpoint
|
||||
|
||||
5. **Data Models**
|
||||
- Schema definitions
|
||||
- Field descriptions
|
||||
- Validation rules
|
||||
|
||||
6. **Error Handling**
|
||||
- Error code reference
|
||||
- Error response format
|
||||
- Troubleshooting guide
|
||||
|
||||
7. **Rate Limiting**
|
||||
- Limits and quotas
|
||||
- Headers to check
|
||||
- Handling rate limit errors
|
||||
|
||||
8. **Changelog**
|
||||
- API version history
|
||||
- Breaking changes
|
||||
- Deprecation notices
|
||||
|
||||
9. **SDKs and Tools**
|
||||
- Official client libraries
|
||||
- Postman collection
|
||||
- OpenAPI specification
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Problem: Documentation Gets Out of Sync
|
||||
**Symptoms:** Examples don't work, parameters are wrong, endpoints return different data
|
||||
**Solution:**
|
||||
- Generate docs from code comments/annotations
|
||||
- Use tools like Swagger/OpenAPI
|
||||
- Add API tests that validate documentation
|
||||
- Review docs with every API change
|
||||
|
||||
### Problem: Missing Error Documentation
|
||||
**Symptoms:** Users don't know how to handle errors, support tickets increase
|
||||
**Solution:**
|
||||
- Document every possible error code
|
||||
- Provide clear error messages
|
||||
- Include troubleshooting steps
|
||||
- Show example error responses
|
||||
|
||||
### Problem: Examples Don't Work
|
||||
**Symptoms:** Users can't get started, frustration increases
|
||||
**Solution:**
|
||||
- Test every code example
|
||||
- Use real, working endpoints
|
||||
- Include complete examples (not fragments)
|
||||
- Provide a sandbox environment
|
||||
|
||||
### Problem: Unclear Parameter Requirements
|
||||
**Symptoms:** Users send invalid requests, validation errors
|
||||
**Solution:**
|
||||
- Mark required vs optional clearly
|
||||
- Document data types and formats
|
||||
- Show validation rules
|
||||
- Provide example values
|
||||
|
||||
## Tools and Formats
|
||||
|
||||
### OpenAPI/Swagger
|
||||
Generate interactive documentation:
|
||||
```yaml
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: My API
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/users:
|
||||
post:
|
||||
summary: Create a new user
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateUserRequest'
|
||||
```
|
||||
|
||||
### Postman Collection
|
||||
Export collection for easy testing:
|
||||
```json
|
||||
{
|
||||
"info": {
|
||||
"name": "My API",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "Create User",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "{{baseUrl}}/api/v1/users"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `@doc-coauthoring` - For collaborative documentation writing
|
||||
- `@copywriting` - For clear, user-friendly descriptions
|
||||
- `@test-driven-development` - For ensuring API behavior matches docs
|
||||
- `@systematic-debugging` - For troubleshooting API issues
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [OpenAPI Specification](https://swagger.io/specification/)
|
||||
- [REST API Best Practices](https://restfulapi.net/)
|
||||
- [GraphQL Documentation](https://graphql.org/learn/)
|
||||
- [API Design Patterns](https://www.apiguide.com/)
|
||||
- [Postman Documentation](https://learning.postman.com/docs/)
|
||||
|
||||
---
|
||||
|
||||
**Pro Tip:** Keep your API documentation as close to your code as possible. Use tools that generate docs from code comments to ensure they stay in sync!
|
||||
584
skills/cc-skill-backend-patterns/SKILL.md
Normal file
584
skills/cc-skill-backend-patterns/SKILL.md
Normal file
@@ -0,0 +1,584 @@
|
||||
---
|
||||
name: backend-patterns
|
||||
description: Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Backend Development Patterns
|
||||
|
||||
Backend architecture patterns and best practices for scalable server-side applications.
|
||||
|
||||
## API Design Patterns
|
||||
|
||||
### RESTful API Structure
|
||||
|
||||
```typescript
|
||||
// ✅ Resource-based URLs
|
||||
GET /api/markets # List resources
|
||||
GET /api/markets/:id # Get single resource
|
||||
POST /api/markets # Create resource
|
||||
PUT /api/markets/:id # Replace resource
|
||||
PATCH /api/markets/:id # Update resource
|
||||
DELETE /api/markets/:id # Delete resource
|
||||
|
||||
// ✅ Query parameters for filtering, sorting, pagination
|
||||
GET /api/markets?status=active&sort=volume&limit=20&offset=0
|
||||
```
|
||||
|
||||
### Repository Pattern
|
||||
|
||||
```typescript
|
||||
// Abstract data access logic
|
||||
interface MarketRepository {
|
||||
findAll(filters?: MarketFilters): Promise<Market[]>
|
||||
findById(id: string): Promise<Market | null>
|
||||
create(data: CreateMarketDto): Promise<Market>
|
||||
update(id: string, data: UpdateMarketDto): Promise<Market>
|
||||
delete(id: string): Promise<void>
|
||||
}
|
||||
|
||||
class SupabaseMarketRepository implements MarketRepository {
|
||||
async findAll(filters?: MarketFilters): Promise<Market[]> {
|
||||
let query = supabase.from('markets').select('*')
|
||||
|
||||
if (filters?.status) {
|
||||
query = query.eq('status', filters.status)
|
||||
}
|
||||
|
||||
if (filters?.limit) {
|
||||
query = query.limit(filters.limit)
|
||||
}
|
||||
|
||||
const { data, error } = await query
|
||||
|
||||
if (error) throw new Error(error.message)
|
||||
return data
|
||||
}
|
||||
|
||||
// Other methods...
|
||||
}
|
||||
```
|
||||
|
||||
### Service Layer Pattern
|
||||
|
||||
```typescript
|
||||
// Business logic separated from data access
|
||||
class MarketService {
|
||||
constructor(private marketRepo: MarketRepository) {}
|
||||
|
||||
async searchMarkets(query: string, limit: number = 10): Promise<Market[]> {
|
||||
// Business logic
|
||||
const embedding = await generateEmbedding(query)
|
||||
const results = await this.vectorSearch(embedding, limit)
|
||||
|
||||
// Fetch full data
|
||||
const markets = await this.marketRepo.findByIds(results.map(r => r.id))
|
||||
|
||||
// Sort by similarity
|
||||
return markets.sort((a, b) => {
|
||||
const scoreA = results.find(r => r.id === a.id)?.score || 0
|
||||
const scoreB = results.find(r => r.id === b.id)?.score || 0
|
||||
return scoreA - scoreB
|
||||
})
|
||||
}
|
||||
|
||||
private async vectorSearch(embedding: number[], limit: number) {
|
||||
// Vector search implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware Pattern
|
||||
|
||||
```typescript
|
||||
// Request/response processing pipeline
|
||||
export function withAuth(handler: NextApiHandler): NextApiHandler {
|
||||
return async (req, res) => {
|
||||
const token = req.headers.authorization?.replace('Bearer ', '')
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({ error: 'Unauthorized' })
|
||||
}
|
||||
|
||||
try {
|
||||
const user = await verifyToken(token)
|
||||
req.user = user
|
||||
return handler(req, res)
|
||||
} catch (error) {
|
||||
return res.status(401).json({ error: 'Invalid token' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
export default withAuth(async (req, res) => {
|
||||
// Handler has access to req.user
|
||||
})
|
||||
```
|
||||
|
||||
## Database Patterns
|
||||
|
||||
### Query Optimization
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status, volume')
|
||||
.eq('status', 'active')
|
||||
.order('volume', { ascending: false })
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
```
|
||||
|
||||
### N+1 Query Prevention
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: N+1 query problem
|
||||
const markets = await getMarkets()
|
||||
for (const market of markets) {
|
||||
market.creator = await getUser(market.creator_id) // N queries
|
||||
}
|
||||
|
||||
// ✅ GOOD: Batch fetch
|
||||
const markets = await getMarkets()
|
||||
const creatorIds = markets.map(m => m.creator_id)
|
||||
const creators = await getUsers(creatorIds) // 1 query
|
||||
const creatorMap = new Map(creators.map(c => [c.id, c]))
|
||||
|
||||
markets.forEach(market => {
|
||||
market.creator = creatorMap.get(market.creator_id)
|
||||
})
|
||||
```
|
||||
|
||||
### Transaction Pattern
|
||||
|
||||
```typescript
|
||||
async function createMarketWithPosition(
|
||||
marketData: CreateMarketDto,
|
||||
positionData: CreatePositionDto
|
||||
) {
|
||||
// Use Supabase transaction
|
||||
const { data, error } = await supabase.rpc('create_market_with_position', {
|
||||
market_data: marketData,
|
||||
position_data: positionData
|
||||
})
|
||||
|
||||
if (error) throw new Error('Transaction failed')
|
||||
return data
|
||||
}
|
||||
|
||||
// SQL function in Supabase
|
||||
CREATE OR REPLACE FUNCTION create_market_with_position(
|
||||
market_data jsonb,
|
||||
position_data jsonb
|
||||
)
|
||||
RETURNS jsonb
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
-- Start transaction automatically
|
||||
INSERT INTO markets VALUES (market_data);
|
||||
INSERT INTO positions VALUES (position_data);
|
||||
RETURN jsonb_build_object('success', true);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
-- Rollback happens automatically
|
||||
RETURN jsonb_build_object('success', false, 'error', SQLERRM);
|
||||
END;
|
||||
$$;
|
||||
```
|
||||
|
||||
## Caching Strategies
|
||||
|
||||
### Redis Caching Layer
|
||||
|
||||
```typescript
|
||||
class CachedMarketRepository implements MarketRepository {
|
||||
constructor(
|
||||
private baseRepo: MarketRepository,
|
||||
private redis: RedisClient
|
||||
) {}
|
||||
|
||||
async findById(id: string): Promise<Market | null> {
|
||||
// Check cache first
|
||||
const cached = await this.redis.get(`market:${id}`)
|
||||
|
||||
if (cached) {
|
||||
return JSON.parse(cached)
|
||||
}
|
||||
|
||||
// Cache miss - fetch from database
|
||||
const market = await this.baseRepo.findById(id)
|
||||
|
||||
if (market) {
|
||||
// Cache for 5 minutes
|
||||
await this.redis.setex(`market:${id}`, 300, JSON.stringify(market))
|
||||
}
|
||||
|
||||
return market
|
||||
}
|
||||
|
||||
async invalidateCache(id: string): Promise<void> {
|
||||
await this.redis.del(`market:${id}`)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Cache-Aside Pattern
|
||||
|
||||
```typescript
|
||||
async function getMarketWithCache(id: string): Promise<Market> {
|
||||
const cacheKey = `market:${id}`
|
||||
|
||||
// Try cache
|
||||
const cached = await redis.get(cacheKey)
|
||||
if (cached) return JSON.parse(cached)
|
||||
|
||||
// Cache miss - fetch from DB
|
||||
const market = await db.markets.findUnique({ where: { id } })
|
||||
|
||||
if (!market) throw new Error('Market not found')
|
||||
|
||||
// Update cache
|
||||
await redis.setex(cacheKey, 300, JSON.stringify(market))
|
||||
|
||||
return market
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling Patterns
|
||||
|
||||
### Centralized Error Handler
|
||||
|
||||
```typescript
|
||||
class ApiError extends Error {
|
||||
constructor(
|
||||
public statusCode: number,
|
||||
public message: string,
|
||||
public isOperational = true
|
||||
) {
|
||||
super(message)
|
||||
Object.setPrototypeOf(this, ApiError.prototype)
|
||||
}
|
||||
}
|
||||
|
||||
export function errorHandler(error: unknown, req: Request): Response {
|
||||
if (error instanceof ApiError) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: error.message
|
||||
}, { status: error.statusCode })
|
||||
}
|
||||
|
||||
if (error instanceof z.ZodError) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors
|
||||
}, { status: 400 })
|
||||
}
|
||||
|
||||
// Log unexpected errors
|
||||
console.error('Unexpected error:', error)
|
||||
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
}, { status: 500 })
|
||||
}
|
||||
|
||||
// Usage
|
||||
export async function GET(request: Request) {
|
||||
try {
|
||||
const data = await fetchData()
|
||||
return NextResponse.json({ success: true, data })
|
||||
} catch (error) {
|
||||
return errorHandler(error, request)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Retry with Exponential Backoff
|
||||
|
||||
```typescript
|
||||
async function fetchWithRetry<T>(
|
||||
fn: () => Promise<T>,
|
||||
maxRetries = 3
|
||||
): Promise<T> {
|
||||
let lastError: Error
|
||||
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
return await fn()
|
||||
} catch (error) {
|
||||
lastError = error as Error
|
||||
|
||||
if (i < maxRetries - 1) {
|
||||
// Exponential backoff: 1s, 2s, 4s
|
||||
const delay = Math.pow(2, i) * 1000
|
||||
await new Promise(resolve => setTimeout(resolve, delay))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError!
|
||||
}
|
||||
|
||||
// Usage
|
||||
const data = await fetchWithRetry(() => fetchFromAPI())
|
||||
```
|
||||
|
||||
## Authentication & Authorization
|
||||
|
||||
### JWT Token Validation
|
||||
|
||||
```typescript
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
interface JWTPayload {
|
||||
userId: string
|
||||
email: string
|
||||
role: 'admin' | 'user'
|
||||
}
|
||||
|
||||
export function verifyToken(token: string): JWTPayload {
|
||||
try {
|
||||
const payload = jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload
|
||||
return payload
|
||||
} catch (error) {
|
||||
throw new ApiError(401, 'Invalid token')
|
||||
}
|
||||
}
|
||||
|
||||
export async function requireAuth(request: Request) {
|
||||
const token = request.headers.get('authorization')?.replace('Bearer ', '')
|
||||
|
||||
if (!token) {
|
||||
throw new ApiError(401, 'Missing authorization token')
|
||||
}
|
||||
|
||||
return verifyToken(token)
|
||||
}
|
||||
|
||||
// Usage in API route
|
||||
export async function GET(request: Request) {
|
||||
const user = await requireAuth(request)
|
||||
|
||||
const data = await getDataForUser(user.userId)
|
||||
|
||||
return NextResponse.json({ success: true, data })
|
||||
}
|
||||
```
|
||||
|
||||
### Role-Based Access Control
|
||||
|
||||
```typescript
|
||||
type Permission = 'read' | 'write' | 'delete' | 'admin'
|
||||
|
||||
interface User {
|
||||
id: string
|
||||
role: 'admin' | 'moderator' | 'user'
|
||||
}
|
||||
|
||||
const rolePermissions: Record<User['role'], Permission[]> = {
|
||||
admin: ['read', 'write', 'delete', 'admin'],
|
||||
moderator: ['read', 'write', 'delete'],
|
||||
user: ['read', 'write']
|
||||
}
|
||||
|
||||
export function hasPermission(user: User, permission: Permission): boolean {
|
||||
return rolePermissions[user.role].includes(permission)
|
||||
}
|
||||
|
||||
export function requirePermission(permission: Permission) {
|
||||
return async (request: Request) => {
|
||||
const user = await requireAuth(request)
|
||||
|
||||
if (!hasPermission(user, permission)) {
|
||||
throw new ApiError(403, 'Insufficient permissions')
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
export const DELETE = requirePermission('delete')(async (request: Request) => {
|
||||
// Handler with permission check
|
||||
})
|
||||
```
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
### Simple In-Memory Rate Limiter
|
||||
|
||||
```typescript
|
||||
class RateLimiter {
|
||||
private requests = new Map<string, number[]>()
|
||||
|
||||
async checkLimit(
|
||||
identifier: string,
|
||||
maxRequests: number,
|
||||
windowMs: number
|
||||
): Promise<boolean> {
|
||||
const now = Date.now()
|
||||
const requests = this.requests.get(identifier) || []
|
||||
|
||||
// Remove old requests outside window
|
||||
const recentRequests = requests.filter(time => now - time < windowMs)
|
||||
|
||||
if (recentRequests.length >= maxRequests) {
|
||||
return false // Rate limit exceeded
|
||||
}
|
||||
|
||||
// Add current request
|
||||
recentRequests.push(now)
|
||||
this.requests.set(identifier, recentRequests)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const limiter = new RateLimiter()
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const ip = request.headers.get('x-forwarded-for') || 'unknown'
|
||||
|
||||
const allowed = await limiter.checkLimit(ip, 100, 60000) // 100 req/min
|
||||
|
||||
if (!allowed) {
|
||||
return NextResponse.json({
|
||||
error: 'Rate limit exceeded'
|
||||
}, { status: 429 })
|
||||
}
|
||||
|
||||
// Continue with request
|
||||
}
|
||||
```
|
||||
|
||||
## Background Jobs & Queues
|
||||
|
||||
### Simple Queue Pattern
|
||||
|
||||
```typescript
|
||||
class JobQueue<T> {
|
||||
private queue: T[] = []
|
||||
private processing = false
|
||||
|
||||
async add(job: T): Promise<void> {
|
||||
this.queue.push(job)
|
||||
|
||||
if (!this.processing) {
|
||||
this.process()
|
||||
}
|
||||
}
|
||||
|
||||
private async process(): Promise<void> {
|
||||
this.processing = true
|
||||
|
||||
while (this.queue.length > 0) {
|
||||
const job = this.queue.shift()!
|
||||
|
||||
try {
|
||||
await this.execute(job)
|
||||
} catch (error) {
|
||||
console.error('Job failed:', error)
|
||||
}
|
||||
}
|
||||
|
||||
this.processing = false
|
||||
}
|
||||
|
||||
private async execute(job: T): Promise<void> {
|
||||
// Job execution logic
|
||||
}
|
||||
}
|
||||
|
||||
// Usage for indexing markets
|
||||
interface IndexJob {
|
||||
marketId: string
|
||||
}
|
||||
|
||||
const indexQueue = new JobQueue<IndexJob>()
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const { marketId } = await request.json()
|
||||
|
||||
// Add to queue instead of blocking
|
||||
await indexQueue.add({ marketId })
|
||||
|
||||
return NextResponse.json({ success: true, message: 'Job queued' })
|
||||
}
|
||||
```
|
||||
|
||||
## Logging & Monitoring
|
||||
|
||||
### Structured Logging
|
||||
|
||||
```typescript
|
||||
interface LogContext {
|
||||
userId?: string
|
||||
requestId?: string
|
||||
method?: string
|
||||
path?: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
class Logger {
|
||||
log(level: 'info' | 'warn' | 'error', message: string, context?: LogContext) {
|
||||
const entry = {
|
||||
timestamp: new Date().toISOString(),
|
||||
level,
|
||||
message,
|
||||
...context
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(entry))
|
||||
}
|
||||
|
||||
info(message: string, context?: LogContext) {
|
||||
this.log('info', message, context)
|
||||
}
|
||||
|
||||
warn(message: string, context?: LogContext) {
|
||||
this.log('warn', message, context)
|
||||
}
|
||||
|
||||
error(message: string, error: Error, context?: LogContext) {
|
||||
this.log('error', message, {
|
||||
...context,
|
||||
error: error.message,
|
||||
stack: error.stack
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const logger = new Logger()
|
||||
|
||||
// Usage
|
||||
export async function GET(request: Request) {
|
||||
const requestId = crypto.randomUUID()
|
||||
|
||||
logger.info('Fetching markets', {
|
||||
requestId,
|
||||
method: 'GET',
|
||||
path: '/api/markets'
|
||||
})
|
||||
|
||||
try {
|
||||
const markets = await fetchMarkets()
|
||||
return NextResponse.json({ success: true, data: markets })
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch markets', error as Error, { requestId })
|
||||
return NextResponse.json({ error: 'Internal error' }, { status: 500 })
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Remember**: Backend patterns enable scalable, maintainable server-side applications. Choose patterns that fit your complexity level.
|
||||
431
skills/cc-skill-clickhouse-io/SKILL.md
Normal file
431
skills/cc-skill-clickhouse-io/SKILL.md
Normal file
@@ -0,0 +1,431 @@
|
||||
---
|
||||
name: clickhouse-io
|
||||
description: ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# ClickHouse Analytics Patterns
|
||||
|
||||
ClickHouse-specific patterns for high-performance analytics and data engineering.
|
||||
|
||||
## Overview
|
||||
|
||||
ClickHouse is a column-oriented database management system (DBMS) for online analytical processing (OLAP). It's optimized for fast analytical queries on large datasets.
|
||||
|
||||
**Key Features:**
|
||||
- Column-oriented storage
|
||||
- Data compression
|
||||
- Parallel query execution
|
||||
- Distributed queries
|
||||
- Real-time analytics
|
||||
|
||||
## Table Design Patterns
|
||||
|
||||
### MergeTree Engine (Most Common)
|
||||
|
||||
```sql
|
||||
CREATE TABLE markets_analytics (
|
||||
date Date,
|
||||
market_id String,
|
||||
market_name String,
|
||||
volume UInt64,
|
||||
trades UInt32,
|
||||
unique_traders UInt32,
|
||||
avg_trade_size Float64,
|
||||
created_at DateTime
|
||||
) ENGINE = MergeTree()
|
||||
PARTITION BY toYYYYMM(date)
|
||||
ORDER BY (date, market_id)
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
|
||||
### ReplacingMergeTree (Deduplication)
|
||||
|
||||
```sql
|
||||
-- For data that may have duplicates (e.g., from multiple sources)
|
||||
CREATE TABLE user_events (
|
||||
event_id String,
|
||||
user_id String,
|
||||
event_type String,
|
||||
timestamp DateTime,
|
||||
properties String
|
||||
) ENGINE = ReplacingMergeTree()
|
||||
PARTITION BY toYYYYMM(timestamp)
|
||||
ORDER BY (user_id, event_id, timestamp)
|
||||
PRIMARY KEY (user_id, event_id);
|
||||
```
|
||||
|
||||
### AggregatingMergeTree (Pre-aggregation)
|
||||
|
||||
```sql
|
||||
-- For maintaining aggregated metrics
|
||||
CREATE TABLE market_stats_hourly (
|
||||
hour DateTime,
|
||||
market_id String,
|
||||
total_volume AggregateFunction(sum, UInt64),
|
||||
total_trades AggregateFunction(count, UInt32),
|
||||
unique_users AggregateFunction(uniq, String)
|
||||
) ENGINE = AggregatingMergeTree()
|
||||
PARTITION BY toYYYYMM(hour)
|
||||
ORDER BY (hour, market_id);
|
||||
|
||||
-- Query aggregated data
|
||||
SELECT
|
||||
hour,
|
||||
market_id,
|
||||
sumMerge(total_volume) AS volume,
|
||||
countMerge(total_trades) AS trades,
|
||||
uniqMerge(unique_users) AS users
|
||||
FROM market_stats_hourly
|
||||
WHERE hour >= toStartOfHour(now() - INTERVAL 24 HOUR)
|
||||
GROUP BY hour, market_id
|
||||
ORDER BY hour DESC;
|
||||
```
|
||||
|
||||
## Query Optimization Patterns
|
||||
|
||||
### Efficient Filtering
|
||||
|
||||
```sql
|
||||
-- ✅ GOOD: Use indexed columns first
|
||||
SELECT *
|
||||
FROM markets_analytics
|
||||
WHERE date >= '2025-01-01'
|
||||
AND market_id = 'market-123'
|
||||
AND volume > 1000
|
||||
ORDER BY date DESC
|
||||
LIMIT 100;
|
||||
|
||||
-- ❌ BAD: Filter on non-indexed columns first
|
||||
SELECT *
|
||||
FROM markets_analytics
|
||||
WHERE volume > 1000
|
||||
AND market_name LIKE '%election%'
|
||||
AND date >= '2025-01-01';
|
||||
```
|
||||
|
||||
### Aggregations
|
||||
|
||||
```sql
|
||||
-- ✅ GOOD: Use ClickHouse-specific aggregation functions
|
||||
SELECT
|
||||
toStartOfDay(created_at) AS day,
|
||||
market_id,
|
||||
sum(volume) AS total_volume,
|
||||
count() AS total_trades,
|
||||
uniq(trader_id) AS unique_traders,
|
||||
avg(trade_size) AS avg_size
|
||||
FROM trades
|
||||
WHERE created_at >= today() - INTERVAL 7 DAY
|
||||
GROUP BY day, market_id
|
||||
ORDER BY day DESC, total_volume DESC;
|
||||
|
||||
-- ✅ Use quantile for percentiles (more efficient than percentile)
|
||||
SELECT
|
||||
quantile(0.50)(trade_size) AS median,
|
||||
quantile(0.95)(trade_size) AS p95,
|
||||
quantile(0.99)(trade_size) AS p99
|
||||
FROM trades
|
||||
WHERE created_at >= now() - INTERVAL 1 HOUR;
|
||||
```
|
||||
|
||||
### Window Functions
|
||||
|
||||
```sql
|
||||
-- Calculate running totals
|
||||
SELECT
|
||||
date,
|
||||
market_id,
|
||||
volume,
|
||||
sum(volume) OVER (
|
||||
PARTITION BY market_id
|
||||
ORDER BY date
|
||||
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
) AS cumulative_volume
|
||||
FROM markets_analytics
|
||||
WHERE date >= today() - INTERVAL 30 DAY
|
||||
ORDER BY market_id, date;
|
||||
```
|
||||
|
||||
## Data Insertion Patterns
|
||||
|
||||
### Bulk Insert (Recommended)
|
||||
|
||||
```typescript
|
||||
import { ClickHouse } from 'clickhouse'
|
||||
|
||||
const clickhouse = new ClickHouse({
|
||||
url: process.env.CLICKHOUSE_URL,
|
||||
port: 8123,
|
||||
basicAuth: {
|
||||
username: process.env.CLICKHOUSE_USER,
|
||||
password: process.env.CLICKHOUSE_PASSWORD
|
||||
}
|
||||
})
|
||||
|
||||
// ✅ Batch insert (efficient)
|
||||
async function bulkInsertTrades(trades: Trade[]) {
|
||||
const values = trades.map(trade => `(
|
||||
'${trade.id}',
|
||||
'${trade.market_id}',
|
||||
'${trade.user_id}',
|
||||
${trade.amount},
|
||||
'${trade.timestamp.toISOString()}'
|
||||
)`).join(',')
|
||||
|
||||
await clickhouse.query(`
|
||||
INSERT INTO trades (id, market_id, user_id, amount, timestamp)
|
||||
VALUES ${values}
|
||||
`).toPromise()
|
||||
}
|
||||
|
||||
// ❌ Individual inserts (slow)
|
||||
async function insertTrade(trade: Trade) {
|
||||
// Don't do this in a loop!
|
||||
await clickhouse.query(`
|
||||
INSERT INTO trades VALUES ('${trade.id}', ...)
|
||||
`).toPromise()
|
||||
}
|
||||
```
|
||||
|
||||
### Streaming Insert
|
||||
|
||||
```typescript
|
||||
// For continuous data ingestion
|
||||
import { createWriteStream } from 'fs'
|
||||
import { pipeline } from 'stream/promises'
|
||||
|
||||
async function streamInserts() {
|
||||
const stream = clickhouse.insert('trades').stream()
|
||||
|
||||
for await (const batch of dataSource) {
|
||||
stream.write(batch)
|
||||
}
|
||||
|
||||
await stream.end()
|
||||
}
|
||||
```
|
||||
|
||||
## Materialized Views
|
||||
|
||||
### Real-time Aggregations
|
||||
|
||||
```sql
|
||||
-- Create materialized view for hourly stats
|
||||
CREATE MATERIALIZED VIEW market_stats_hourly_mv
|
||||
TO market_stats_hourly
|
||||
AS SELECT
|
||||
toStartOfHour(timestamp) AS hour,
|
||||
market_id,
|
||||
sumState(amount) AS total_volume,
|
||||
countState() AS total_trades,
|
||||
uniqState(user_id) AS unique_users
|
||||
FROM trades
|
||||
GROUP BY hour, market_id;
|
||||
|
||||
-- Query the materialized view
|
||||
SELECT
|
||||
hour,
|
||||
market_id,
|
||||
sumMerge(total_volume) AS volume,
|
||||
countMerge(total_trades) AS trades,
|
||||
uniqMerge(unique_users) AS users
|
||||
FROM market_stats_hourly
|
||||
WHERE hour >= now() - INTERVAL 24 HOUR
|
||||
GROUP BY hour, market_id;
|
||||
```
|
||||
|
||||
## Performance Monitoring
|
||||
|
||||
### Query Performance
|
||||
|
||||
```sql
|
||||
-- Check slow queries
|
||||
SELECT
|
||||
query_id,
|
||||
user,
|
||||
query,
|
||||
query_duration_ms,
|
||||
read_rows,
|
||||
read_bytes,
|
||||
memory_usage
|
||||
FROM system.query_log
|
||||
WHERE type = 'QueryFinish'
|
||||
AND query_duration_ms > 1000
|
||||
AND event_time >= now() - INTERVAL 1 HOUR
|
||||
ORDER BY query_duration_ms DESC
|
||||
LIMIT 10;
|
||||
```
|
||||
|
||||
### Table Statistics
|
||||
|
||||
```sql
|
||||
-- Check table sizes
|
||||
SELECT
|
||||
database,
|
||||
table,
|
||||
formatReadableSize(sum(bytes)) AS size,
|
||||
sum(rows) AS rows,
|
||||
max(modification_time) AS latest_modification
|
||||
FROM system.parts
|
||||
WHERE active
|
||||
GROUP BY database, table
|
||||
ORDER BY sum(bytes) DESC;
|
||||
```
|
||||
|
||||
## Common Analytics Queries
|
||||
|
||||
### Time Series Analysis
|
||||
|
||||
```sql
|
||||
-- Daily active users
|
||||
SELECT
|
||||
toDate(timestamp) AS date,
|
||||
uniq(user_id) AS daily_active_users
|
||||
FROM events
|
||||
WHERE timestamp >= today() - INTERVAL 30 DAY
|
||||
GROUP BY date
|
||||
ORDER BY date;
|
||||
|
||||
-- Retention analysis
|
||||
SELECT
|
||||
signup_date,
|
||||
countIf(days_since_signup = 0) AS day_0,
|
||||
countIf(days_since_signup = 1) AS day_1,
|
||||
countIf(days_since_signup = 7) AS day_7,
|
||||
countIf(days_since_signup = 30) AS day_30
|
||||
FROM (
|
||||
SELECT
|
||||
user_id,
|
||||
min(toDate(timestamp)) AS signup_date,
|
||||
toDate(timestamp) AS activity_date,
|
||||
dateDiff('day', signup_date, activity_date) AS days_since_signup
|
||||
FROM events
|
||||
GROUP BY user_id, activity_date
|
||||
)
|
||||
GROUP BY signup_date
|
||||
ORDER BY signup_date DESC;
|
||||
```
|
||||
|
||||
### Funnel Analysis
|
||||
|
||||
```sql
|
||||
-- Conversion funnel
|
||||
SELECT
|
||||
countIf(step = 'viewed_market') AS viewed,
|
||||
countIf(step = 'clicked_trade') AS clicked,
|
||||
countIf(step = 'completed_trade') AS completed,
|
||||
round(clicked / viewed * 100, 2) AS view_to_click_rate,
|
||||
round(completed / clicked * 100, 2) AS click_to_completion_rate
|
||||
FROM (
|
||||
SELECT
|
||||
user_id,
|
||||
session_id,
|
||||
event_type AS step
|
||||
FROM events
|
||||
WHERE event_date = today()
|
||||
)
|
||||
GROUP BY session_id;
|
||||
```
|
||||
|
||||
### Cohort Analysis
|
||||
|
||||
```sql
|
||||
-- User cohorts by signup month
|
||||
SELECT
|
||||
toStartOfMonth(signup_date) AS cohort,
|
||||
toStartOfMonth(activity_date) AS month,
|
||||
dateDiff('month', cohort, month) AS months_since_signup,
|
||||
count(DISTINCT user_id) AS active_users
|
||||
FROM (
|
||||
SELECT
|
||||
user_id,
|
||||
min(toDate(timestamp)) OVER (PARTITION BY user_id) AS signup_date,
|
||||
toDate(timestamp) AS activity_date
|
||||
FROM events
|
||||
)
|
||||
GROUP BY cohort, month, months_since_signup
|
||||
ORDER BY cohort, months_since_signup;
|
||||
```
|
||||
|
||||
## Data Pipeline Patterns
|
||||
|
||||
### ETL Pattern
|
||||
|
||||
```typescript
|
||||
// Extract, Transform, Load
|
||||
async function etlPipeline() {
|
||||
// 1. Extract from source
|
||||
const rawData = await extractFromPostgres()
|
||||
|
||||
// 2. Transform
|
||||
const transformed = rawData.map(row => ({
|
||||
date: new Date(row.created_at).toISOString().split('T')[0],
|
||||
market_id: row.market_slug,
|
||||
volume: parseFloat(row.total_volume),
|
||||
trades: parseInt(row.trade_count)
|
||||
}))
|
||||
|
||||
// 3. Load to ClickHouse
|
||||
await bulkInsertToClickHouse(transformed)
|
||||
}
|
||||
|
||||
// Run periodically
|
||||
setInterval(etlPipeline, 60 * 60 * 1000) // Every hour
|
||||
```
|
||||
|
||||
### Change Data Capture (CDC)
|
||||
|
||||
```typescript
|
||||
// Listen to PostgreSQL changes and sync to ClickHouse
|
||||
import { Client } from 'pg'
|
||||
|
||||
const pgClient = new Client({ connectionString: process.env.DATABASE_URL })
|
||||
|
||||
pgClient.query('LISTEN market_updates')
|
||||
|
||||
pgClient.on('notification', async (msg) => {
|
||||
const update = JSON.parse(msg.payload)
|
||||
|
||||
await clickhouse.insert('market_updates', [
|
||||
{
|
||||
market_id: update.id,
|
||||
event_type: update.operation, // INSERT, UPDATE, DELETE
|
||||
timestamp: new Date(),
|
||||
data: JSON.stringify(update.new_data)
|
||||
}
|
||||
])
|
||||
})
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Partitioning Strategy
|
||||
- Partition by time (usually month or day)
|
||||
- Avoid too many partitions (performance impact)
|
||||
- Use DATE type for partition key
|
||||
|
||||
### 2. Ordering Key
|
||||
- Put most frequently filtered columns first
|
||||
- Consider cardinality (high cardinality first)
|
||||
- Order impacts compression
|
||||
|
||||
### 3. Data Types
|
||||
- Use smallest appropriate type (UInt32 vs UInt64)
|
||||
- Use LowCardinality for repeated strings
|
||||
- Use Enum for categorical data
|
||||
|
||||
### 4. Avoid
|
||||
- SELECT * (specify columns)
|
||||
- FINAL (merge data before query instead)
|
||||
- Too many JOINs (denormalize for analytics)
|
||||
- Small frequent inserts (batch instead)
|
||||
|
||||
### 5. Monitoring
|
||||
- Track query performance
|
||||
- Monitor disk usage
|
||||
- Check merge operations
|
||||
- Review slow query log
|
||||
|
||||
**Remember**: ClickHouse excels at analytical workloads. Design tables for your query patterns, batch inserts, and leverage materialized views for real-time aggregations.
|
||||
522
skills/cc-skill-coding-standards/SKILL.md
Normal file
522
skills/cc-skill-coding-standards/SKILL.md
Normal file
@@ -0,0 +1,522 @@
|
||||
---
|
||||
name: coding-standards
|
||||
description: Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Coding Standards & Best Practices
|
||||
|
||||
Universal coding standards applicable across all projects.
|
||||
|
||||
## Code Quality Principles
|
||||
|
||||
### 1. Readability First
|
||||
- Code is read more than written
|
||||
- Clear variable and function names
|
||||
- Self-documenting code preferred over comments
|
||||
- Consistent formatting
|
||||
|
||||
### 2. KISS (Keep It Simple, Stupid)
|
||||
- Simplest solution that works
|
||||
- Avoid over-engineering
|
||||
- No premature optimization
|
||||
- Easy to understand > clever code
|
||||
|
||||
### 3. DRY (Don't Repeat Yourself)
|
||||
- Extract common logic into functions
|
||||
- Create reusable components
|
||||
- Share utilities across modules
|
||||
- Avoid copy-paste programming
|
||||
|
||||
### 4. YAGNI (You Aren't Gonna Need It)
|
||||
- Don't build features before they're needed
|
||||
- Avoid speculative generality
|
||||
- Add complexity only when required
|
||||
- Start simple, refactor when needed
|
||||
|
||||
## TypeScript/JavaScript Standards
|
||||
|
||||
### Variable Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive names
|
||||
const marketSearchQuery = 'election'
|
||||
const isUserAuthenticated = true
|
||||
const totalRevenue = 1000
|
||||
|
||||
// ❌ BAD: Unclear names
|
||||
const q = 'election'
|
||||
const flag = true
|
||||
const x = 1000
|
||||
```
|
||||
|
||||
### Function Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Verb-noun pattern
|
||||
async function fetchMarketData(marketId: string) { }
|
||||
function calculateSimilarity(a: number[], b: number[]) { }
|
||||
function isValidEmail(email: string): boolean { }
|
||||
|
||||
// ❌ BAD: Unclear or noun-only
|
||||
async function market(id: string) { }
|
||||
function similarity(a, b) { }
|
||||
function email(e) { }
|
||||
```
|
||||
|
||||
### Immutability Pattern (CRITICAL)
|
||||
|
||||
```typescript
|
||||
// ✅ ALWAYS use spread operator
|
||||
const updatedUser = {
|
||||
...user,
|
||||
name: 'New Name'
|
||||
}
|
||||
|
||||
const updatedArray = [...items, newItem]
|
||||
|
||||
// ❌ NEVER mutate directly
|
||||
user.name = 'New Name' // BAD
|
||||
items.push(newItem) // BAD
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Comprehensive error handling
|
||||
async function fetchData(url: string) {
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
console.error('Fetch failed:', error)
|
||||
throw new Error('Failed to fetch data')
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ BAD: No error handling
|
||||
async function fetchData(url) {
|
||||
const response = await fetch(url)
|
||||
return response.json()
|
||||
}
|
||||
```
|
||||
|
||||
### Async/Await Best Practices
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Parallel execution when possible
|
||||
const [users, markets, stats] = await Promise.all([
|
||||
fetchUsers(),
|
||||
fetchMarkets(),
|
||||
fetchStats()
|
||||
])
|
||||
|
||||
// ❌ BAD: Sequential when unnecessary
|
||||
const users = await fetchUsers()
|
||||
const markets = await fetchMarkets()
|
||||
const stats = await fetchStats()
|
||||
```
|
||||
|
||||
### Type Safety
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper types
|
||||
interface Market {
|
||||
id: string
|
||||
name: string
|
||||
status: 'active' | 'resolved' | 'closed'
|
||||
created_at: Date
|
||||
}
|
||||
|
||||
function getMarket(id: string): Promise<Market> {
|
||||
// Implementation
|
||||
}
|
||||
|
||||
// ❌ BAD: Using 'any'
|
||||
function getMarket(id: any): Promise<any> {
|
||||
// Implementation
|
||||
}
|
||||
```
|
||||
|
||||
## React Best Practices
|
||||
|
||||
### Component Structure
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Functional component with types
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode
|
||||
onClick: () => void
|
||||
disabled?: boolean
|
||||
variant?: 'primary' | 'secondary'
|
||||
}
|
||||
|
||||
export function Button({
|
||||
children,
|
||||
onClick,
|
||||
disabled = false,
|
||||
variant = 'primary'
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
className={`btn btn-${variant}`}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
// ❌ BAD: No types, unclear structure
|
||||
export function Button(props) {
|
||||
return <button onClick={props.onClick}>{props.children}</button>
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Hooks
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Reusable custom hook
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedValue(value)
|
||||
}, delay)
|
||||
|
||||
return () => clearTimeout(handler)
|
||||
}, [value, delay])
|
||||
|
||||
return debouncedValue
|
||||
}
|
||||
|
||||
// Usage
|
||||
const debouncedQuery = useDebounce(searchQuery, 500)
|
||||
```
|
||||
|
||||
### State Management
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper state updates
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
// Functional update for state based on previous state
|
||||
setCount(prev => prev + 1)
|
||||
|
||||
// ❌ BAD: Direct state reference
|
||||
setCount(count + 1) // Can be stale in async scenarios
|
||||
```
|
||||
|
||||
### Conditional Rendering
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Clear conditional rendering
|
||||
{isLoading && <Spinner />}
|
||||
{error && <ErrorMessage error={error} />}
|
||||
{data && <DataDisplay data={data} />}
|
||||
|
||||
// ❌ BAD: Ternary hell
|
||||
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
|
||||
```
|
||||
|
||||
## API Design Standards
|
||||
|
||||
### REST API Conventions
|
||||
|
||||
```
|
||||
GET /api/markets # List all markets
|
||||
GET /api/markets/:id # Get specific market
|
||||
POST /api/markets # Create new market
|
||||
PUT /api/markets/:id # Update market (full)
|
||||
PATCH /api/markets/:id # Update market (partial)
|
||||
DELETE /api/markets/:id # Delete market
|
||||
|
||||
# Query parameters for filtering
|
||||
GET /api/markets?status=active&limit=10&offset=0
|
||||
```
|
||||
|
||||
### Response Format
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Consistent response structure
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
error?: string
|
||||
meta?: {
|
||||
total: number
|
||||
page: number
|
||||
limit: number
|
||||
}
|
||||
}
|
||||
|
||||
// Success response
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: markets,
|
||||
meta: { total: 100, page: 1, limit: 10 }
|
||||
})
|
||||
|
||||
// Error response
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Invalid request'
|
||||
}, { status: 400 })
|
||||
```
|
||||
|
||||
### Input Validation
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// ✅ GOOD: Schema validation
|
||||
const CreateMarketSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
description: z.string().min(1).max(2000),
|
||||
endDate: z.string().datetime(),
|
||||
categories: z.array(z.string()).min(1)
|
||||
})
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const body = await request.json()
|
||||
|
||||
try {
|
||||
const validated = CreateMarketSchema.parse(body)
|
||||
// Proceed with validated data
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors
|
||||
}, { status: 400 })
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## File Organization
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── app/ # Next.js App Router
|
||||
│ ├── api/ # API routes
|
||||
│ ├── markets/ # Market pages
|
||||
│ └── (auth)/ # Auth pages (route groups)
|
||||
├── components/ # React components
|
||||
│ ├── ui/ # Generic UI components
|
||||
│ ├── forms/ # Form components
|
||||
│ └── layouts/ # Layout components
|
||||
├── hooks/ # Custom React hooks
|
||||
├── lib/ # Utilities and configs
|
||||
│ ├── api/ # API clients
|
||||
│ ├── utils/ # Helper functions
|
||||
│ └── constants/ # Constants
|
||||
├── types/ # TypeScript types
|
||||
└── styles/ # Global styles
|
||||
```
|
||||
|
||||
### File Naming
|
||||
|
||||
```
|
||||
components/Button.tsx # PascalCase for components
|
||||
hooks/useAuth.ts # camelCase with 'use' prefix
|
||||
lib/formatDate.ts # camelCase for utilities
|
||||
types/market.types.ts # camelCase with .types suffix
|
||||
```
|
||||
|
||||
## Comments & Documentation
|
||||
|
||||
### When to Comment
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Explain WHY, not WHAT
|
||||
// Use exponential backoff to avoid overwhelming the API during outages
|
||||
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
|
||||
|
||||
// Deliberately using mutation here for performance with large arrays
|
||||
items.push(newItem)
|
||||
|
||||
// ❌ BAD: Stating the obvious
|
||||
// Increment counter by 1
|
||||
count++
|
||||
|
||||
// Set name to user's name
|
||||
name = user.name
|
||||
```
|
||||
|
||||
### JSDoc for Public APIs
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Searches markets using semantic similarity.
|
||||
*
|
||||
* @param query - Natural language search query
|
||||
* @param limit - Maximum number of results (default: 10)
|
||||
* @returns Array of markets sorted by similarity score
|
||||
* @throws {Error} If OpenAI API fails or Redis unavailable
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const results = await searchMarkets('election', 5)
|
||||
* console.log(results[0].name) // "Trump vs Biden"
|
||||
* ```
|
||||
*/
|
||||
export async function searchMarkets(
|
||||
query: string,
|
||||
limit: number = 10
|
||||
): Promise<Market[]> {
|
||||
// Implementation
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Best Practices
|
||||
|
||||
### Memoization
|
||||
|
||||
```typescript
|
||||
import { useMemo, useCallback } from 'react'
|
||||
|
||||
// ✅ GOOD: Memoize expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ GOOD: Memoize callbacks
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
```
|
||||
|
||||
### Lazy Loading
|
||||
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ GOOD: Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
|
||||
export function Dashboard() {
|
||||
return (
|
||||
<Suspense fallback={<Spinner />}>
|
||||
<HeavyChart />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Database Queries
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status')
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
```
|
||||
|
||||
## Testing Standards
|
||||
|
||||
### Test Structure (AAA Pattern)
|
||||
|
||||
```typescript
|
||||
test('calculates similarity correctly', () => {
|
||||
// Arrange
|
||||
const vector1 = [1, 0, 0]
|
||||
const vector2 = [0, 1, 0]
|
||||
|
||||
// Act
|
||||
const similarity = calculateCosineSimilarity(vector1, vector2)
|
||||
|
||||
// Assert
|
||||
expect(similarity).toBe(0)
|
||||
})
|
||||
```
|
||||
|
||||
### Test Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive test names
|
||||
test('returns empty array when no markets match query', () => { })
|
||||
test('throws error when OpenAI API key is missing', () => { })
|
||||
test('falls back to substring search when Redis unavailable', () => { })
|
||||
|
||||
// ❌ BAD: Vague test names
|
||||
test('works', () => { })
|
||||
test('test search', () => { })
|
||||
```
|
||||
|
||||
## Code Smell Detection
|
||||
|
||||
Watch for these anti-patterns:
|
||||
|
||||
### 1. Long Functions
|
||||
```typescript
|
||||
// ❌ BAD: Function > 50 lines
|
||||
function processMarketData() {
|
||||
// 100 lines of code
|
||||
}
|
||||
|
||||
// ✅ GOOD: Split into smaller functions
|
||||
function processMarketData() {
|
||||
const validated = validateData()
|
||||
const transformed = transformData(validated)
|
||||
return saveData(transformed)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Deep Nesting
|
||||
```typescript
|
||||
// ❌ BAD: 5+ levels of nesting
|
||||
if (user) {
|
||||
if (user.isAdmin) {
|
||||
if (market) {
|
||||
if (market.isActive) {
|
||||
if (hasPermission) {
|
||||
// Do something
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ GOOD: Early returns
|
||||
if (!user) return
|
||||
if (!user.isAdmin) return
|
||||
if (!market) return
|
||||
if (!market.isActive) return
|
||||
if (!hasPermission) return
|
||||
|
||||
// Do something
|
||||
```
|
||||
|
||||
### 3. Magic Numbers
|
||||
```typescript
|
||||
// ❌ BAD: Unexplained numbers
|
||||
if (retryCount > 3) { }
|
||||
setTimeout(callback, 500)
|
||||
|
||||
// ✅ GOOD: Named constants
|
||||
const MAX_RETRIES = 3
|
||||
const DEBOUNCE_DELAY_MS = 500
|
||||
|
||||
if (retryCount > MAX_RETRIES) { }
|
||||
setTimeout(callback, DEBOUNCE_DELAY_MS)
|
||||
```
|
||||
|
||||
**Remember**: Code quality is not negotiable. Clear, maintainable code enables rapid development and confident refactoring.
|
||||
10
skills/cc-skill-continuous-learning/SKILL.md
Normal file
10
skills/cc-skill-continuous-learning/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: cc-skill-continuous-learning
|
||||
description: Development skill from everything-claude-code
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# cc-skill-continuous-learning
|
||||
|
||||
Development skill skill.
|
||||
18
skills/cc-skill-continuous-learning/config.json
Normal file
18
skills/cc-skill-continuous-learning/config.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"min_session_length": 10,
|
||||
"extraction_threshold": "medium",
|
||||
"auto_approve": false,
|
||||
"learned_skills_path": "~/.claude/skills/learned/",
|
||||
"patterns_to_detect": [
|
||||
"error_resolution",
|
||||
"user_corrections",
|
||||
"workarounds",
|
||||
"debugging_techniques",
|
||||
"project_specific"
|
||||
],
|
||||
"ignore_patterns": [
|
||||
"simple_typos",
|
||||
"one_time_fixes",
|
||||
"external_api_issues"
|
||||
]
|
||||
}
|
||||
60
skills/cc-skill-continuous-learning/evaluate-session.sh
Executable file
60
skills/cc-skill-continuous-learning/evaluate-session.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
# Continuous Learning - Session Evaluator
|
||||
# Runs on Stop hook to extract reusable patterns from Claude Code sessions
|
||||
#
|
||||
# Why Stop hook instead of UserPromptSubmit:
|
||||
# - Stop runs once at session end (lightweight)
|
||||
# - UserPromptSubmit runs every message (heavy, adds latency)
|
||||
#
|
||||
# Hook config (in ~/.claude/settings.json):
|
||||
# {
|
||||
# "hooks": {
|
||||
# "Stop": [{
|
||||
# "matcher": "*",
|
||||
# "hooks": [{
|
||||
# "type": "command",
|
||||
# "command": "~/.claude/skills/continuous-learning/evaluate-session.sh"
|
||||
# }]
|
||||
# }]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# Patterns to detect: error_resolution, debugging_techniques, workarounds, project_specific
|
||||
# Patterns to ignore: simple_typos, one_time_fixes, external_api_issues
|
||||
# Extracted skills saved to: ~/.claude/skills/learned/
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="$SCRIPT_DIR/config.json"
|
||||
LEARNED_SKILLS_PATH="${HOME}/.claude/skills/learned"
|
||||
MIN_SESSION_LENGTH=10
|
||||
|
||||
# Load config if exists
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
MIN_SESSION_LENGTH=$(jq -r '.min_session_length // 10' "$CONFIG_FILE")
|
||||
LEARNED_SKILLS_PATH=$(jq -r '.learned_skills_path // "~/.claude/skills/learned/"' "$CONFIG_FILE" | sed "s|~|$HOME|")
|
||||
fi
|
||||
|
||||
# Ensure learned skills directory exists
|
||||
mkdir -p "$LEARNED_SKILLS_PATH"
|
||||
|
||||
# Get transcript path from environment (set by Claude Code)
|
||||
transcript_path="${CLAUDE_TRANSCRIPT_PATH:-}"
|
||||
|
||||
if [ -z "$transcript_path" ] || [ ! -f "$transcript_path" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Count messages in session
|
||||
message_count=$(grep -c '"type":"user"' "$transcript_path" 2>/dev/null || echo "0")
|
||||
|
||||
# Skip short sessions
|
||||
if [ "$message_count" -lt "$MIN_SESSION_LENGTH" ]; then
|
||||
echo "[ContinuousLearning] Session too short ($message_count messages), skipping" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Signal to Claude that session should be evaluated for extractable patterns
|
||||
echo "[ContinuousLearning] Session has $message_count messages - evaluate for extractable patterns" >&2
|
||||
echo "[ContinuousLearning] Save learned skills to: $LEARNED_SKILLS_PATH" >&2
|
||||
633
skills/cc-skill-frontend-patterns/SKILL.md
Normal file
633
skills/cc-skill-frontend-patterns/SKILL.md
Normal file
@@ -0,0 +1,633 @@
|
||||
---
|
||||
name: frontend-patterns
|
||||
description: Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Frontend Development Patterns
|
||||
|
||||
Modern frontend patterns for React, Next.js, and performant user interfaces.
|
||||
|
||||
## Component Patterns
|
||||
|
||||
### Composition Over Inheritance
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Component composition
|
||||
interface CardProps {
|
||||
children: React.ReactNode
|
||||
variant?: 'default' | 'outlined'
|
||||
}
|
||||
|
||||
export function Card({ children, variant = 'default' }: CardProps) {
|
||||
return <div className={`card card-${variant}`}>{children}</div>
|
||||
}
|
||||
|
||||
export function CardHeader({ children }: { children: React.ReactNode }) {
|
||||
return <div className="card-header">{children}</div>
|
||||
}
|
||||
|
||||
export function CardBody({ children }: { children: React.ReactNode }) {
|
||||
return <div className="card-body">{children}</div>
|
||||
}
|
||||
|
||||
// Usage
|
||||
<Card>
|
||||
<CardHeader>Title</CardHeader>
|
||||
<CardBody>Content</CardBody>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### Compound Components
|
||||
|
||||
```typescript
|
||||
interface TabsContextValue {
|
||||
activeTab: string
|
||||
setActiveTab: (tab: string) => void
|
||||
}
|
||||
|
||||
const TabsContext = createContext<TabsContextValue | undefined>(undefined)
|
||||
|
||||
export function Tabs({ children, defaultTab }: {
|
||||
children: React.ReactNode
|
||||
defaultTab: string
|
||||
}) {
|
||||
const [activeTab, setActiveTab] = useState(defaultTab)
|
||||
|
||||
return (
|
||||
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
|
||||
{children}
|
||||
</TabsContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function TabList({ children }: { children: React.ReactNode }) {
|
||||
return <div className="tab-list">{children}</div>
|
||||
}
|
||||
|
||||
export function Tab({ id, children }: { id: string, children: React.ReactNode }) {
|
||||
const context = useContext(TabsContext)
|
||||
if (!context) throw new Error('Tab must be used within Tabs')
|
||||
|
||||
return (
|
||||
<button
|
||||
className={context.activeTab === id ? 'active' : ''}
|
||||
onClick={() => context.setActiveTab(id)}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
// Usage
|
||||
<Tabs defaultTab="overview">
|
||||
<TabList>
|
||||
<Tab id="overview">Overview</Tab>
|
||||
<Tab id="details">Details</Tab>
|
||||
</TabList>
|
||||
</Tabs>
|
||||
```
|
||||
|
||||
### Render Props Pattern
|
||||
|
||||
```typescript
|
||||
interface DataLoaderProps<T> {
|
||||
url: string
|
||||
children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode
|
||||
}
|
||||
|
||||
export function DataLoader<T>({ url, children }: DataLoaderProps<T>) {
|
||||
const [data, setData] = useState<T | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
fetch(url)
|
||||
.then(res => res.json())
|
||||
.then(setData)
|
||||
.catch(setError)
|
||||
.finally(() => setLoading(false))
|
||||
}, [url])
|
||||
|
||||
return <>{children(data, loading, error)}</>
|
||||
}
|
||||
|
||||
// Usage
|
||||
<DataLoader<Market[]> url="/api/markets">
|
||||
{(markets, loading, error) => {
|
||||
if (loading) return <Spinner />
|
||||
if (error) return <Error error={error} />
|
||||
return <MarketList markets={markets!} />
|
||||
}}
|
||||
</DataLoader>
|
||||
```
|
||||
|
||||
## Custom Hooks Patterns
|
||||
|
||||
### State Management Hook
|
||||
|
||||
```typescript
|
||||
export function useToggle(initialValue = false): [boolean, () => void] {
|
||||
const [value, setValue] = useState(initialValue)
|
||||
|
||||
const toggle = useCallback(() => {
|
||||
setValue(v => !v)
|
||||
}, [])
|
||||
|
||||
return [value, toggle]
|
||||
}
|
||||
|
||||
// Usage
|
||||
const [isOpen, toggleOpen] = useToggle()
|
||||
```
|
||||
|
||||
### Async Data Fetching Hook
|
||||
|
||||
```typescript
|
||||
interface UseQueryOptions<T> {
|
||||
onSuccess?: (data: T) => void
|
||||
onError?: (error: Error) => void
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export function useQuery<T>(
|
||||
key: string,
|
||||
fetcher: () => Promise<T>,
|
||||
options?: UseQueryOptions<T>
|
||||
) {
|
||||
const [data, setData] = useState<T | null>(null)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const refetch = useCallback(async () => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const result = await fetcher()
|
||||
setData(result)
|
||||
options?.onSuccess?.(result)
|
||||
} catch (err) {
|
||||
const error = err as Error
|
||||
setError(error)
|
||||
options?.onError?.(error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [fetcher, options])
|
||||
|
||||
useEffect(() => {
|
||||
if (options?.enabled !== false) {
|
||||
refetch()
|
||||
}
|
||||
}, [key, refetch, options?.enabled])
|
||||
|
||||
return { data, error, loading, refetch }
|
||||
}
|
||||
|
||||
// Usage
|
||||
const { data: markets, loading, error, refetch } = useQuery(
|
||||
'markets',
|
||||
() => fetch('/api/markets').then(r => r.json()),
|
||||
{
|
||||
onSuccess: data => console.log('Fetched', data.length, 'markets'),
|
||||
onError: err => console.error('Failed:', err)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Debounce Hook
|
||||
|
||||
```typescript
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedValue(value)
|
||||
}, delay)
|
||||
|
||||
return () => clearTimeout(handler)
|
||||
}, [value, delay])
|
||||
|
||||
return debouncedValue
|
||||
}
|
||||
|
||||
// Usage
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const debouncedQuery = useDebounce(searchQuery, 500)
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedQuery) {
|
||||
performSearch(debouncedQuery)
|
||||
}
|
||||
}, [debouncedQuery])
|
||||
```
|
||||
|
||||
## State Management Patterns
|
||||
|
||||
### Context + Reducer Pattern
|
||||
|
||||
```typescript
|
||||
interface State {
|
||||
markets: Market[]
|
||||
selectedMarket: Market | null
|
||||
loading: boolean
|
||||
}
|
||||
|
||||
type Action =
|
||||
| { type: 'SET_MARKETS'; payload: Market[] }
|
||||
| { type: 'SELECT_MARKET'; payload: Market }
|
||||
| { type: 'SET_LOADING'; payload: boolean }
|
||||
|
||||
function reducer(state: State, action: Action): State {
|
||||
switch (action.type) {
|
||||
case 'SET_MARKETS':
|
||||
return { ...state, markets: action.payload }
|
||||
case 'SELECT_MARKET':
|
||||
return { ...state, selectedMarket: action.payload }
|
||||
case 'SET_LOADING':
|
||||
return { ...state, loading: action.payload }
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
const MarketContext = createContext<{
|
||||
state: State
|
||||
dispatch: Dispatch<Action>
|
||||
} | undefined>(undefined)
|
||||
|
||||
export function MarketProvider({ children }: { children: React.ReactNode }) {
|
||||
const [state, dispatch] = useReducer(reducer, {
|
||||
markets: [],
|
||||
selectedMarket: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<MarketContext.Provider value={{ state, dispatch }}>
|
||||
{children}
|
||||
</MarketContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useMarkets() {
|
||||
const context = useContext(MarketContext)
|
||||
if (!context) throw new Error('useMarkets must be used within MarketProvider')
|
||||
return context
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Memoization
|
||||
|
||||
```typescript
|
||||
// ✅ useMemo for expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ useCallback for functions passed to children
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
|
||||
// ✅ React.memo for pure components
|
||||
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
return (
|
||||
<div className="market-card">
|
||||
<h3>{market.name}</h3>
|
||||
<p>{market.description}</p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
```
|
||||
|
||||
### Code Splitting & Lazy Loading
|
||||
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
|
||||
|
||||
export function Dashboard() {
|
||||
return (
|
||||
<div>
|
||||
<Suspense fallback={<ChartSkeleton />}>
|
||||
<HeavyChart data={data} />
|
||||
</Suspense>
|
||||
|
||||
<Suspense fallback={null}>
|
||||
<ThreeJsBackground />
|
||||
</Suspense>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Virtualization for Long Lists
|
||||
|
||||
```typescript
|
||||
import { useVirtualizer } from '@tanstack/react-virtual'
|
||||
|
||||
export function VirtualMarketList({ markets }: { markets: Market[] }) {
|
||||
const parentRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const virtualizer = useVirtualizer({
|
||||
count: markets.length,
|
||||
getScrollElement: () => parentRef.current,
|
||||
estimateSize: () => 100, // Estimated row height
|
||||
overscan: 5 // Extra items to render
|
||||
})
|
||||
|
||||
return (
|
||||
<div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}>
|
||||
<div
|
||||
style={{
|
||||
height: `${virtualizer.getTotalSize()}px`,
|
||||
position: 'relative'
|
||||
}}
|
||||
>
|
||||
{virtualizer.getVirtualItems().map(virtualRow => (
|
||||
<div
|
||||
key={virtualRow.index}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: `${virtualRow.size}px`,
|
||||
transform: `translateY(${virtualRow.start}px)`
|
||||
}}
|
||||
>
|
||||
<MarketCard market={markets[virtualRow.index]} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Form Handling Patterns
|
||||
|
||||
### Controlled Form with Validation
|
||||
|
||||
```typescript
|
||||
interface FormData {
|
||||
name: string
|
||||
description: string
|
||||
endDate: string
|
||||
}
|
||||
|
||||
interface FormErrors {
|
||||
name?: string
|
||||
description?: string
|
||||
endDate?: string
|
||||
}
|
||||
|
||||
export function CreateMarketForm() {
|
||||
const [formData, setFormData] = useState<FormData>({
|
||||
name: '',
|
||||
description: '',
|
||||
endDate: ''
|
||||
})
|
||||
|
||||
const [errors, setErrors] = useState<FormErrors>({})
|
||||
|
||||
const validate = (): boolean => {
|
||||
const newErrors: FormErrors = {}
|
||||
|
||||
if (!formData.name.trim()) {
|
||||
newErrors.name = 'Name is required'
|
||||
} else if (formData.name.length > 200) {
|
||||
newErrors.name = 'Name must be under 200 characters'
|
||||
}
|
||||
|
||||
if (!formData.description.trim()) {
|
||||
newErrors.description = 'Description is required'
|
||||
}
|
||||
|
||||
if (!formData.endDate) {
|
||||
newErrors.endDate = 'End date is required'
|
||||
}
|
||||
|
||||
setErrors(newErrors)
|
||||
return Object.keys(newErrors).length === 0
|
||||
}
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (!validate()) return
|
||||
|
||||
try {
|
||||
await createMarket(formData)
|
||||
// Success handling
|
||||
} catch (error) {
|
||||
// Error handling
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<input
|
||||
value={formData.name}
|
||||
onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}
|
||||
placeholder="Market name"
|
||||
/>
|
||||
{errors.name && <span className="error">{errors.name}</span>}
|
||||
|
||||
{/* Other fields */}
|
||||
|
||||
<button type="submit">Create Market</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Error Boundary Pattern
|
||||
|
||||
```typescript
|
||||
interface ErrorBoundaryState {
|
||||
hasError: boolean
|
||||
error: Error | null
|
||||
}
|
||||
|
||||
export class ErrorBoundary extends React.Component<
|
||||
{ children: React.ReactNode },
|
||||
ErrorBoundaryState
|
||||
> {
|
||||
state: ErrorBoundaryState = {
|
||||
hasError: false,
|
||||
error: null
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
||||
return { hasError: true, error }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
||||
console.error('Error boundary caught:', error, errorInfo)
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div className="error-fallback">
|
||||
<h2>Something went wrong</h2>
|
||||
<p>{this.state.error?.message}</p>
|
||||
<button onClick={() => this.setState({ hasError: false })}>
|
||||
Try again
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return this.props.children
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
<ErrorBoundary>
|
||||
<App />
|
||||
</ErrorBoundary>
|
||||
```
|
||||
|
||||
## Animation Patterns
|
||||
|
||||
### Framer Motion Animations
|
||||
|
||||
```typescript
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
|
||||
// ✅ List animations
|
||||
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{markets.map(market => (
|
||||
<motion.div
|
||||
key={market.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<MarketCard market={market} />
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ Modal animations
|
||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
<>
|
||||
<motion.div
|
||||
className="modal-overlay"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={onClose}
|
||||
/>
|
||||
<motion.div
|
||||
className="modal-content"
|
||||
initial={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Accessibility Patterns
|
||||
|
||||
### Keyboard Navigation
|
||||
|
||||
```typescript
|
||||
export function Dropdown({ options, onSelect }: DropdownProps) {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [activeIndex, setActiveIndex] = useState(0)
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||
switch (e.key) {
|
||||
case 'ArrowDown':
|
||||
e.preventDefault()
|
||||
setActiveIndex(i => Math.min(i + 1, options.length - 1))
|
||||
break
|
||||
case 'ArrowUp':
|
||||
e.preventDefault()
|
||||
setActiveIndex(i => Math.max(i - 1, 0))
|
||||
break
|
||||
case 'Enter':
|
||||
e.preventDefault()
|
||||
onSelect(options[activeIndex])
|
||||
setIsOpen(false)
|
||||
break
|
||||
case 'Escape':
|
||||
setIsOpen(false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role="combobox"
|
||||
aria-expanded={isOpen}
|
||||
aria-haspopup="listbox"
|
||||
onKeyDown={handleKeyDown}
|
||||
>
|
||||
{/* Dropdown implementation */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Focus Management
|
||||
|
||||
```typescript
|
||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||
const modalRef = useRef<HTMLDivElement>(null)
|
||||
const previousFocusRef = useRef<HTMLElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
// Save currently focused element
|
||||
previousFocusRef.current = document.activeElement as HTMLElement
|
||||
|
||||
// Focus modal
|
||||
modalRef.current?.focus()
|
||||
} else {
|
||||
// Restore focus when closing
|
||||
previousFocusRef.current?.focus()
|
||||
}
|
||||
}, [isOpen])
|
||||
|
||||
return isOpen ? (
|
||||
<div
|
||||
ref={modalRef}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
tabIndex={-1}
|
||||
onKeyDown={e => e.key === 'Escape' && onClose()}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
```
|
||||
|
||||
**Remember**: Modern frontend patterns enable maintainable, performant user interfaces. Choose patterns that fit your project complexity.
|
||||
352
skills/cc-skill-project-guidelines-example/SKILL.md
Normal file
352
skills/cc-skill-project-guidelines-example/SKILL.md
Normal file
@@ -0,0 +1,352 @@
|
||||
---
|
||||
name: cc-skill-project-guidelines-example
|
||||
description: Project Guidelines Skill (Example)
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Project Guidelines Skill (Example)
|
||||
|
||||
This is an example of a project-specific skill. Use this as a template for your own projects.
|
||||
|
||||
Based on a real production application: [Zenith](https://zenith.chat) - AI-powered customer discovery platform.
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
Reference this skill when working on the specific project it's designed for. Project skills contain:
|
||||
- Architecture overview
|
||||
- File structure
|
||||
- Code patterns
|
||||
- Testing requirements
|
||||
- Deployment workflow
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
**Tech Stack:**
|
||||
- **Frontend**: Next.js 15 (App Router), TypeScript, React
|
||||
- **Backend**: FastAPI (Python), Pydantic models
|
||||
- **Database**: Supabase (PostgreSQL)
|
||||
- **AI**: Claude API with tool calling and structured output
|
||||
- **Deployment**: Google Cloud Run
|
||||
- **Testing**: Playwright (E2E), pytest (backend), React Testing Library
|
||||
|
||||
**Services:**
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Frontend │
|
||||
│ Next.js 15 + TypeScript + TailwindCSS │
|
||||
│ Deployed: Vercel / Cloud Run │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Backend │
|
||||
│ FastAPI + Python 3.11 + Pydantic │
|
||||
│ Deployed: Cloud Run │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┼───────────────┐
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ Supabase │ │ Claude │ │ Redis │
|
||||
│ Database │ │ API │ │ Cache │
|
||||
└──────────┘ └──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
project/
|
||||
├── frontend/
|
||||
│ └── src/
|
||||
│ ├── app/ # Next.js app router pages
|
||||
│ │ ├── api/ # API routes
|
||||
│ │ ├── (auth)/ # Auth-protected routes
|
||||
│ │ └── workspace/ # Main app workspace
|
||||
│ ├── components/ # React components
|
||||
│ │ ├── ui/ # Base UI components
|
||||
│ │ ├── forms/ # Form components
|
||||
│ │ └── layouts/ # Layout components
|
||||
│ ├── hooks/ # Custom React hooks
|
||||
│ ├── lib/ # Utilities
|
||||
│ ├── types/ # TypeScript definitions
|
||||
│ └── config/ # Configuration
|
||||
│
|
||||
├── backend/
|
||||
│ ├── routers/ # FastAPI route handlers
|
||||
│ ├── models.py # Pydantic models
|
||||
│ ├── main.py # FastAPI app entry
|
||||
│ ├── auth_system.py # Authentication
|
||||
│ ├── database.py # Database operations
|
||||
│ ├── services/ # Business logic
|
||||
│ └── tests/ # pytest tests
|
||||
│
|
||||
├── deploy/ # Deployment configs
|
||||
├── docs/ # Documentation
|
||||
└── scripts/ # Utility scripts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Code Patterns
|
||||
|
||||
### API Response Format (FastAPI)
|
||||
|
||||
```python
|
||||
from pydantic import BaseModel
|
||||
from typing import Generic, TypeVar, Optional
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
class ApiResponse(BaseModel, Generic[T]):
|
||||
success: bool
|
||||
data: Optional[T] = None
|
||||
error: Optional[str] = None
|
||||
|
||||
@classmethod
|
||||
def ok(cls, data: T) -> "ApiResponse[T]":
|
||||
return cls(success=True, data=data)
|
||||
|
||||
@classmethod
|
||||
def fail(cls, error: str) -> "ApiResponse[T]":
|
||||
return cls(success=False, error=error)
|
||||
```
|
||||
|
||||
### Frontend API Calls (TypeScript)
|
||||
|
||||
```typescript
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
error?: string
|
||||
}
|
||||
|
||||
async function fetchApi<T>(
|
||||
endpoint: string,
|
||||
options?: RequestInit
|
||||
): Promise<ApiResponse<T>> {
|
||||
try {
|
||||
const response = await fetch(`/api${endpoint}`, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options?.headers,
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
return { success: false, error: `HTTP ${response.status}` }
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
return { success: false, error: String(error) }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Claude AI Integration (Structured Output)
|
||||
|
||||
```python
|
||||
from anthropic import Anthropic
|
||||
from pydantic import BaseModel
|
||||
|
||||
class AnalysisResult(BaseModel):
|
||||
summary: str
|
||||
key_points: list[str]
|
||||
confidence: float
|
||||
|
||||
async def analyze_with_claude(content: str) -> AnalysisResult:
|
||||
client = Anthropic()
|
||||
|
||||
response = client.messages.create(
|
||||
model="claude-sonnet-4-5-20250514",
|
||||
max_tokens=1024,
|
||||
messages=[{"role": "user", "content": content}],
|
||||
tools=[{
|
||||
"name": "provide_analysis",
|
||||
"description": "Provide structured analysis",
|
||||
"input_schema": AnalysisResult.model_json_schema()
|
||||
}],
|
||||
tool_choice={"type": "tool", "name": "provide_analysis"}
|
||||
)
|
||||
|
||||
# Extract tool use result
|
||||
tool_use = next(
|
||||
block for block in response.content
|
||||
if block.type == "tool_use"
|
||||
)
|
||||
|
||||
return AnalysisResult(**tool_use.input)
|
||||
```
|
||||
|
||||
### Custom Hooks (React)
|
||||
|
||||
```typescript
|
||||
import { useState, useCallback } from 'react'
|
||||
|
||||
interface UseApiState<T> {
|
||||
data: T | null
|
||||
loading: boolean
|
||||
error: string | null
|
||||
}
|
||||
|
||||
export function useApi<T>(
|
||||
fetchFn: () => Promise<ApiResponse<T>>
|
||||
) {
|
||||
const [state, setState] = useState<UseApiState<T>>({
|
||||
data: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
})
|
||||
|
||||
const execute = useCallback(async () => {
|
||||
setState(prev => ({ ...prev, loading: true, error: null }))
|
||||
|
||||
const result = await fetchFn()
|
||||
|
||||
if (result.success) {
|
||||
setState({ data: result.data!, loading: false, error: null })
|
||||
} else {
|
||||
setState({ data: null, loading: false, error: result.error! })
|
||||
}
|
||||
}, [fetchFn])
|
||||
|
||||
return { ...state, execute }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
### Backend (pytest)
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
poetry run pytest tests/
|
||||
|
||||
# Run with coverage
|
||||
poetry run pytest tests/ --cov=. --cov-report=html
|
||||
|
||||
# Run specific test file
|
||||
poetry run pytest tests/test_auth.py -v
|
||||
```
|
||||
|
||||
**Test structure:**
|
||||
```python
|
||||
import pytest
|
||||
from httpx import AsyncClient
|
||||
from main import app
|
||||
|
||||
@pytest.fixture
|
||||
async def client():
|
||||
async with AsyncClient(app=app, base_url="http://test") as ac:
|
||||
yield ac
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_health_check(client: AsyncClient):
|
||||
response = await client.get("/health")
|
||||
assert response.status_code == 200
|
||||
assert response.json()["status"] == "healthy"
|
||||
```
|
||||
|
||||
### Frontend (React Testing Library)
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
npm run test
|
||||
|
||||
# Run with coverage
|
||||
npm run test -- --coverage
|
||||
|
||||
# Run E2E tests
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
**Test structure:**
|
||||
```typescript
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import { WorkspacePanel } from './WorkspacePanel'
|
||||
|
||||
describe('WorkspacePanel', () => {
|
||||
it('renders workspace correctly', () => {
|
||||
render(<WorkspacePanel />)
|
||||
expect(screen.getByRole('main')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('handles session creation', async () => {
|
||||
render(<WorkspacePanel />)
|
||||
fireEvent.click(screen.getByText('New Session'))
|
||||
expect(await screen.findByText('Session created')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment Workflow
|
||||
|
||||
### Pre-Deployment Checklist
|
||||
|
||||
- [ ] All tests passing locally
|
||||
- [ ] `npm run build` succeeds (frontend)
|
||||
- [ ] `poetry run pytest` passes (backend)
|
||||
- [ ] No hardcoded secrets
|
||||
- [ ] Environment variables documented
|
||||
- [ ] Database migrations ready
|
||||
|
||||
### Deployment Commands
|
||||
|
||||
```bash
|
||||
# Build and deploy frontend
|
||||
cd frontend && npm run build
|
||||
gcloud run deploy frontend --source .
|
||||
|
||||
# Build and deploy backend
|
||||
cd backend
|
||||
gcloud run deploy backend --source .
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Frontend (.env.local)
|
||||
NEXT_PUBLIC_API_URL=https://api.example.com
|
||||
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
|
||||
|
||||
# Backend (.env)
|
||||
DATABASE_URL=postgresql://...
|
||||
ANTHROPIC_API_KEY=sk-ant-...
|
||||
SUPABASE_URL=https://xxx.supabase.co
|
||||
SUPABASE_KEY=eyJ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Critical Rules
|
||||
|
||||
1. **No emojis** in code, comments, or documentation
|
||||
2. **Immutability** - never mutate objects or arrays
|
||||
3. **TDD** - write tests before implementation
|
||||
4. **80% coverage** minimum
|
||||
5. **Many small files** - 200-400 lines typical, 800 max
|
||||
6. **No console.log** in production code
|
||||
7. **Proper error handling** with try/catch
|
||||
8. **Input validation** with Pydantic/Zod
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `coding-standards.md` - General coding best practices
|
||||
- `backend-patterns.md` - API and database patterns
|
||||
- `frontend-patterns.md` - React and Next.js patterns
|
||||
- `tdd-workflow/` - Test-driven development methodology
|
||||
496
skills/cc-skill-security-review/SKILL.md
Normal file
496
skills/cc-skill-security-review/SKILL.md
Normal file
@@ -0,0 +1,496 @@
|
||||
---
|
||||
name: security-review
|
||||
description: Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Security Review Skill
|
||||
|
||||
This skill ensures all code follows security best practices and identifies potential vulnerabilities.
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Implementing authentication or authorization
|
||||
- Handling user input or file uploads
|
||||
- Creating new API endpoints
|
||||
- Working with secrets or credentials
|
||||
- Implementing payment features
|
||||
- Storing or transmitting sensitive data
|
||||
- Integrating third-party APIs
|
||||
|
||||
## Security Checklist
|
||||
|
||||
### 1. Secrets Management
|
||||
|
||||
#### ❌ NEVER Do This
|
||||
```typescript
|
||||
const apiKey = "sk-proj-xxxxx" // Hardcoded secret
|
||||
const dbPassword = "password123" // In source code
|
||||
```
|
||||
|
||||
#### ✅ ALWAYS Do This
|
||||
```typescript
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
const dbUrl = process.env.DATABASE_URL
|
||||
|
||||
// Verify secrets exist
|
||||
if (!apiKey) {
|
||||
throw new Error('OPENAI_API_KEY not configured')
|
||||
}
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] No hardcoded API keys, tokens, or passwords
|
||||
- [ ] All secrets in environment variables
|
||||
- [ ] `.env.local` in .gitignore
|
||||
- [ ] No secrets in git history
|
||||
- [ ] Production secrets in hosting platform (Vercel, Railway)
|
||||
|
||||
### 2. Input Validation
|
||||
|
||||
#### Always Validate User Input
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// Define validation schema
|
||||
const CreateUserSchema = z.object({
|
||||
email: z.string().email(),
|
||||
name: z.string().min(1).max(100),
|
||||
age: z.number().int().min(0).max(150)
|
||||
})
|
||||
|
||||
// Validate before processing
|
||||
export async function createUser(input: unknown) {
|
||||
try {
|
||||
const validated = CreateUserSchema.parse(input)
|
||||
return await db.users.create(validated)
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return { success: false, errors: error.errors }
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### File Upload Validation
|
||||
```typescript
|
||||
function validateFileUpload(file: File) {
|
||||
// Size check (5MB max)
|
||||
const maxSize = 5 * 1024 * 1024
|
||||
if (file.size > maxSize) {
|
||||
throw new Error('File too large (max 5MB)')
|
||||
}
|
||||
|
||||
// Type check
|
||||
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
|
||||
if (!allowedTypes.includes(file.type)) {
|
||||
throw new Error('Invalid file type')
|
||||
}
|
||||
|
||||
// Extension check
|
||||
const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif']
|
||||
const extension = file.name.toLowerCase().match(/\.[^.]+$/)?.[0]
|
||||
if (!extension || !allowedExtensions.includes(extension)) {
|
||||
throw new Error('Invalid file extension')
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] All user inputs validated with schemas
|
||||
- [ ] File uploads restricted (size, type, extension)
|
||||
- [ ] No direct use of user input in queries
|
||||
- [ ] Whitelist validation (not blacklist)
|
||||
- [ ] Error messages don't leak sensitive info
|
||||
|
||||
### 3. SQL Injection Prevention
|
||||
|
||||
#### ❌ NEVER Concatenate SQL
|
||||
```typescript
|
||||
// DANGEROUS - SQL Injection vulnerability
|
||||
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
||||
await db.query(query)
|
||||
```
|
||||
|
||||
#### ✅ ALWAYS Use Parameterized Queries
|
||||
```typescript
|
||||
// Safe - parameterized query
|
||||
const { data } = await supabase
|
||||
.from('users')
|
||||
.select('*')
|
||||
.eq('email', userEmail)
|
||||
|
||||
// Or with raw SQL
|
||||
await db.query(
|
||||
'SELECT * FROM users WHERE email = $1',
|
||||
[userEmail]
|
||||
)
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] All database queries use parameterized queries
|
||||
- [ ] No string concatenation in SQL
|
||||
- [ ] ORM/query builder used correctly
|
||||
- [ ] Supabase queries properly sanitized
|
||||
|
||||
### 4. Authentication & Authorization
|
||||
|
||||
#### JWT Token Handling
|
||||
```typescript
|
||||
// ❌ WRONG: localStorage (vulnerable to XSS)
|
||||
localStorage.setItem('token', token)
|
||||
|
||||
// ✅ CORRECT: httpOnly cookies
|
||||
res.setHeader('Set-Cookie',
|
||||
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
||||
```
|
||||
|
||||
#### Authorization Checks
|
||||
```typescript
|
||||
export async function deleteUser(userId: string, requesterId: string) {
|
||||
// ALWAYS verify authorization first
|
||||
const requester = await db.users.findUnique({
|
||||
where: { id: requesterId }
|
||||
})
|
||||
|
||||
if (requester.role !== 'admin') {
|
||||
return NextResponse.json(
|
||||
{ error: 'Unauthorized' },
|
||||
{ status: 403 }
|
||||
)
|
||||
}
|
||||
|
||||
// Proceed with deletion
|
||||
await db.users.delete({ where: { id: userId } })
|
||||
}
|
||||
```
|
||||
|
||||
#### Row Level Security (Supabase)
|
||||
```sql
|
||||
-- Enable RLS on all tables
|
||||
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Users can only view their own data
|
||||
CREATE POLICY "Users view own data"
|
||||
ON users FOR SELECT
|
||||
USING (auth.uid() = id);
|
||||
|
||||
-- Users can only update their own data
|
||||
CREATE POLICY "Users update own data"
|
||||
ON users FOR UPDATE
|
||||
USING (auth.uid() = id);
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] Tokens stored in httpOnly cookies (not localStorage)
|
||||
- [ ] Authorization checks before sensitive operations
|
||||
- [ ] Row Level Security enabled in Supabase
|
||||
- [ ] Role-based access control implemented
|
||||
- [ ] Session management secure
|
||||
|
||||
### 5. XSS Prevention
|
||||
|
||||
#### Sanitize HTML
|
||||
```typescript
|
||||
import DOMPurify from 'isomorphic-dompurify'
|
||||
|
||||
// ALWAYS sanitize user-provided HTML
|
||||
function renderUserContent(html: string) {
|
||||
const clean = DOMPurify.sanitize(html, {
|
||||
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
|
||||
ALLOWED_ATTR: []
|
||||
})
|
||||
return <div dangerouslySetInnerHTML={{ __html: clean }} />
|
||||
}
|
||||
```
|
||||
|
||||
#### Content Security Policy
|
||||
```typescript
|
||||
// next.config.js
|
||||
const securityHeaders = [
|
||||
{
|
||||
key: 'Content-Security-Policy',
|
||||
value: `
|
||||
default-src 'self';
|
||||
script-src 'self' 'unsafe-eval' 'unsafe-inline';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
img-src 'self' data: https:;
|
||||
font-src 'self';
|
||||
connect-src 'self' https://api.example.com;
|
||||
`.replace(/\s{2,}/g, ' ').trim()
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] User-provided HTML sanitized
|
||||
- [ ] CSP headers configured
|
||||
- [ ] No unvalidated dynamic content rendering
|
||||
- [ ] React's built-in XSS protection used
|
||||
|
||||
### 6. CSRF Protection
|
||||
|
||||
#### CSRF Tokens
|
||||
```typescript
|
||||
import { csrf } from '@/lib/csrf'
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const token = request.headers.get('X-CSRF-Token')
|
||||
|
||||
if (!csrf.verify(token)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Invalid CSRF token' },
|
||||
{ status: 403 }
|
||||
)
|
||||
}
|
||||
|
||||
// Process request
|
||||
}
|
||||
```
|
||||
|
||||
#### SameSite Cookies
|
||||
```typescript
|
||||
res.setHeader('Set-Cookie',
|
||||
`session=${sessionId}; HttpOnly; Secure; SameSite=Strict`)
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] CSRF tokens on state-changing operations
|
||||
- [ ] SameSite=Strict on all cookies
|
||||
- [ ] Double-submit cookie pattern implemented
|
||||
|
||||
### 7. Rate Limiting
|
||||
|
||||
#### API Rate Limiting
|
||||
```typescript
|
||||
import rateLimit from 'express-rate-limit'
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // 100 requests per window
|
||||
message: 'Too many requests'
|
||||
})
|
||||
|
||||
// Apply to routes
|
||||
app.use('/api/', limiter)
|
||||
```
|
||||
|
||||
#### Expensive Operations
|
||||
```typescript
|
||||
// Aggressive rate limiting for searches
|
||||
const searchLimiter = rateLimit({
|
||||
windowMs: 60 * 1000, // 1 minute
|
||||
max: 10, // 10 requests per minute
|
||||
message: 'Too many search requests'
|
||||
})
|
||||
|
||||
app.use('/api/search', searchLimiter)
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] Rate limiting on all API endpoints
|
||||
- [ ] Stricter limits on expensive operations
|
||||
- [ ] IP-based rate limiting
|
||||
- [ ] User-based rate limiting (authenticated)
|
||||
|
||||
### 8. Sensitive Data Exposure
|
||||
|
||||
#### Logging
|
||||
```typescript
|
||||
// ❌ WRONG: Logging sensitive data
|
||||
console.log('User login:', { email, password })
|
||||
console.log('Payment:', { cardNumber, cvv })
|
||||
|
||||
// ✅ CORRECT: Redact sensitive data
|
||||
console.log('User login:', { email, userId })
|
||||
console.log('Payment:', { last4: card.last4, userId })
|
||||
```
|
||||
|
||||
#### Error Messages
|
||||
```typescript
|
||||
// ❌ WRONG: Exposing internal details
|
||||
catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, stack: error.stack },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Generic error messages
|
||||
catch (error) {
|
||||
console.error('Internal error:', error)
|
||||
return NextResponse.json(
|
||||
{ error: 'An error occurred. Please try again.' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] No passwords, tokens, or secrets in logs
|
||||
- [ ] Error messages generic for users
|
||||
- [ ] Detailed errors only in server logs
|
||||
- [ ] No stack traces exposed to users
|
||||
|
||||
### 9. Blockchain Security (Solana)
|
||||
|
||||
#### Wallet Verification
|
||||
```typescript
|
||||
import { verify } from '@solana/web3.js'
|
||||
|
||||
async function verifyWalletOwnership(
|
||||
publicKey: string,
|
||||
signature: string,
|
||||
message: string
|
||||
) {
|
||||
try {
|
||||
const isValid = verify(
|
||||
Buffer.from(message),
|
||||
Buffer.from(signature, 'base64'),
|
||||
Buffer.from(publicKey, 'base64')
|
||||
)
|
||||
return isValid
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Transaction Verification
|
||||
```typescript
|
||||
async function verifyTransaction(transaction: Transaction) {
|
||||
// Verify recipient
|
||||
if (transaction.to !== expectedRecipient) {
|
||||
throw new Error('Invalid recipient')
|
||||
}
|
||||
|
||||
// Verify amount
|
||||
if (transaction.amount > maxAmount) {
|
||||
throw new Error('Amount exceeds limit')
|
||||
}
|
||||
|
||||
// Verify user has sufficient balance
|
||||
const balance = await getBalance(transaction.from)
|
||||
if (balance < transaction.amount) {
|
||||
throw new Error('Insufficient balance')
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] Wallet signatures verified
|
||||
- [ ] Transaction details validated
|
||||
- [ ] Balance checks before transactions
|
||||
- [ ] No blind transaction signing
|
||||
|
||||
### 10. Dependency Security
|
||||
|
||||
#### Regular Updates
|
||||
```bash
|
||||
# Check for vulnerabilities
|
||||
npm audit
|
||||
|
||||
# Fix automatically fixable issues
|
||||
npm audit fix
|
||||
|
||||
# Update dependencies
|
||||
npm update
|
||||
|
||||
# Check for outdated packages
|
||||
npm outdated
|
||||
```
|
||||
|
||||
#### Lock Files
|
||||
```bash
|
||||
# ALWAYS commit lock files
|
||||
git add package-lock.json
|
||||
|
||||
# Use in CI/CD for reproducible builds
|
||||
npm ci # Instead of npm install
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] Dependencies up to date
|
||||
- [ ] No known vulnerabilities (npm audit clean)
|
||||
- [ ] Lock files committed
|
||||
- [ ] Dependabot enabled on GitHub
|
||||
- [ ] Regular security updates
|
||||
|
||||
## Security Testing
|
||||
|
||||
### Automated Security Tests
|
||||
```typescript
|
||||
// Test authentication
|
||||
test('requires authentication', async () => {
|
||||
const response = await fetch('/api/protected')
|
||||
expect(response.status).toBe(401)
|
||||
})
|
||||
|
||||
// Test authorization
|
||||
test('requires admin role', async () => {
|
||||
const response = await fetch('/api/admin', {
|
||||
headers: { Authorization: `Bearer ${userToken}` }
|
||||
})
|
||||
expect(response.status).toBe(403)
|
||||
})
|
||||
|
||||
// Test input validation
|
||||
test('rejects invalid input', async () => {
|
||||
const response = await fetch('/api/users', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ email: 'not-an-email' })
|
||||
})
|
||||
expect(response.status).toBe(400)
|
||||
})
|
||||
|
||||
// Test rate limiting
|
||||
test('enforces rate limits', async () => {
|
||||
const requests = Array(101).fill(null).map(() =>
|
||||
fetch('/api/endpoint')
|
||||
)
|
||||
|
||||
const responses = await Promise.all(requests)
|
||||
const tooManyRequests = responses.filter(r => r.status === 429)
|
||||
|
||||
expect(tooManyRequests.length).toBeGreaterThan(0)
|
||||
})
|
||||
```
|
||||
|
||||
## Pre-Deployment Security Checklist
|
||||
|
||||
Before ANY production deployment:
|
||||
|
||||
- [ ] **Secrets**: No hardcoded secrets, all in env vars
|
||||
- [ ] **Input Validation**: All user inputs validated
|
||||
- [ ] **SQL Injection**: All queries parameterized
|
||||
- [ ] **XSS**: User content sanitized
|
||||
- [ ] **CSRF**: Protection enabled
|
||||
- [ ] **Authentication**: Proper token handling
|
||||
- [ ] **Authorization**: Role checks in place
|
||||
- [ ] **Rate Limiting**: Enabled on all endpoints
|
||||
- [ ] **HTTPS**: Enforced in production
|
||||
- [ ] **Security Headers**: CSP, X-Frame-Options configured
|
||||
- [ ] **Error Handling**: No sensitive data in errors
|
||||
- [ ] **Logging**: No sensitive data logged
|
||||
- [ ] **Dependencies**: Up to date, no vulnerabilities
|
||||
- [ ] **Row Level Security**: Enabled in Supabase
|
||||
- [ ] **CORS**: Properly configured
|
||||
- [ ] **File Uploads**: Validated (size, type)
|
||||
- [ ] **Wallet Signatures**: Verified (if blockchain)
|
||||
|
||||
## Resources
|
||||
|
||||
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
|
||||
- [Next.js Security](https://nextjs.org/docs/security)
|
||||
- [Supabase Security](https://supabase.com/docs/guides/auth)
|
||||
- [Web Security Academy](https://portswigger.net/web-security)
|
||||
|
||||
---
|
||||
|
||||
**Remember**: Security is not optional. One vulnerability can compromise the entire platform. When in doubt, err on the side of caution.
|
||||
10
skills/cc-skill-strategic-compact/SKILL.md
Normal file
10
skills/cc-skill-strategic-compact/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: cc-skill-strategic-compact
|
||||
description: Development skill from everything-claude-code
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# cc-skill-strategic-compact
|
||||
|
||||
Development skill skill.
|
||||
52
skills/cc-skill-strategic-compact/suggest-compact.sh
Executable file
52
skills/cc-skill-strategic-compact/suggest-compact.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
# Strategic Compact Suggester
|
||||
# Runs on PreToolUse or periodically to suggest manual compaction at logical intervals
|
||||
#
|
||||
# Why manual over auto-compact:
|
||||
# - Auto-compact happens at arbitrary points, often mid-task
|
||||
# - Strategic compacting preserves context through logical phases
|
||||
# - Compact after exploration, before execution
|
||||
# - Compact after completing a milestone, before starting next
|
||||
#
|
||||
# Hook config (in ~/.claude/settings.json):
|
||||
# {
|
||||
# "hooks": {
|
||||
# "PreToolUse": [{
|
||||
# "matcher": "Edit|Write",
|
||||
# "hooks": [{
|
||||
# "type": "command",
|
||||
# "command": "~/.claude/skills/strategic-compact/suggest-compact.sh"
|
||||
# }]
|
||||
# }]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# Criteria for suggesting compact:
|
||||
# - Session has been running for extended period
|
||||
# - Large number of tool calls made
|
||||
# - Transitioning from research/exploration to implementation
|
||||
# - Plan has been finalized
|
||||
|
||||
# Track tool call count (increment in a temp file)
|
||||
COUNTER_FILE="/tmp/claude-tool-count-$$"
|
||||
THRESHOLD=${COMPACT_THRESHOLD:-50}
|
||||
|
||||
# Initialize or increment counter
|
||||
if [ -f "$COUNTER_FILE" ]; then
|
||||
count=$(cat "$COUNTER_FILE")
|
||||
count=$((count + 1))
|
||||
echo "$count" > "$COUNTER_FILE"
|
||||
else
|
||||
echo "1" > "$COUNTER_FILE"
|
||||
count=1
|
||||
fi
|
||||
|
||||
# Suggest compact after threshold tool calls
|
||||
if [ "$count" -eq "$THRESHOLD" ]; then
|
||||
echo "[StrategicCompact] $THRESHOLD tool calls reached - consider /compact if transitioning phases" >&2
|
||||
fi
|
||||
|
||||
# Suggest at regular intervals after threshold
|
||||
if [ "$count" -gt "$THRESHOLD" ] && [ $((count % 25)) -eq 0 ]; then
|
||||
echo "[StrategicCompact] $count tool calls - good checkpoint for /compact if context is stale" >&2
|
||||
fi
|
||||
45
skills/remotion-best-practices/SKILL.md
Normal file
45
skills/remotion-best-practices/SKILL.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: remotion-best-practices
|
||||
description: Best practices for Remotion - Video creation in React
|
||||
author: remotion-dev
|
||||
version: "1.0"
|
||||
metadata:
|
||||
tags: remotion, video, react, animation, composition
|
||||
---
|
||||
|
||||
## When to use
|
||||
|
||||
Use this skills whenever you are dealing with Remotion code to obtain the domain-specific knowledge.
|
||||
|
||||
## How to use
|
||||
|
||||
Read individual rule files for detailed explanations and code examples:
|
||||
|
||||
- [rules/3d.md](rules/3d.md) - 3D content in Remotion using Three.js and React Three Fiber
|
||||
- [rules/animations.md](rules/animations.md) - Fundamental animation skills for Remotion
|
||||
- [rules/assets.md](rules/assets.md) - Importing images, videos, audio, and fonts into Remotion
|
||||
- [rules/audio.md](rules/audio.md) - Using audio and sound in Remotion - importing, trimming, volume, speed, pitch
|
||||
- [rules/calculate-metadata.md](rules/calculate-metadata.md) - Dynamically set composition duration, dimensions, and props
|
||||
- [rules/can-decode.md](rules/can-decode.md) - Check if a video can be decoded by the browser using Mediabunny
|
||||
- [rules/charts.md](rules/charts.md) - Chart and data visualization patterns for Remotion
|
||||
- [rules/compositions.md](rules/compositions.md) - Defining compositions, stills, folders, default props and dynamic metadata
|
||||
- [rules/display-captions.md](rules/display-captions.md) - Displaying captions in Remotion with TikTok-style pages and word highlighting
|
||||
- [rules/extract-frames.md](rules/extract-frames.md) - Extract frames from videos at specific timestamps using Mediabunny
|
||||
- [rules/fonts.md](rules/fonts.md) - Loading Google Fonts and local fonts in Remotion
|
||||
- [rules/get-audio-duration.md](rules/get-audio-duration.md) - Getting the duration of an audio file in seconds with Mediabunny
|
||||
- [rules/get-video-dimensions.md](rules/get-video-dimensions.md) - Getting the width and height of a video file with Mediabunny
|
||||
- [rules/get-video-duration.md](rules/get-video-duration.md) - Getting the duration of a video file in seconds with Mediabunny
|
||||
- [rules/gifs.md](rules/gifs.md) - Displaying GIFs synchronized with Remotion's timeline
|
||||
- [rules/images.md](rules/images.md) - Embedding images in Remotion using the Img component
|
||||
- [rules/import-srt-captions.md](rules/import-srt-captions.md) - Importing .srt subtitle files into Remotion using @remotion/captions
|
||||
- [rules/lottie.md](rules/lottie.md) - Embedding Lottie animations in Remotion
|
||||
- [rules/measuring-dom-nodes.md](rules/measuring-dom-nodes.md) - Measuring DOM element dimensions in Remotion
|
||||
- [rules/measuring-text.md](rules/measuring-text.md) - Measuring text dimensions, fitting text to containers, and checking overflow
|
||||
- [rules/sequencing.md](rules/sequencing.md) - Sequencing patterns for Remotion - delay, trim, limit duration of items
|
||||
- [rules/tailwind.md](rules/tailwind.md) - Using TailwindCSS in Remotion
|
||||
- [rules/text-animations.md](rules/text-animations.md) - Typography and text animation patterns for Remotion
|
||||
- [rules/timing.md](rules/timing.md) - Interpolation curves in Remotion - linear, easing, spring animations
|
||||
- [rules/transcribe-captions.md](rules/transcribe-captions.md) - Transcribing audio to generate captions in Remotion
|
||||
- [rules/transitions.md](rules/transitions.md) - Scene transition patterns for Remotion
|
||||
- [rules/trimming.md](rules/trimming.md) - Trimming patterns for Remotion - cut the beginning or end of animations
|
||||
- [rules/videos.md](rules/videos.md) - Embedding videos in Remotion - trimming, volume, speed, looping, pitch
|
||||
86
skills/remotion-best-practices/rules/3d.md
Normal file
86
skills/remotion-best-practices/rules/3d.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
name: 3d
|
||||
description: 3D content in Remotion using Three.js and React Three Fiber.
|
||||
metadata:
|
||||
tags: 3d, three, threejs
|
||||
---
|
||||
|
||||
# Using Three.js and React Three Fiber in Remotion
|
||||
|
||||
Follow React Three Fiber and Three.js best practices.
|
||||
Only the following Remotion-specific rules need to be followed:
|
||||
|
||||
## Prerequisites
|
||||
|
||||
First, the `@remotion/three` package needs to be installed.
|
||||
If it is not, use the following command:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/three # If project uses npm
|
||||
bunx remotion add @remotion/three # If project uses bun
|
||||
yarn remotion add @remotion/three # If project uses yarn
|
||||
pnpm exec remotion add @remotion/three # If project uses pnpm
|
||||
```
|
||||
|
||||
## Using ThreeCanvas
|
||||
|
||||
You MUST wrap 3D content in `<ThreeCanvas>` and include proper lighting.
|
||||
`<ThreeCanvas>` MUST have a `width` and `height` prop.
|
||||
|
||||
```tsx
|
||||
import { ThreeCanvas } from "@remotion/three";
|
||||
import { useVideoConfig } from "remotion";
|
||||
|
||||
const { width, height } = useVideoConfig();
|
||||
|
||||
<ThreeCanvas width={width} height={height}>
|
||||
<ambientLight intensity={0.4} />
|
||||
<directionalLight position={[5, 5, 5]} intensity={0.8} />
|
||||
<mesh>
|
||||
<sphereGeometry args={[1, 32, 32]} />
|
||||
<meshStandardMaterial color="red" />
|
||||
</mesh>
|
||||
</ThreeCanvas>
|
||||
```
|
||||
|
||||
## No animations not driven by `useCurrentFrame()`
|
||||
|
||||
Shaders, models etc MUST NOT animate by themselves.
|
||||
No animations are allowed unless they are driven by `useCurrentFrame()`.
|
||||
Otherwise, it will cause flickering during rendering.
|
||||
|
||||
Using `useFrame()` from `@react-three/fiber` is forbidden.
|
||||
|
||||
## Animate using `useCurrentFrame()`
|
||||
|
||||
Use `useCurrentFrame()` to perform animations.
|
||||
|
||||
```tsx
|
||||
const frame = useCurrentFrame();
|
||||
const rotationY = frame * 0.02;
|
||||
|
||||
<mesh rotation={[0, rotationY, 0]}>
|
||||
<boxGeometry args={[2, 2, 2]} />
|
||||
<meshStandardMaterial color="#4a9eff" />
|
||||
</mesh>
|
||||
```
|
||||
|
||||
## Using `<Sequence>` inside `<ThreeCanvas>`
|
||||
|
||||
The `layout` prop of any `<Sequence>` inside a `<ThreeCanvas>` must be set to `none`.
|
||||
|
||||
```tsx
|
||||
import { Sequence } from "remotion";
|
||||
import { ThreeCanvas } from "@remotion/three";
|
||||
|
||||
const { width, height } = useVideoConfig();
|
||||
|
||||
<ThreeCanvas width={width} height={height}>
|
||||
<Sequence layout="none">
|
||||
<mesh>
|
||||
<boxGeometry args={[2, 2, 2]} />
|
||||
<meshStandardMaterial color="#4a9eff" />
|
||||
</mesh>
|
||||
</Sequence>
|
||||
</ThreeCanvas>
|
||||
```
|
||||
29
skills/remotion-best-practices/rules/animations.md
Normal file
29
skills/remotion-best-practices/rules/animations.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: animations
|
||||
description: Fundamental animation skills for Remotion
|
||||
metadata:
|
||||
tags: animations, transitions, frames, useCurrentFrame
|
||||
---
|
||||
|
||||
All animations MUST be driven by the `useCurrentFrame()` hook.
|
||||
Write animations in seconds and multiply them by the `fps` value from `useVideoConfig()`.
|
||||
|
||||
```tsx
|
||||
import { useCurrentFrame } from "remotion";
|
||||
|
||||
export const FadeIn = () => {
|
||||
const frame = useCurrentFrame();
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
const opacity = interpolate(frame, [0, 2 * fps], [0, 1], {
|
||||
extrapolateRight: 'clamp',
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{ opacity }}>Hello World!</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
CSS transitions or animations are FORBIDDEN - they will not render correctly.
|
||||
Tailwind animation class names are FORBIDDEN - they will not render correctly.
|
||||
78
skills/remotion-best-practices/rules/assets.md
Normal file
78
skills/remotion-best-practices/rules/assets.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
name: assets
|
||||
description: Importing images, videos, audio, and fonts into Remotion
|
||||
metadata:
|
||||
tags: assets, staticFile, images, fonts, public
|
||||
---
|
||||
|
||||
# Importing assets in Remotion
|
||||
|
||||
## The public folder
|
||||
|
||||
Place assets in the `public/` folder at your project root.
|
||||
|
||||
## Using staticFile()
|
||||
|
||||
You MUST use `staticFile()` to reference files from the `public/` folder:
|
||||
|
||||
```tsx
|
||||
import {Img, staticFile} from 'remotion';
|
||||
|
||||
export const MyComposition = () => {
|
||||
return <Img src={staticFile('logo.png')} />;
|
||||
};
|
||||
```
|
||||
|
||||
The function returns an encoded URL that works correctly when deploying to subdirectories.
|
||||
|
||||
## Using with components
|
||||
|
||||
**Images:**
|
||||
|
||||
```tsx
|
||||
import {Img, staticFile} from 'remotion';
|
||||
|
||||
<Img src={staticFile('photo.png')} />;
|
||||
```
|
||||
|
||||
**Videos:**
|
||||
|
||||
```tsx
|
||||
import {Video} from '@remotion/media';
|
||||
import {staticFile} from 'remotion';
|
||||
|
||||
<Video src={staticFile('clip.mp4')} />;
|
||||
```
|
||||
|
||||
**Audio:**
|
||||
|
||||
```tsx
|
||||
import {Audio} from '@remotion/media';
|
||||
import {staticFile} from 'remotion';
|
||||
|
||||
<Audio src={staticFile('music.mp3')} />;
|
||||
```
|
||||
|
||||
**Fonts:**
|
||||
|
||||
```tsx
|
||||
import {staticFile} from 'remotion';
|
||||
|
||||
const fontFamily = new FontFace('MyFont', `url(${staticFile('font.woff2')})`);
|
||||
await fontFamily.load();
|
||||
document.fonts.add(fontFamily);
|
||||
```
|
||||
|
||||
## Remote URLs
|
||||
|
||||
Remote URLs can be used directly without `staticFile()`:
|
||||
|
||||
```tsx
|
||||
<Img src="https://example.com/image.png" />
|
||||
<Video src="https://remotion.media/video.mp4" />
|
||||
```
|
||||
|
||||
## Important notes
|
||||
|
||||
- Remotion components (`<Img>`, `<Video>`, `<Audio>`) ensure assets are fully loaded before rendering
|
||||
- Special characters in filenames (`#`, `?`, `&`) are automatically encoded
|
||||
173
skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx
Normal file
173
skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx
Normal file
@@ -0,0 +1,173 @@
|
||||
import {loadFont} from '@remotion/google-fonts/Inter';
|
||||
import {AbsoluteFill, spring, useCurrentFrame, useVideoConfig} from 'remotion';
|
||||
|
||||
const {fontFamily} = loadFont();
|
||||
|
||||
const COLOR_BAR = '#D4AF37';
|
||||
const COLOR_TEXT = '#ffffff';
|
||||
const COLOR_MUTED = '#888888';
|
||||
const COLOR_BG = '#0a0a0a';
|
||||
const COLOR_AXIS = '#333333';
|
||||
|
||||
// Ideal composition size: 1280x720
|
||||
|
||||
const Title: React.FC<{children: React.ReactNode}> = ({children}) => (
|
||||
<div style={{textAlign: 'center', marginBottom: 40}}>
|
||||
<div style={{color: COLOR_TEXT, fontSize: 48, fontWeight: 600}}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const YAxis: React.FC<{steps: number[]; height: number}> = ({
|
||||
steps,
|
||||
height,
|
||||
}) => (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
height,
|
||||
paddingRight: 16,
|
||||
}}
|
||||
>
|
||||
{steps
|
||||
.slice()
|
||||
.reverse()
|
||||
.map((step) => (
|
||||
<div
|
||||
key={step}
|
||||
style={{
|
||||
color: COLOR_MUTED,
|
||||
fontSize: 20,
|
||||
textAlign: 'right',
|
||||
}}
|
||||
>
|
||||
{step.toLocaleString()}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
const Bar: React.FC<{
|
||||
height: number;
|
||||
progress: number;
|
||||
}> = ({height, progress}) => (
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'flex-end',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height,
|
||||
backgroundColor: COLOR_BAR,
|
||||
borderRadius: '8px 8px 0 0',
|
||||
opacity: progress,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
const XAxis: React.FC<{
|
||||
children: React.ReactNode;
|
||||
labels: string[];
|
||||
height: number;
|
||||
}> = ({children, labels, height}) => (
|
||||
<div style={{flex: 1, display: 'flex', flexDirection: 'column'}}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
gap: 16,
|
||||
height,
|
||||
borderLeft: `2px solid ${COLOR_AXIS}`,
|
||||
borderBottom: `2px solid ${COLOR_AXIS}`,
|
||||
paddingLeft: 16,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
gap: 16,
|
||||
paddingLeft: 16,
|
||||
marginTop: 12,
|
||||
}}
|
||||
>
|
||||
{labels.map((label) => (
|
||||
<div
|
||||
key={label}
|
||||
style={{
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
color: COLOR_MUTED,
|
||||
fontSize: 20,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const MyAnimation = () => {
|
||||
const frame = useCurrentFrame();
|
||||
const {fps, height} = useVideoConfig();
|
||||
|
||||
const data = [
|
||||
{month: 'Jan', price: 2039},
|
||||
{month: 'Mar', price: 2160},
|
||||
{month: 'May', price: 2327},
|
||||
{month: 'Jul', price: 2426},
|
||||
{month: 'Sep', price: 2634},
|
||||
{month: 'Nov', price: 2672},
|
||||
];
|
||||
|
||||
const minPrice = 2000;
|
||||
const maxPrice = 2800;
|
||||
const priceRange = maxPrice - minPrice;
|
||||
const chartHeight = height - 280;
|
||||
const yAxisSteps = [2000, 2400, 2800];
|
||||
|
||||
return (
|
||||
<AbsoluteFill
|
||||
style={{
|
||||
backgroundColor: COLOR_BG,
|
||||
padding: 60,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
fontFamily,
|
||||
}}
|
||||
>
|
||||
<Title>Gold Price 2024</Title>
|
||||
|
||||
<div style={{display: 'flex', flex: 1}}>
|
||||
<YAxis steps={yAxisSteps} height={chartHeight} />
|
||||
<XAxis height={chartHeight} labels={data.map((d) => d.month)}>
|
||||
{data.map((item, i) => {
|
||||
const progress = spring({
|
||||
frame: frame - i * 5 - 10,
|
||||
fps,
|
||||
config: {damping: 18, stiffness: 80},
|
||||
});
|
||||
|
||||
const barHeight =
|
||||
((item.price - minPrice) / priceRange) * chartHeight * progress;
|
||||
|
||||
return (
|
||||
<Bar key={item.month} height={barHeight} progress={progress} />
|
||||
);
|
||||
})}
|
||||
</XAxis>
|
||||
</div>
|
||||
</AbsoluteFill>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
import {
|
||||
AbsoluteFill,
|
||||
interpolate,
|
||||
useCurrentFrame,
|
||||
useVideoConfig,
|
||||
} from 'remotion';
|
||||
|
||||
const COLOR_BG = '#ffffff';
|
||||
const COLOR_TEXT = '#000000';
|
||||
const FULL_TEXT = 'From prompt to motion graphics. This is Remotion.';
|
||||
const PAUSE_AFTER = 'From prompt to motion graphics.';
|
||||
const FONT_SIZE = 72;
|
||||
const FONT_WEIGHT = 700;
|
||||
const CHAR_FRAMES = 2;
|
||||
const CURSOR_BLINK_FRAMES = 16;
|
||||
const PAUSE_SECONDS = 1;
|
||||
|
||||
// Ideal composition size: 1280x720
|
||||
|
||||
const getTypedText = ({
|
||||
frame,
|
||||
fullText,
|
||||
pauseAfter,
|
||||
charFrames,
|
||||
pauseFrames,
|
||||
}: {
|
||||
frame: number;
|
||||
fullText: string;
|
||||
pauseAfter: string;
|
||||
charFrames: number;
|
||||
pauseFrames: number;
|
||||
}): string => {
|
||||
const pauseIndex = fullText.indexOf(pauseAfter);
|
||||
const preLen =
|
||||
pauseIndex >= 0 ? pauseIndex + pauseAfter.length : fullText.length;
|
||||
|
||||
let typedChars = 0;
|
||||
if (frame < preLen * charFrames) {
|
||||
typedChars = Math.floor(frame / charFrames);
|
||||
} else if (frame < preLen * charFrames + pauseFrames) {
|
||||
typedChars = preLen;
|
||||
} else {
|
||||
const postPhase = frame - preLen * charFrames - pauseFrames;
|
||||
typedChars = Math.min(
|
||||
fullText.length,
|
||||
preLen + Math.floor(postPhase / charFrames),
|
||||
);
|
||||
}
|
||||
return fullText.slice(0, typedChars);
|
||||
};
|
||||
|
||||
const Cursor: React.FC<{
|
||||
frame: number;
|
||||
blinkFrames: number;
|
||||
symbol?: string;
|
||||
}> = ({frame, blinkFrames, symbol = '\u258C'}) => {
|
||||
const opacity = interpolate(
|
||||
frame % blinkFrames,
|
||||
[0, blinkFrames / 2, blinkFrames],
|
||||
[1, 0, 1],
|
||||
{extrapolateLeft: 'clamp', extrapolateRight: 'clamp'},
|
||||
);
|
||||
|
||||
return <span style={{opacity}}>{symbol}</span>;
|
||||
};
|
||||
|
||||
export const MyAnimation = () => {
|
||||
const frame = useCurrentFrame();
|
||||
const {fps} = useVideoConfig();
|
||||
|
||||
const pauseFrames = Math.round(fps * PAUSE_SECONDS);
|
||||
|
||||
const typedText = getTypedText({
|
||||
frame,
|
||||
fullText: FULL_TEXT,
|
||||
pauseAfter: PAUSE_AFTER,
|
||||
charFrames: CHAR_FRAMES,
|
||||
pauseFrames,
|
||||
});
|
||||
|
||||
return (
|
||||
<AbsoluteFill
|
||||
style={{
|
||||
backgroundColor: COLOR_BG,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
color: COLOR_TEXT,
|
||||
fontSize: FONT_SIZE,
|
||||
fontWeight: FONT_WEIGHT,
|
||||
fontFamily: 'sans-serif',
|
||||
}}
|
||||
>
|
||||
<span>{typedText}</span>
|
||||
<Cursor frame={frame} blinkFrames={CURSOR_BLINK_FRAMES} />
|
||||
</div>
|
||||
</AbsoluteFill>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
import {loadFont} from '@remotion/google-fonts/Inter';
|
||||
import React from 'react';
|
||||
import {
|
||||
AbsoluteFill,
|
||||
spring,
|
||||
useCurrentFrame,
|
||||
useVideoConfig,
|
||||
} from 'remotion';
|
||||
|
||||
/*
|
||||
* Highlight a word in a sentence with a spring-animated wipe effect.
|
||||
*/
|
||||
|
||||
// Ideal composition size: 1280x720
|
||||
|
||||
const COLOR_BG = '#ffffff';
|
||||
const COLOR_TEXT = '#000000';
|
||||
const COLOR_HIGHLIGHT = '#A7C7E7';
|
||||
const FULL_TEXT = 'This is Remotion.';
|
||||
const HIGHLIGHT_WORD = 'Remotion';
|
||||
const FONT_SIZE = 72;
|
||||
const FONT_WEIGHT = 700;
|
||||
const HIGHLIGHT_START_FRAME = 30;
|
||||
const HIGHLIGHT_WIPE_DURATION = 18;
|
||||
|
||||
const {fontFamily} = loadFont();
|
||||
|
||||
const Highlight: React.FC<{
|
||||
word: string;
|
||||
color: string;
|
||||
delay: number;
|
||||
durationInFrames: number;
|
||||
}> = ({word, color, delay, durationInFrames}) => {
|
||||
const frame = useCurrentFrame();
|
||||
const {fps} = useVideoConfig();
|
||||
|
||||
const highlightProgress = spring({
|
||||
fps,
|
||||
frame,
|
||||
config: {damping: 200},
|
||||
delay,
|
||||
durationInFrames,
|
||||
});
|
||||
const scaleX = Math.max(0, Math.min(1, highlightProgress));
|
||||
|
||||
return (
|
||||
<span style={{position: 'relative', display: 'inline-block'}}>
|
||||
<span
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: '50%',
|
||||
height: '1.05em',
|
||||
transform: `translateY(-50%) scaleX(${scaleX})`,
|
||||
transformOrigin: 'left center',
|
||||
backgroundColor: color,
|
||||
borderRadius: '0.18em',
|
||||
zIndex: 0,
|
||||
}}
|
||||
/>
|
||||
<span style={{position: 'relative', zIndex: 1}}>{word}</span>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export const MyAnimation = () => {
|
||||
const highlightIndex = FULL_TEXT.indexOf(HIGHLIGHT_WORD);
|
||||
const hasHighlight = highlightIndex >= 0;
|
||||
const preText = hasHighlight ? FULL_TEXT.slice(0, highlightIndex) : FULL_TEXT;
|
||||
const postText = hasHighlight
|
||||
? FULL_TEXT.slice(highlightIndex + HIGHLIGHT_WORD.length)
|
||||
: '';
|
||||
|
||||
return (
|
||||
<AbsoluteFill
|
||||
style={{
|
||||
backgroundColor: COLOR_BG,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
fontFamily,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
color: COLOR_TEXT,
|
||||
fontSize: FONT_SIZE,
|
||||
fontWeight: FONT_WEIGHT,
|
||||
}}
|
||||
>
|
||||
{hasHighlight ? (
|
||||
<>
|
||||
<span>{preText}</span>
|
||||
<Highlight
|
||||
word={HIGHLIGHT_WORD}
|
||||
color={COLOR_HIGHLIGHT}
|
||||
delay={HIGHLIGHT_START_FRAME}
|
||||
durationInFrames={HIGHLIGHT_WIPE_DURATION}
|
||||
/>
|
||||
<span>{postText}</span>
|
||||
</>
|
||||
) : (
|
||||
<span>{FULL_TEXT}</span>
|
||||
)}
|
||||
</div>
|
||||
</AbsoluteFill>
|
||||
);
|
||||
};
|
||||
172
skills/remotion-best-practices/rules/audio.md
Normal file
172
skills/remotion-best-practices/rules/audio.md
Normal file
@@ -0,0 +1,172 @@
|
||||
---
|
||||
name: audio
|
||||
description: Using audio and sound in Remotion - importing, trimming, volume, speed, pitch
|
||||
metadata:
|
||||
tags: audio, media, trim, volume, speed, loop, pitch, mute, sound, sfx
|
||||
---
|
||||
|
||||
# Using audio in Remotion
|
||||
|
||||
## Prerequisites
|
||||
|
||||
First, the @remotion/media package needs to be installed.
|
||||
If it is not installed, use the following command:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/media # If project uses npm
|
||||
bunx remotion add @remotion/media # If project uses bun
|
||||
yarn remotion add @remotion/media # If project uses yarn
|
||||
pnpm exec remotion add @remotion/media # If project uses pnpm
|
||||
```
|
||||
|
||||
## Importing Audio
|
||||
|
||||
Use `<Audio>` from `@remotion/media` to add audio to your composition.
|
||||
|
||||
```tsx
|
||||
import { Audio } from "@remotion/media";
|
||||
import { staticFile } from "remotion";
|
||||
|
||||
export const MyComposition = () => {
|
||||
return <Audio src={staticFile("audio.mp3")} />;
|
||||
};
|
||||
```
|
||||
|
||||
Remote URLs are also supported:
|
||||
|
||||
```tsx
|
||||
<Audio src="https://remotion.media/audio.mp3" />
|
||||
```
|
||||
|
||||
By default, audio plays from the start, at full volume and full length.
|
||||
Multiple audio tracks can be layered by adding multiple `<Audio>` components.
|
||||
|
||||
## Trimming
|
||||
|
||||
Use `trimBefore` and `trimAfter` to remove portions of the audio. Values are in frames.
|
||||
|
||||
```tsx
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
return (
|
||||
<Audio
|
||||
src={staticFile("audio.mp3")}
|
||||
trimBefore={2 * fps} // Skip the first 2 seconds
|
||||
trimAfter={10 * fps} // End at the 10 second mark
|
||||
/>
|
||||
);
|
||||
```
|
||||
|
||||
The audio still starts playing at the beginning of the composition - only the specified portion is played.
|
||||
|
||||
## Delaying
|
||||
|
||||
Wrap the audio in a `<Sequence>` to delay when it starts:
|
||||
|
||||
```tsx
|
||||
import { Sequence, staticFile } from "remotion";
|
||||
import { Audio } from "@remotion/media";
|
||||
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
return (
|
||||
<Sequence from={1 * fps}>
|
||||
<Audio src={staticFile("audio.mp3")} />
|
||||
</Sequence>
|
||||
);
|
||||
```
|
||||
|
||||
The audio will start playing after 1 second.
|
||||
|
||||
## Volume
|
||||
|
||||
Set a static volume (0 to 1):
|
||||
|
||||
```tsx
|
||||
<Audio src={staticFile("audio.mp3")} volume={0.5} />
|
||||
```
|
||||
|
||||
Or use a callback for dynamic volume based on the current frame:
|
||||
|
||||
```tsx
|
||||
import { interpolate } from "remotion";
|
||||
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
return (
|
||||
<Audio
|
||||
src={staticFile("audio.mp3")}
|
||||
volume={(f) =>
|
||||
interpolate(f, [0, 1 * fps], [0, 1], { extrapolateRight: "clamp" })
|
||||
}
|
||||
/>
|
||||
);
|
||||
```
|
||||
|
||||
The value of `f` starts at 0 when the audio begins to play, not the composition frame.
|
||||
|
||||
## Muting
|
||||
|
||||
Use `muted` to silence the audio. It can be set dynamically:
|
||||
|
||||
```tsx
|
||||
const frame = useCurrentFrame();
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
return (
|
||||
<Audio
|
||||
src={staticFile("audio.mp3")}
|
||||
muted={frame >= 2 * fps && frame <= 4 * fps} // Mute between 2s and 4s
|
||||
/>
|
||||
);
|
||||
```
|
||||
|
||||
## Speed
|
||||
|
||||
Use `playbackRate` to change the playback speed:
|
||||
|
||||
```tsx
|
||||
<Audio src={staticFile("audio.mp3")} playbackRate={2} /> {/* 2x speed */}
|
||||
<Audio src={staticFile("audio.mp3")} playbackRate={0.5} /> {/* Half speed */}
|
||||
```
|
||||
|
||||
Reverse playback is not supported.
|
||||
|
||||
## Looping
|
||||
|
||||
Use `loop` to loop the audio indefinitely:
|
||||
|
||||
```tsx
|
||||
<Audio src={staticFile("audio.mp3")} loop />
|
||||
```
|
||||
|
||||
Use `loopVolumeCurveBehavior` to control how the frame count behaves when looping:
|
||||
|
||||
- `"repeat"`: Frame count resets to 0 each loop (default)
|
||||
- `"extend"`: Frame count continues incrementing
|
||||
|
||||
```tsx
|
||||
<Audio
|
||||
src={staticFile("audio.mp3")}
|
||||
loop
|
||||
loopVolumeCurveBehavior="extend"
|
||||
volume={(f) => interpolate(f, [0, 300], [1, 0])} // Fade out over multiple loops
|
||||
/>
|
||||
```
|
||||
|
||||
## Pitch
|
||||
|
||||
Use `toneFrequency` to adjust the pitch without affecting speed. Values range from 0.01 to 2:
|
||||
|
||||
```tsx
|
||||
<Audio
|
||||
src={staticFile("audio.mp3")}
|
||||
toneFrequency={1.5} // Higher pitch
|
||||
/>
|
||||
<Audio
|
||||
src={staticFile("audio.mp3")}
|
||||
toneFrequency={0.8} // Lower pitch
|
||||
/>
|
||||
```
|
||||
|
||||
Pitch shifting only works during server-side rendering, not in the Remotion Studio preview or in the `<Player />`.
|
||||
104
skills/remotion-best-practices/rules/calculate-metadata.md
Normal file
104
skills/remotion-best-practices/rules/calculate-metadata.md
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
name: calculate-metadata
|
||||
description: Dynamically set composition duration, dimensions, and props
|
||||
metadata:
|
||||
tags: calculateMetadata, duration, dimensions, props, dynamic
|
||||
---
|
||||
|
||||
# Using calculateMetadata
|
||||
|
||||
Use `calculateMetadata` on a `<Composition>` to dynamically set duration, dimensions, and transform props before rendering.
|
||||
|
||||
```tsx
|
||||
<Composition id="MyComp" component={MyComponent} durationInFrames={300} fps={30} width={1920} height={1080} defaultProps={{videoSrc: 'https://remotion.media/video.mp4'}} calculateMetadata={calculateMetadata} />
|
||||
```
|
||||
|
||||
## Setting duration based on a video
|
||||
|
||||
Use the `getMediaMetadata()` function from the mediabunny/metadata skill to get the video duration:
|
||||
|
||||
```tsx
|
||||
import {CalculateMetadataFunction} from 'remotion';
|
||||
import {getMediaMetadata} from '../get-media-metadata';
|
||||
|
||||
const calculateMetadata: CalculateMetadataFunction<Props> = async ({props}) => {
|
||||
const {durationInSeconds} = await getMediaMetadata(props.videoSrc);
|
||||
|
||||
return {
|
||||
durationInFrames: Math.ceil(durationInSeconds * 30),
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Matching dimensions of a video
|
||||
|
||||
```tsx
|
||||
const calculateMetadata: CalculateMetadataFunction<Props> = async ({props}) => {
|
||||
const {durationInSeconds, dimensions} = await getMediaMetadata(props.videoSrc);
|
||||
|
||||
return {
|
||||
durationInFrames: Math.ceil(durationInSeconds * 30),
|
||||
width: dimensions?.width ?? 1920,
|
||||
height: dimensions?.height ?? 1080,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Setting duration based on multiple videos
|
||||
|
||||
```tsx
|
||||
const calculateMetadata: CalculateMetadataFunction<Props> = async ({props}) => {
|
||||
const metadataPromises = props.videos.map((video) => getMediaMetadata(video.src));
|
||||
const allMetadata = await Promise.all(metadataPromises);
|
||||
|
||||
const totalDuration = allMetadata.reduce((sum, meta) => sum + meta.durationInSeconds, 0);
|
||||
|
||||
return {
|
||||
durationInFrames: Math.ceil(totalDuration * 30),
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Setting a default outName
|
||||
|
||||
Set the default output filename based on props:
|
||||
|
||||
```tsx
|
||||
const calculateMetadata: CalculateMetadataFunction<Props> = async ({props}) => {
|
||||
return {
|
||||
defaultOutName: `video-${props.id}.mp4`,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Transforming props
|
||||
|
||||
Fetch data or transform props before rendering:
|
||||
|
||||
```tsx
|
||||
const calculateMetadata: CalculateMetadataFunction<Props> = async ({props, abortSignal}) => {
|
||||
const response = await fetch(props.dataUrl, {signal: abortSignal});
|
||||
const data = await response.json();
|
||||
|
||||
return {
|
||||
props: {
|
||||
...props,
|
||||
fetchedData: data,
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
The `abortSignal` cancels stale requests when props change in the Studio.
|
||||
|
||||
## Return value
|
||||
|
||||
All fields are optional. Returned values override the `<Composition>` props:
|
||||
|
||||
- `durationInFrames`: Number of frames
|
||||
- `width`: Composition width in pixels
|
||||
- `height`: Composition height in pixels
|
||||
- `fps`: Frames per second
|
||||
- `props`: Transformed props passed to the component
|
||||
- `defaultOutName`: Default output filename
|
||||
- `defaultCodec`: Default codec for rendering
|
||||
75
skills/remotion-best-practices/rules/can-decode.md
Normal file
75
skills/remotion-best-practices/rules/can-decode.md
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
name: can-decode
|
||||
description: Check if a video can be decoded by the browser using Mediabunny
|
||||
metadata:
|
||||
tags: decode, validation, video, audio, compatibility, browser
|
||||
---
|
||||
|
||||
# Checking if a video can be decoded
|
||||
|
||||
Use Mediabunny to check if a video can be decoded by the browser before attempting to play it.
|
||||
|
||||
## The `canDecode()` function
|
||||
|
||||
This function can be copy-pasted into any project.
|
||||
|
||||
```tsx
|
||||
import { Input, ALL_FORMATS, UrlSource } from "mediabunny";
|
||||
|
||||
export const canDecode = async (src: string) => {
|
||||
const input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new UrlSource(src, {
|
||||
getRetryDelay: () => null,
|
||||
}),
|
||||
});
|
||||
|
||||
try {
|
||||
await input.getFormat();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
if (videoTrack && !(await videoTrack.canDecode())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const audioTrack = await input.getPrimaryAudioTrack();
|
||||
if (audioTrack && !(await audioTrack.canDecode())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
const src = "https://remotion.media/video.mp4";
|
||||
const isDecodable = await canDecode(src);
|
||||
|
||||
if (isDecodable) {
|
||||
console.log("Video can be decoded");
|
||||
} else {
|
||||
console.log("Video cannot be decoded by this browser");
|
||||
}
|
||||
```
|
||||
|
||||
## Using with Blob
|
||||
|
||||
For file uploads or drag-and-drop, use `BlobSource`:
|
||||
|
||||
```tsx
|
||||
import { Input, ALL_FORMATS, BlobSource } from "mediabunny";
|
||||
|
||||
export const canDecodeBlob = async (blob: Blob) => {
|
||||
const input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new BlobSource(blob),
|
||||
});
|
||||
|
||||
// Same validation logic as above
|
||||
};
|
||||
```
|
||||
58
skills/remotion-best-practices/rules/charts.md
Normal file
58
skills/remotion-best-practices/rules/charts.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: charts
|
||||
description: Chart and data visualization patterns for Remotion. Use when creating bar charts, pie charts, histograms, progress bars, or any data-driven animations.
|
||||
metadata:
|
||||
tags: charts, data, visualization, bar-chart, pie-chart, graphs
|
||||
---
|
||||
|
||||
# Charts in Remotion
|
||||
|
||||
You can create bar charts in Remotion by using regular React code - HTML and SVG is allowed, as well as D3.js.
|
||||
|
||||
## No animations not powered by `useCurrentFrame()`
|
||||
|
||||
Disable all animations by third party libraries.
|
||||
They will cause flickering during rendering.
|
||||
Instead, drive all animations from `useCurrentFrame()`.
|
||||
|
||||
## Bar Chart Animations
|
||||
|
||||
See [Bar Chart Example](assets/charts/bar-chart.tsx) for a basic example implmentation.
|
||||
|
||||
### Staggered Bars
|
||||
|
||||
You can animate the height of the bars and stagger them like this:
|
||||
|
||||
```tsx
|
||||
const STAGGER_DELAY = 5;
|
||||
const frame = useCurrentFrame();
|
||||
const {fps} = useVideoConfig();
|
||||
|
||||
const bars = data.map((item, i) => {
|
||||
const delay = i * STAGGER_DELAY;
|
||||
const height = spring({
|
||||
frame,
|
||||
fps,
|
||||
delay,
|
||||
config: {damping: 200},
|
||||
});
|
||||
return <div style={{height: height * item.value}} />;
|
||||
});
|
||||
```
|
||||
|
||||
## Pie Chart Animation
|
||||
|
||||
Animate segments using stroke-dashoffset, starting from 12 o'clock.
|
||||
|
||||
```tsx
|
||||
const frame = useCurrentFrame();
|
||||
const {fps} = useVideoConfig();
|
||||
|
||||
const progress = interpolate(frame, [0, 100], [0, 1]);
|
||||
|
||||
const circumference = 2 * Math.PI * radius;
|
||||
const segmentLength = (value / total) * circumference;
|
||||
const offset = interpolate(progress, [0, 1], [segmentLength, 0]);
|
||||
|
||||
<circle r={radius} cx={center} cy={center} fill="none" stroke={color} strokeWidth={strokeWidth} strokeDasharray={`${segmentLength} ${circumference}`} strokeDashoffset={offset} transform={`rotate(-90 ${center} ${center})`} />;
|
||||
```
|
||||
146
skills/remotion-best-practices/rules/compositions.md
Normal file
146
skills/remotion-best-practices/rules/compositions.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
name: compositions
|
||||
description: Defining compositions, stills, folders, default props and dynamic metadata
|
||||
metadata:
|
||||
tags: composition, still, folder, props, metadata
|
||||
---
|
||||
|
||||
A `<Composition>` defines the component, width, height, fps and duration of a renderable video.
|
||||
|
||||
It normally is placed in the `src/Root.tsx` file.
|
||||
|
||||
```tsx
|
||||
import { Composition } from "remotion";
|
||||
import { MyComposition } from "./MyComposition";
|
||||
|
||||
export const RemotionRoot = () => {
|
||||
return (
|
||||
<Composition
|
||||
id="MyComposition"
|
||||
component={MyComposition}
|
||||
durationInFrames={100}
|
||||
fps={30}
|
||||
width={1080}
|
||||
height={1080}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Default Props
|
||||
|
||||
Pass `defaultProps` to provide initial values for your component.
|
||||
Values must be JSON-serializable (`Date`, `Map`, `Set`, and `staticFile()` are supported).
|
||||
|
||||
```tsx
|
||||
import { Composition } from "remotion";
|
||||
import { MyComposition, MyCompositionProps } from "./MyComposition";
|
||||
|
||||
export const RemotionRoot = () => {
|
||||
return (
|
||||
<Composition
|
||||
id="MyComposition"
|
||||
component={MyComposition}
|
||||
durationInFrames={100}
|
||||
fps={30}
|
||||
width={1080}
|
||||
height={1080}
|
||||
defaultProps={{
|
||||
title: "Hello World",
|
||||
color: "#ff0000",
|
||||
} satisfies MyCompositionProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
Use `type` declarations for props rather than `interface` to ensure `defaultProps` type safety.
|
||||
|
||||
## Folders
|
||||
|
||||
Use `<Folder>` to organize compositions in the sidebar.
|
||||
Folder names can only contain letters, numbers, and hyphens.
|
||||
|
||||
```tsx
|
||||
import { Composition, Folder } from "remotion";
|
||||
|
||||
export const RemotionRoot = () => {
|
||||
return (
|
||||
<>
|
||||
<Folder name="Marketing">
|
||||
<Composition id="Promo" /* ... */ />
|
||||
<Composition id="Ad" /* ... */ />
|
||||
</Folder>
|
||||
<Folder name="Social">
|
||||
<Folder name="Instagram">
|
||||
<Composition id="Story" /* ... */ />
|
||||
<Composition id="Reel" /* ... */ />
|
||||
</Folder>
|
||||
</Folder>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Stills
|
||||
|
||||
Use `<Still>` for single-frame images. It does not require `durationInFrames` or `fps`.
|
||||
|
||||
```tsx
|
||||
import { Still } from "remotion";
|
||||
import { Thumbnail } from "./Thumbnail";
|
||||
|
||||
export const RemotionRoot = () => {
|
||||
return (
|
||||
<Still
|
||||
id="Thumbnail"
|
||||
component={Thumbnail}
|
||||
width={1280}
|
||||
height={720}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Calculate Metadata
|
||||
|
||||
Use `calculateMetadata` to make dimensions, duration, or props dynamic based on data.
|
||||
|
||||
```tsx
|
||||
import { Composition, CalculateMetadataFunction } from "remotion";
|
||||
import { MyComposition, MyCompositionProps } from "./MyComposition";
|
||||
|
||||
const calculateMetadata: CalculateMetadataFunction<MyCompositionProps> = async ({
|
||||
props,
|
||||
abortSignal,
|
||||
}) => {
|
||||
const data = await fetch(`https://api.example.com/video/${props.videoId}`, {
|
||||
signal: abortSignal,
|
||||
}).then((res) => res.json());
|
||||
|
||||
return {
|
||||
durationInFrames: Math.ceil(data.duration * 30),
|
||||
props: {
|
||||
...props,
|
||||
videoUrl: data.url,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const RemotionRoot = () => {
|
||||
return (
|
||||
<Composition
|
||||
id="MyComposition"
|
||||
component={MyComposition}
|
||||
durationInFrames={100} // Placeholder, will be overridden
|
||||
fps={30}
|
||||
width={1080}
|
||||
height={1080}
|
||||
defaultProps={{ videoId: "abc123" }}
|
||||
calculateMetadata={calculateMetadata}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
The function can return `props`, `durationInFrames`, `width`, `height`, `fps`, and codec-related defaults. It runs once before rendering begins.
|
||||
126
skills/remotion-best-practices/rules/display-captions.md
Normal file
126
skills/remotion-best-practices/rules/display-captions.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
name: display-captions
|
||||
description: Displaying captions in Remotion with TikTok-style pages and word highlighting
|
||||
metadata:
|
||||
tags: captions, subtitles, display, tiktok, highlight
|
||||
---
|
||||
|
||||
# Displaying captions in Remotion
|
||||
|
||||
This guide explains how to display captions in Remotion, assuming you already have captions in the `Caption` format.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
First, the @remotion/captions package needs to be installed.
|
||||
If it is not installed, use the following command:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/captions # If project uses npm
|
||||
bunx remotion add @remotion/captions # If project uses bun
|
||||
yarn remotion add @remotion/captions # If project uses yarn
|
||||
pnpm exec remotion add @remotion/captions # If project uses pnpm
|
||||
```
|
||||
|
||||
## Creating pages
|
||||
|
||||
Use `createTikTokStyleCaptions()` to group captions into pages. The `combineTokensWithinMilliseconds` option controls how many words appear at once:
|
||||
|
||||
```tsx
|
||||
import {useMemo} from 'react';
|
||||
import {createTikTokStyleCaptions} from '@remotion/captions';
|
||||
import type {Caption} from '@remotion/captions';
|
||||
|
||||
// How often captions should switch (in milliseconds)
|
||||
// Higher values = more words per page
|
||||
// Lower values = fewer words (more word-by-word)
|
||||
const SWITCH_CAPTIONS_EVERY_MS = 1200;
|
||||
|
||||
const {pages} = useMemo(() => {
|
||||
return createTikTokStyleCaptions({
|
||||
captions,
|
||||
combineTokensWithinMilliseconds: SWITCH_CAPTIONS_EVERY_MS,
|
||||
});
|
||||
}, [captions]);
|
||||
```
|
||||
|
||||
## Rendering with Sequences
|
||||
|
||||
Map over the pages and render each one in a `<Sequence>`. Calculate the start frame and duration from the page timing:
|
||||
|
||||
```tsx
|
||||
import {Sequence, useVideoConfig, AbsoluteFill} from 'remotion';
|
||||
import type {TikTokPage} from '@remotion/captions';
|
||||
|
||||
const CaptionedContent: React.FC = () => {
|
||||
const {fps} = useVideoConfig();
|
||||
|
||||
return (
|
||||
<AbsoluteFill>
|
||||
{pages.map((page, index) => {
|
||||
const nextPage = pages[index + 1] ?? null;
|
||||
const startFrame = (page.startMs / 1000) * fps;
|
||||
const endFrame = Math.min(
|
||||
nextPage ? (nextPage.startMs / 1000) * fps : Infinity,
|
||||
startFrame + (SWITCH_CAPTIONS_EVERY_MS / 1000) * fps,
|
||||
);
|
||||
const durationInFrames = endFrame - startFrame;
|
||||
|
||||
if (durationInFrames <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Sequence
|
||||
key={index}
|
||||
from={startFrame}
|
||||
durationInFrames={durationInFrames}
|
||||
>
|
||||
<CaptionPage page={page} />
|
||||
</Sequence>
|
||||
);
|
||||
})}
|
||||
</AbsoluteFill>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Word highlighting
|
||||
|
||||
A caption page contains `tokens` which you can use to highlight the currently spoken word:
|
||||
|
||||
```tsx
|
||||
import {AbsoluteFill, useCurrentFrame, useVideoConfig} from 'remotion';
|
||||
import type {TikTokPage} from '@remotion/captions';
|
||||
|
||||
const HIGHLIGHT_COLOR = '#39E508';
|
||||
|
||||
const CaptionPage: React.FC<{page: TikTokPage}> = ({page}) => {
|
||||
const frame = useCurrentFrame();
|
||||
const {fps} = useVideoConfig();
|
||||
|
||||
// Current time relative to the start of the sequence
|
||||
const currentTimeMs = (frame / fps) * 1000;
|
||||
// Convert to absolute time by adding the page start
|
||||
const absoluteTimeMs = page.startMs + currentTimeMs;
|
||||
|
||||
return (
|
||||
<AbsoluteFill style={{justifyContent: 'center', alignItems: 'center'}}>
|
||||
<div style={{fontSize: 80, fontWeight: 'bold', whiteSpace: 'pre'}}>
|
||||
{page.tokens.map((token) => {
|
||||
const isActive =
|
||||
token.fromMs <= absoluteTimeMs && token.toMs > absoluteTimeMs;
|
||||
|
||||
return (
|
||||
<span
|
||||
key={token.fromMs}
|
||||
style={{color: isActive ? HIGHLIGHT_COLOR : 'white'}}
|
||||
>
|
||||
{token.text}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</AbsoluteFill>
|
||||
);
|
||||
};
|
||||
```
|
||||
229
skills/remotion-best-practices/rules/extract-frames.md
Normal file
229
skills/remotion-best-practices/rules/extract-frames.md
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
name: extract-frames
|
||||
description: Extract frames from videos at specific timestamps using Mediabunny
|
||||
metadata:
|
||||
tags: frames, extract, video, thumbnail, filmstrip, canvas
|
||||
---
|
||||
|
||||
# Extracting frames from videos
|
||||
|
||||
Use Mediabunny to extract frames from videos at specific timestamps. This is useful for generating thumbnails, filmstrips, or processing individual frames.
|
||||
|
||||
## The `extractFrames()` function
|
||||
|
||||
This function can be copy-pasted into any project.
|
||||
|
||||
```tsx
|
||||
import {
|
||||
ALL_FORMATS,
|
||||
Input,
|
||||
UrlSource,
|
||||
VideoSample,
|
||||
VideoSampleSink,
|
||||
} from "mediabunny";
|
||||
|
||||
type Options = {
|
||||
track: { width: number; height: number };
|
||||
container: string;
|
||||
durationInSeconds: number | null;
|
||||
};
|
||||
|
||||
export type ExtractFramesTimestampsInSecondsFn = (
|
||||
options: Options
|
||||
) => Promise<number[]> | number[];
|
||||
|
||||
export type ExtractFramesProps = {
|
||||
src: string;
|
||||
timestampsInSeconds: number[] | ExtractFramesTimestampsInSecondsFn;
|
||||
onVideoSample: (sample: VideoSample) => void;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
|
||||
export async function extractFrames({
|
||||
src,
|
||||
timestampsInSeconds,
|
||||
onVideoSample,
|
||||
signal,
|
||||
}: ExtractFramesProps): Promise<void> {
|
||||
using input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new UrlSource(src),
|
||||
});
|
||||
|
||||
const [durationInSeconds, format, videoTrack] = await Promise.all([
|
||||
input.computeDuration(),
|
||||
input.getFormat(),
|
||||
input.getPrimaryVideoTrack(),
|
||||
]);
|
||||
|
||||
if (!videoTrack) {
|
||||
throw new Error("No video track found in the input");
|
||||
}
|
||||
|
||||
if (signal?.aborted) {
|
||||
throw new Error("Aborted");
|
||||
}
|
||||
|
||||
const timestamps =
|
||||
typeof timestampsInSeconds === "function"
|
||||
? await timestampsInSeconds({
|
||||
track: {
|
||||
width: videoTrack.displayWidth,
|
||||
height: videoTrack.displayHeight,
|
||||
},
|
||||
container: format.name,
|
||||
durationInSeconds,
|
||||
})
|
||||
: timestampsInSeconds;
|
||||
|
||||
if (timestamps.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (signal?.aborted) {
|
||||
throw new Error("Aborted");
|
||||
}
|
||||
|
||||
const sink = new VideoSampleSink(videoTrack);
|
||||
|
||||
for await (using videoSample of sink.samplesAtTimestamps(timestamps)) {
|
||||
if (signal?.aborted) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!videoSample) {
|
||||
continue;
|
||||
}
|
||||
|
||||
onVideoSample(videoSample);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
Extract frames at specific timestamps:
|
||||
|
||||
```tsx
|
||||
await extractFrames({
|
||||
src: "https://remotion.media/video.mp4",
|
||||
timestampsInSeconds: [0, 1, 2, 3, 4],
|
||||
onVideoSample: (sample) => {
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = sample.displayWidth;
|
||||
canvas.height = sample.displayHeight;
|
||||
const ctx = canvas.getContext("2d");
|
||||
sample.draw(ctx!, 0, 0);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Creating a filmstrip
|
||||
|
||||
Use a callback function to dynamically calculate timestamps based on video metadata:
|
||||
|
||||
```tsx
|
||||
const canvasWidth = 500;
|
||||
const canvasHeight = 80;
|
||||
const fromSeconds = 0;
|
||||
const toSeconds = 10;
|
||||
|
||||
await extractFrames({
|
||||
src: "https://remotion.media/video.mp4",
|
||||
timestampsInSeconds: async ({ track, durationInSeconds }) => {
|
||||
const aspectRatio = track.width / track.height;
|
||||
const amountOfFramesFit = Math.ceil(
|
||||
canvasWidth / (canvasHeight * aspectRatio)
|
||||
);
|
||||
const segmentDuration = toSeconds - fromSeconds;
|
||||
const timestamps: number[] = [];
|
||||
|
||||
for (let i = 0; i < amountOfFramesFit; i++) {
|
||||
timestamps.push(
|
||||
fromSeconds + (segmentDuration / amountOfFramesFit) * (i + 0.5)
|
||||
);
|
||||
}
|
||||
|
||||
return timestamps;
|
||||
},
|
||||
onVideoSample: (sample) => {
|
||||
console.log(`Frame at ${sample.timestamp}s`);
|
||||
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = sample.displayWidth;
|
||||
canvas.height = sample.displayHeight;
|
||||
const ctx = canvas.getContext("2d");
|
||||
sample.draw(ctx!, 0, 0);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Cancellation with AbortSignal
|
||||
|
||||
Cancel frame extraction after a timeout:
|
||||
|
||||
```tsx
|
||||
const controller = new AbortController();
|
||||
|
||||
setTimeout(() => controller.abort(), 5000);
|
||||
|
||||
try {
|
||||
await extractFrames({
|
||||
src: "https://remotion.media/video.mp4",
|
||||
timestampsInSeconds: [0, 1, 2, 3, 4],
|
||||
onVideoSample: (sample) => {
|
||||
using frame = sample;
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = frame.displayWidth;
|
||||
canvas.height = frame.displayHeight;
|
||||
const ctx = canvas.getContext("2d");
|
||||
frame.draw(ctx!, 0, 0);
|
||||
},
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
console.log("Frame extraction complete!");
|
||||
} catch (error) {
|
||||
console.error("Frame extraction was aborted or failed:", error);
|
||||
}
|
||||
```
|
||||
|
||||
## Timeout with Promise.race
|
||||
|
||||
```tsx
|
||||
const controller = new AbortController();
|
||||
|
||||
const timeoutPromise = new Promise<never>((_, reject) => {
|
||||
const timeoutId = setTimeout(() => {
|
||||
controller.abort();
|
||||
reject(new Error("Frame extraction timed out after 10 seconds"));
|
||||
}, 10000);
|
||||
|
||||
controller.signal.addEventListener("abort", () => clearTimeout(timeoutId), {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
await Promise.race([
|
||||
extractFrames({
|
||||
src: "https://remotion.media/video.mp4",
|
||||
timestampsInSeconds: [0, 1, 2, 3, 4],
|
||||
onVideoSample: (sample) => {
|
||||
using frame = sample;
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = frame.displayWidth;
|
||||
canvas.height = frame.displayHeight;
|
||||
const ctx = canvas.getContext("2d");
|
||||
frame.draw(ctx!, 0, 0);
|
||||
},
|
||||
signal: controller.signal,
|
||||
}),
|
||||
timeoutPromise,
|
||||
]);
|
||||
|
||||
console.log("Frame extraction complete!");
|
||||
} catch (error) {
|
||||
console.error("Frame extraction was aborted or failed:", error);
|
||||
}
|
||||
```
|
||||
152
skills/remotion-best-practices/rules/fonts.md
Normal file
152
skills/remotion-best-practices/rules/fonts.md
Normal file
@@ -0,0 +1,152 @@
|
||||
---
|
||||
name: fonts
|
||||
description: Loading Google Fonts and local fonts in Remotion
|
||||
metadata:
|
||||
tags: fonts, google-fonts, typography, text
|
||||
---
|
||||
|
||||
# Using fonts in Remotion
|
||||
|
||||
## Google Fonts with @remotion/google-fonts
|
||||
|
||||
The recommended way to use Google Fonts. It's type-safe and automatically blocks rendering until the font is ready.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
First, the @remotion/google-fonts package needs to be installed.
|
||||
If it is not installed, use the following command:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/google-fonts # If project uses npm
|
||||
bunx remotion add @remotion/google-fonts # If project uses bun
|
||||
yarn remotion add @remotion/google-fonts # If project uses yarn
|
||||
pnpm exec remotion add @remotion/google-fonts # If project uses pnpm
|
||||
```
|
||||
|
||||
```tsx
|
||||
import { loadFont } from "@remotion/google-fonts/Lobster";
|
||||
|
||||
const { fontFamily } = loadFont();
|
||||
|
||||
export const MyComposition = () => {
|
||||
return <div style={{ fontFamily }}>Hello World</div>;
|
||||
};
|
||||
```
|
||||
|
||||
Preferrably, specify only needed weights and subsets to reduce file size:
|
||||
|
||||
```tsx
|
||||
import { loadFont } from "@remotion/google-fonts/Roboto";
|
||||
|
||||
const { fontFamily } = loadFont("normal", {
|
||||
weights: ["400", "700"],
|
||||
subsets: ["latin"],
|
||||
});
|
||||
```
|
||||
|
||||
### Waiting for font to load
|
||||
|
||||
Use `waitUntilDone()` if you need to know when the font is ready:
|
||||
|
||||
```tsx
|
||||
import { loadFont } from "@remotion/google-fonts/Lobster";
|
||||
|
||||
const { fontFamily, waitUntilDone } = loadFont();
|
||||
|
||||
await waitUntilDone();
|
||||
```
|
||||
|
||||
## Local fonts with @remotion/fonts
|
||||
|
||||
For local font files, use the `@remotion/fonts` package.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
First, install @remotion/fonts:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/fonts # If project uses npm
|
||||
bunx remotion add @remotion/fonts # If project uses bun
|
||||
yarn remotion add @remotion/fonts # If project uses yarn
|
||||
pnpm exec remotion add @remotion/fonts # If project uses pnpm
|
||||
```
|
||||
|
||||
### Loading a local font
|
||||
|
||||
Place your font file in the `public/` folder and use `loadFont()`:
|
||||
|
||||
```tsx
|
||||
import { loadFont } from "@remotion/fonts";
|
||||
import { staticFile } from "remotion";
|
||||
|
||||
await loadFont({
|
||||
family: "MyFont",
|
||||
url: staticFile("MyFont-Regular.woff2"),
|
||||
});
|
||||
|
||||
export const MyComposition = () => {
|
||||
return <div style={{ fontFamily: "MyFont" }}>Hello World</div>;
|
||||
};
|
||||
```
|
||||
|
||||
### Loading multiple weights
|
||||
|
||||
Load each weight separately with the same family name:
|
||||
|
||||
```tsx
|
||||
import { loadFont } from "@remotion/fonts";
|
||||
import { staticFile } from "remotion";
|
||||
|
||||
await Promise.all([
|
||||
loadFont({
|
||||
family: "Inter",
|
||||
url: staticFile("Inter-Regular.woff2"),
|
||||
weight: "400",
|
||||
}),
|
||||
loadFont({
|
||||
family: "Inter",
|
||||
url: staticFile("Inter-Bold.woff2"),
|
||||
weight: "700",
|
||||
}),
|
||||
]);
|
||||
```
|
||||
|
||||
### Available options
|
||||
|
||||
```tsx
|
||||
loadFont({
|
||||
family: "MyFont", // Required: name to use in CSS
|
||||
url: staticFile("font.woff2"), // Required: font file URL
|
||||
format: "woff2", // Optional: auto-detected from extension
|
||||
weight: "400", // Optional: font weight
|
||||
style: "normal", // Optional: normal or italic
|
||||
display: "block", // Optional: font-display behavior
|
||||
});
|
||||
```
|
||||
|
||||
## Using in components
|
||||
|
||||
Call `loadFont()` at the top level of your component or in a separate file that's imported early:
|
||||
|
||||
```tsx
|
||||
import { loadFont } from "@remotion/google-fonts/Montserrat";
|
||||
|
||||
const { fontFamily } = loadFont("normal", {
|
||||
weights: ["400", "700"],
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const Title: React.FC<{ text: string }> = ({ text }) => {
|
||||
return (
|
||||
<h1
|
||||
style={{
|
||||
fontFamily,
|
||||
fontSize: 80,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</h1>
|
||||
);
|
||||
};
|
||||
```
|
||||
58
skills/remotion-best-practices/rules/get-audio-duration.md
Normal file
58
skills/remotion-best-practices/rules/get-audio-duration.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: get-audio-duration
|
||||
description: Getting the duration of an audio file in seconds with Mediabunny
|
||||
metadata:
|
||||
tags: duration, audio, length, time, seconds, mp3, wav
|
||||
---
|
||||
|
||||
# Getting audio duration with Mediabunny
|
||||
|
||||
Mediabunny can extract the duration of an audio file. It works in browser, Node.js, and Bun environments.
|
||||
|
||||
## Getting audio duration
|
||||
|
||||
```tsx
|
||||
import { Input, ALL_FORMATS, UrlSource } from "mediabunny";
|
||||
|
||||
export const getAudioDuration = async (src: string) => {
|
||||
const input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new UrlSource(src, {
|
||||
getRetryDelay: () => null,
|
||||
}),
|
||||
});
|
||||
|
||||
const durationInSeconds = await input.computeDuration();
|
||||
return durationInSeconds;
|
||||
};
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
const duration = await getAudioDuration("https://remotion.media/audio.mp3");
|
||||
console.log(duration); // e.g. 180.5 (seconds)
|
||||
```
|
||||
|
||||
## Using with local files
|
||||
|
||||
For local files, use `FileSource` instead of `UrlSource`:
|
||||
|
||||
```tsx
|
||||
import { Input, ALL_FORMATS, FileSource } from "mediabunny";
|
||||
|
||||
const input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new FileSource(file), // File object from input or drag-drop
|
||||
});
|
||||
|
||||
const durationInSeconds = await input.computeDuration();
|
||||
```
|
||||
|
||||
## Using with staticFile in Remotion
|
||||
|
||||
```tsx
|
||||
import { staticFile } from "remotion";
|
||||
|
||||
const duration = await getAudioDuration(staticFile("audio.mp3"));
|
||||
```
|
||||
68
skills/remotion-best-practices/rules/get-video-dimensions.md
Normal file
68
skills/remotion-best-practices/rules/get-video-dimensions.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
name: get-video-dimensions
|
||||
description: Getting the width and height of a video file with Mediabunny
|
||||
metadata:
|
||||
tags: dimensions, width, height, resolution, size, video
|
||||
---
|
||||
|
||||
# Getting video dimensions with Mediabunny
|
||||
|
||||
Mediabunny can extract the width and height of a video file. It works in browser, Node.js, and Bun environments.
|
||||
|
||||
## Getting video dimensions
|
||||
|
||||
```tsx
|
||||
import { Input, ALL_FORMATS, UrlSource } from "mediabunny";
|
||||
|
||||
export const getVideoDimensions = async (src: string) => {
|
||||
const input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new UrlSource(src, {
|
||||
getRetryDelay: () => null,
|
||||
}),
|
||||
});
|
||||
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
if (!videoTrack) {
|
||||
throw new Error("No video track found");
|
||||
}
|
||||
|
||||
return {
|
||||
width: videoTrack.displayWidth,
|
||||
height: videoTrack.displayHeight,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
const dimensions = await getVideoDimensions("https://remotion.media/video.mp4");
|
||||
console.log(dimensions.width); // e.g. 1920
|
||||
console.log(dimensions.height); // e.g. 1080
|
||||
```
|
||||
|
||||
## Using with local files
|
||||
|
||||
For local files, use `FileSource` instead of `UrlSource`:
|
||||
|
||||
```tsx
|
||||
import { Input, ALL_FORMATS, FileSource } from "mediabunny";
|
||||
|
||||
const input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new FileSource(file), // File object from input or drag-drop
|
||||
});
|
||||
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
const width = videoTrack.displayWidth;
|
||||
const height = videoTrack.displayHeight;
|
||||
```
|
||||
|
||||
## Using with staticFile in Remotion
|
||||
|
||||
```tsx
|
||||
import { staticFile } from "remotion";
|
||||
|
||||
const dimensions = await getVideoDimensions(staticFile("video.mp4"));
|
||||
```
|
||||
58
skills/remotion-best-practices/rules/get-video-duration.md
Normal file
58
skills/remotion-best-practices/rules/get-video-duration.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: get-video-duration
|
||||
description: Getting the duration of a video file in seconds with Mediabunny
|
||||
metadata:
|
||||
tags: duration, video, length, time, seconds
|
||||
---
|
||||
|
||||
# Getting video duration with Mediabunny
|
||||
|
||||
Mediabunny can extract the duration of a video file. It works in browser, Node.js, and Bun environments.
|
||||
|
||||
## Getting video duration
|
||||
|
||||
```tsx
|
||||
import { Input, ALL_FORMATS, UrlSource } from "mediabunny";
|
||||
|
||||
export const getVideoDuration = async (src: string) => {
|
||||
const input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new UrlSource(src, {
|
||||
getRetryDelay: () => null,
|
||||
}),
|
||||
});
|
||||
|
||||
const durationInSeconds = await input.computeDuration();
|
||||
return durationInSeconds;
|
||||
};
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
const duration = await getVideoDuration("https://remotion.media/video.mp4");
|
||||
console.log(duration); // e.g. 10.5 (seconds)
|
||||
```
|
||||
|
||||
## Using with local files
|
||||
|
||||
For local files, use `FileSource` instead of `UrlSource`:
|
||||
|
||||
```tsx
|
||||
import { Input, ALL_FORMATS, FileSource } from "mediabunny";
|
||||
|
||||
const input = new Input({
|
||||
formats: ALL_FORMATS,
|
||||
source: new FileSource(file), // File object from input or drag-drop
|
||||
});
|
||||
|
||||
const durationInSeconds = await input.computeDuration();
|
||||
```
|
||||
|
||||
## Using with staticFile in Remotion
|
||||
|
||||
```tsx
|
||||
import { staticFile } from "remotion";
|
||||
|
||||
const duration = await getVideoDuration(staticFile("video.mp4"));
|
||||
```
|
||||
138
skills/remotion-best-practices/rules/gifs.md
Normal file
138
skills/remotion-best-practices/rules/gifs.md
Normal file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
name: gif
|
||||
description: Displaying GIFs, APNG, AVIF and WebP in Remotion
|
||||
metadata:
|
||||
tags: gif, animation, images, animated, apng, avif, webp
|
||||
---
|
||||
|
||||
# Using Animated images in Remotion
|
||||
|
||||
## Basic usage
|
||||
|
||||
Use `<AnimatedImage>` to display a GIF, APNG, AVIF or WebP image synchronized with Remotion's timeline:
|
||||
|
||||
```tsx
|
||||
import {AnimatedImage, staticFile} from 'remotion';
|
||||
|
||||
export const MyComposition = () => {
|
||||
return <AnimatedImage src={staticFile('animation.gif')} width={500} height={500} />;
|
||||
};
|
||||
```
|
||||
|
||||
Remote URLs are also supported (must have CORS enabled):
|
||||
|
||||
```tsx
|
||||
<AnimatedImage src="https://example.com/animation.gif" width={500} height={500} />
|
||||
```
|
||||
|
||||
## Sizing and fit
|
||||
|
||||
Control how the image fills its container with the `fit` prop:
|
||||
|
||||
```tsx
|
||||
// Stretch to fill (default)
|
||||
<AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="fill" />
|
||||
|
||||
// Maintain aspect ratio, fit inside container
|
||||
<AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="contain" />
|
||||
|
||||
// Fill container, crop if needed
|
||||
<AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="cover" />
|
||||
```
|
||||
|
||||
## Playback speed
|
||||
|
||||
Use `playbackRate` to control the animation speed:
|
||||
|
||||
```tsx
|
||||
<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} playbackRate={2} /> {/* 2x speed */}
|
||||
<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} playbackRate={0.5} /> {/* Half speed */}
|
||||
```
|
||||
|
||||
## Looping behavior
|
||||
|
||||
Control what happens when the animation finishes:
|
||||
|
||||
```tsx
|
||||
// Loop indefinitely (default)
|
||||
<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="loop" />
|
||||
|
||||
// Play once, show final frame
|
||||
<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="pause-after-finish" />
|
||||
|
||||
// Play once, then clear canvas
|
||||
<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="clear-after-finish" />
|
||||
```
|
||||
|
||||
## Styling
|
||||
|
||||
Use the `style` prop for additional CSS (use `width` and `height` props for sizing):
|
||||
|
||||
```tsx
|
||||
<AnimatedImage
|
||||
src={staticFile('animation.gif')}
|
||||
width={500}
|
||||
height={500}
|
||||
style={{
|
||||
borderRadius: 20,
|
||||
position: 'absolute',
|
||||
top: 100,
|
||||
left: 50,
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## Getting GIF duration
|
||||
|
||||
Use `getGifDurationInSeconds()` from `@remotion/gif` to get the duration of a GIF.
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/gif # If project uses npm
|
||||
bunx remotion add @remotion/gif # If project uses bun
|
||||
yarn remotion add @remotion/gif # If project uses yarn
|
||||
pnpm exec remotion add @remotion/gif # If project uses pnpm
|
||||
```
|
||||
|
||||
```tsx
|
||||
import {getGifDurationInSeconds} from '@remotion/gif';
|
||||
import {staticFile} from 'remotion';
|
||||
|
||||
const duration = await getGifDurationInSeconds(staticFile('animation.gif'));
|
||||
console.log(duration); // e.g. 2.5
|
||||
```
|
||||
|
||||
This is useful for setting the composition duration to match the GIF:
|
||||
|
||||
```tsx
|
||||
import {getGifDurationInSeconds} from '@remotion/gif';
|
||||
import {staticFile, CalculateMetadataFunction} from 'remotion';
|
||||
|
||||
const calculateMetadata: CalculateMetadataFunction = async () => {
|
||||
const duration = await getGifDurationInSeconds(staticFile('animation.gif'));
|
||||
return {
|
||||
durationInFrames: Math.ceil(duration * 30),
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Alternative
|
||||
|
||||
If `<AnimatedImage>` does not work (only supported in Chrome and Firefox), you can use `<Gif>` from `@remotion/gif` instead.
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/gif # If project uses npm
|
||||
bunx remotion add @remotion/gif # If project uses bun
|
||||
yarn remotion add @remotion/gif # If project uses yarn
|
||||
pnpm exec remotion add @remotion/gif # If project uses pnpm
|
||||
```
|
||||
|
||||
```tsx
|
||||
import {Gif} from '@remotion/gif';
|
||||
import {staticFile} from 'remotion';
|
||||
|
||||
export const MyComposition = () => {
|
||||
return <Gif src={staticFile('animation.gif')} width={500} height={500} />;
|
||||
};
|
||||
```
|
||||
|
||||
The `<Gif>` component has the same props as `<AnimatedImage>` but only supports GIF files.
|
||||
130
skills/remotion-best-practices/rules/images.md
Normal file
130
skills/remotion-best-practices/rules/images.md
Normal file
@@ -0,0 +1,130 @@
|
||||
---
|
||||
name: images
|
||||
description: Embedding images in Remotion using the <Img> component
|
||||
metadata:
|
||||
tags: images, img, staticFile, png, jpg, svg, webp
|
||||
---
|
||||
|
||||
# Using images in Remotion
|
||||
|
||||
## The `<Img>` component
|
||||
|
||||
Always use the `<Img>` component from `remotion` to display images:
|
||||
|
||||
```tsx
|
||||
import { Img, staticFile } from "remotion";
|
||||
|
||||
export const MyComposition = () => {
|
||||
return <Img src={staticFile("photo.png")} />;
|
||||
};
|
||||
```
|
||||
|
||||
## Important restrictions
|
||||
|
||||
**You MUST use the `<Img>` component from `remotion`.** Do not use:
|
||||
|
||||
- Native HTML `<img>` elements
|
||||
- Next.js `<Image>` component
|
||||
- CSS `background-image`
|
||||
|
||||
The `<Img>` component ensures images are fully loaded before rendering, preventing flickering and blank frames during video export.
|
||||
|
||||
## Local images with staticFile()
|
||||
|
||||
Place images in the `public/` folder and use `staticFile()` to reference them:
|
||||
|
||||
```
|
||||
my-video/
|
||||
├─ public/
|
||||
│ ├─ logo.png
|
||||
│ ├─ avatar.jpg
|
||||
│ └─ icon.svg
|
||||
├─ src/
|
||||
├─ package.json
|
||||
```
|
||||
|
||||
```tsx
|
||||
import { Img, staticFile } from "remotion";
|
||||
|
||||
<Img src={staticFile("logo.png")} />
|
||||
```
|
||||
|
||||
## Remote images
|
||||
|
||||
Remote URLs can be used directly without `staticFile()`:
|
||||
|
||||
```tsx
|
||||
<Img src="https://example.com/image.png" />
|
||||
```
|
||||
|
||||
Ensure remote images have CORS enabled.
|
||||
|
||||
For animated GIFs, use the `<Gif>` component from `@remotion/gif` instead.
|
||||
|
||||
## Sizing and positioning
|
||||
|
||||
Use the `style` prop to control size and position:
|
||||
|
||||
```tsx
|
||||
<Img
|
||||
src={staticFile("photo.png")}
|
||||
style={{
|
||||
width: 500,
|
||||
height: 300,
|
||||
position: "absolute",
|
||||
top: 100,
|
||||
left: 50,
|
||||
objectFit: "cover",
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## Dynamic image paths
|
||||
|
||||
Use template literals for dynamic file references:
|
||||
|
||||
```tsx
|
||||
import { Img, staticFile, useCurrentFrame } from "remotion";
|
||||
|
||||
const frame = useCurrentFrame();
|
||||
|
||||
// Image sequence
|
||||
<Img src={staticFile(`frames/frame${frame}.png`)} />
|
||||
|
||||
// Selecting based on props
|
||||
<Img src={staticFile(`avatars/${props.userId}.png`)} />
|
||||
|
||||
// Conditional images
|
||||
<Img src={staticFile(`icons/${isActive ? "active" : "inactive"}.svg`)} />
|
||||
```
|
||||
|
||||
This pattern is useful for:
|
||||
|
||||
- Image sequences (frame-by-frame animations)
|
||||
- User-specific avatars or profile images
|
||||
- Theme-based icons
|
||||
- State-dependent graphics
|
||||
|
||||
## Getting image dimensions
|
||||
|
||||
Use `getImageDimensions()` to get the dimensions of an image:
|
||||
|
||||
```tsx
|
||||
import { getImageDimensions, staticFile } from "remotion";
|
||||
|
||||
const { width, height } = await getImageDimensions(staticFile("photo.png"));
|
||||
```
|
||||
|
||||
This is useful for calculating aspect ratios or sizing compositions:
|
||||
|
||||
```tsx
|
||||
import { getImageDimensions, staticFile, CalculateMetadataFunction } from "remotion";
|
||||
|
||||
const calculateMetadata: CalculateMetadataFunction = async () => {
|
||||
const { width, height } = await getImageDimensions(staticFile("photo.png"));
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
};
|
||||
};
|
||||
```
|
||||
67
skills/remotion-best-practices/rules/import-srt-captions.md
Normal file
67
skills/remotion-best-practices/rules/import-srt-captions.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
name: import-srt-captions
|
||||
description: Importing .srt subtitle files into Remotion using @remotion/captions
|
||||
metadata:
|
||||
tags: captions, subtitles, srt, import, parse
|
||||
---
|
||||
|
||||
# Importing .srt subtitles into Remotion
|
||||
|
||||
If you have an existing `.srt` subtitle file, you can import it into Remotion using `parseSrt()` from `@remotion/captions`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
First, the @remotion/captions package needs to be installed.
|
||||
If it is not installed, use the following command:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/captions # If project uses npm
|
||||
bunx remotion add @remotion/captions # If project uses bun
|
||||
yarn remotion add @remotion/captions # If project uses yarn
|
||||
pnpm exec remotion add @remotion/captions # If project uses pnpm
|
||||
```
|
||||
|
||||
## Reading an .srt file
|
||||
|
||||
Use `staticFile()` to reference an `.srt` file in your `public` folder, then fetch and parse it:
|
||||
|
||||
```tsx
|
||||
import {useState, useEffect, useCallback} from 'react';
|
||||
import {AbsoluteFill, staticFile, useDelayRender} from 'remotion';
|
||||
import {parseSrt} from '@remotion/captions';
|
||||
import type {Caption} from '@remotion/captions';
|
||||
|
||||
export const MyComponent: React.FC = () => {
|
||||
const [captions, setCaptions] = useState<Caption[] | null>(null);
|
||||
const {delayRender, continueRender, cancelRender} = useDelayRender();
|
||||
const [handle] = useState(() => delayRender());
|
||||
|
||||
const fetchCaptions = useCallback(async () => {
|
||||
try {
|
||||
const response = await fetch(staticFile('subtitles.srt'));
|
||||
const text = await response.text();
|
||||
const {captions: parsed} = parseSrt({input: text});
|
||||
setCaptions(parsed);
|
||||
continueRender(handle);
|
||||
} catch (e) {
|
||||
cancelRender(e);
|
||||
}
|
||||
}, [continueRender, cancelRender, handle]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchCaptions();
|
||||
}, [fetchCaptions]);
|
||||
|
||||
if (!captions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <AbsoluteFill>{/* Use captions here */}</AbsoluteFill>;
|
||||
};
|
||||
```
|
||||
|
||||
Remote URLs are also supported - you can `fetch()` a remote file via URL instead of using `staticFile()`.
|
||||
|
||||
## Using imported captions
|
||||
|
||||
Once parsed, the captions are in the `Caption` format and can be used with all `@remotion/captions` utilities.
|
||||
68
skills/remotion-best-practices/rules/lottie.md
Normal file
68
skills/remotion-best-practices/rules/lottie.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
name: lottie
|
||||
description: Embedding Lottie animations in Remotion.
|
||||
metadata:
|
||||
category: Animation
|
||||
---
|
||||
|
||||
# Using Lottie Animations in Remotion
|
||||
|
||||
## Prerequisites
|
||||
|
||||
First, the @remotion/lottie package needs to be installed.
|
||||
If it is not, use the following command:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/lottie # If project uses npm
|
||||
bunx remotion add @remotion/lottie # If project uses bun
|
||||
yarn remotion add @remotion/lottie # If project uses yarn
|
||||
pnpm exec remotion add @remotion/lottie # If project uses pnpm
|
||||
```
|
||||
|
||||
## Displaying a Lottie file
|
||||
|
||||
To import a Lottie animation:
|
||||
|
||||
- Fetch the Lottie asset
|
||||
- Wrap the loading process in `delayRender()` and `continueRender()`
|
||||
- Save the animation data in a state
|
||||
- Render the Lottie animation using the `Lottie` component from the `@remotion/lottie` package
|
||||
|
||||
```tsx
|
||||
import {Lottie, LottieAnimationData} from '@remotion/lottie';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {cancelRender, continueRender, delayRender} from 'remotion';
|
||||
|
||||
export const MyAnimation = () => {
|
||||
const [handle] = useState(() => delayRender('Loading Lottie animation'));
|
||||
|
||||
const [animationData, setAnimationData] = useState<LottieAnimationData | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetch('https://assets4.lottiefiles.com/packages/lf20_zyquagfl.json')
|
||||
.then((data) => data.json())
|
||||
.then((json) => {
|
||||
setAnimationData(json);
|
||||
continueRender(handle);
|
||||
})
|
||||
.catch((err) => {
|
||||
cancelRender(err);
|
||||
});
|
||||
}, [handle]);
|
||||
|
||||
if (!animationData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <Lottie animationData={animationData} />;
|
||||
};
|
||||
```
|
||||
|
||||
## Styling and animating
|
||||
|
||||
Lottie supports the `style` prop to allow styles and animations:
|
||||
|
||||
```tsx
|
||||
return <Lottie animationData={animationData} style={{width: 400, height: 400}} />;
|
||||
```
|
||||
|
||||
35
skills/remotion-best-practices/rules/measuring-dom-nodes.md
Normal file
35
skills/remotion-best-practices/rules/measuring-dom-nodes.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: measuring-dom-nodes
|
||||
description: Measuring DOM element dimensions in Remotion
|
||||
metadata:
|
||||
tags: measure, layout, dimensions, getBoundingClientRect, scale
|
||||
---
|
||||
|
||||
# Measuring DOM nodes in Remotion
|
||||
|
||||
Remotion applies a `scale()` transform to the video container, which affects values from `getBoundingClientRect()`. Use `useCurrentScale()` to get correct measurements.
|
||||
|
||||
## Measuring element dimensions
|
||||
|
||||
```tsx
|
||||
import { useCurrentScale } from "remotion";
|
||||
import { useRef, useEffect, useState } from "react";
|
||||
|
||||
export const MyComponent = () => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const scale = useCurrentScale();
|
||||
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref.current) return;
|
||||
const rect = ref.current.getBoundingClientRect();
|
||||
setDimensions({
|
||||
width: rect.width / scale,
|
||||
height: rect.height / scale,
|
||||
});
|
||||
}, [scale]);
|
||||
|
||||
return <div ref={ref}>Content to measure</div>;
|
||||
};
|
||||
```
|
||||
|
||||
143
skills/remotion-best-practices/rules/measuring-text.md
Normal file
143
skills/remotion-best-practices/rules/measuring-text.md
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
name: measuring-text
|
||||
description: Measuring text dimensions, fitting text to containers, and checking overflow
|
||||
metadata:
|
||||
tags: measure, text, layout, dimensions, fitText, fillTextBox
|
||||
---
|
||||
|
||||
# Measuring text in Remotion
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Install @remotion/layout-utils if it is not already installed:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/layout-utils # If project uses npm
|
||||
bunx remotion add @remotion/layout-utils # If project uses bun
|
||||
yarn remotion add @remotion/layout-utils # If project uses yarn
|
||||
pnpm exec remotion add @remotion/layout-utils # If project uses pnpm
|
||||
```
|
||||
|
||||
## Measuring text dimensions
|
||||
|
||||
Use `measureText()` to calculate the width and height of text:
|
||||
|
||||
```tsx
|
||||
import { measureText } from "@remotion/layout-utils";
|
||||
|
||||
const { width, height } = measureText({
|
||||
text: "Hello World",
|
||||
fontFamily: "Arial",
|
||||
fontSize: 32,
|
||||
fontWeight: "bold",
|
||||
});
|
||||
```
|
||||
|
||||
Results are cached - duplicate calls return the cached result.
|
||||
|
||||
## Fitting text to a width
|
||||
|
||||
Use `fitText()` to find the optimal font size for a container:
|
||||
|
||||
```tsx
|
||||
import { fitText } from "@remotion/layout-utils";
|
||||
|
||||
const { fontSize } = fitText({
|
||||
text: "Hello World",
|
||||
withinWidth: 600,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: "bold",
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
fontSize: Math.min(fontSize, 80), // Cap at 80px
|
||||
fontFamily: "Inter",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Hello World
|
||||
</div>
|
||||
);
|
||||
```
|
||||
|
||||
## Checking text overflow
|
||||
|
||||
Use `fillTextBox()` to check if text exceeds a box:
|
||||
|
||||
```tsx
|
||||
import { fillTextBox } from "@remotion/layout-utils";
|
||||
|
||||
const box = fillTextBox({ maxBoxWidth: 400, maxLines: 3 });
|
||||
|
||||
const words = ["Hello", "World", "This", "is", "a", "test"];
|
||||
for (const word of words) {
|
||||
const { exceedsBox } = box.add({
|
||||
text: word + " ",
|
||||
fontFamily: "Arial",
|
||||
fontSize: 24,
|
||||
});
|
||||
if (exceedsBox) {
|
||||
// Text would overflow, handle accordingly
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
**Load fonts first:** Only call measurement functions after fonts are loaded.
|
||||
|
||||
```tsx
|
||||
import { loadFont } from "@remotion/google-fonts/Inter";
|
||||
|
||||
const { fontFamily, waitUntilDone } = loadFont("normal", {
|
||||
weights: ["400"],
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
waitUntilDone().then(() => {
|
||||
// Now safe to measure
|
||||
const { width } = measureText({
|
||||
text: "Hello",
|
||||
fontFamily,
|
||||
fontSize: 32,
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
**Use validateFontIsLoaded:** Catch font loading issues early:
|
||||
|
||||
```tsx
|
||||
measureText({
|
||||
text: "Hello",
|
||||
fontFamily: "MyCustomFont",
|
||||
fontSize: 32,
|
||||
validateFontIsLoaded: true, // Throws if font not loaded
|
||||
});
|
||||
```
|
||||
|
||||
**Match font properties:** Use the same properties for measurement and rendering:
|
||||
|
||||
```tsx
|
||||
const fontStyle = {
|
||||
fontFamily: "Inter",
|
||||
fontSize: 32,
|
||||
fontWeight: "bold" as const,
|
||||
letterSpacing: "0.5px",
|
||||
};
|
||||
|
||||
const { width } = measureText({
|
||||
text: "Hello",
|
||||
...fontStyle,
|
||||
});
|
||||
|
||||
return <div style={fontStyle}>Hello</div>;
|
||||
```
|
||||
|
||||
**Avoid padding and border:** Use `outline` instead of `border` to prevent layout differences:
|
||||
|
||||
```tsx
|
||||
<div style={{ outline: "2px solid red" }}>Text</div>
|
||||
```
|
||||
106
skills/remotion-best-practices/rules/sequencing.md
Normal file
106
skills/remotion-best-practices/rules/sequencing.md
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
name: sequencing
|
||||
description: Sequencing patterns for Remotion - delay, trim, limit duration of items
|
||||
metadata:
|
||||
tags: sequence, series, timing, delay, trim
|
||||
---
|
||||
|
||||
Use `<Sequence>` to delay when an element appears in the timeline.
|
||||
|
||||
```tsx
|
||||
import { Sequence } from "remotion";
|
||||
|
||||
const {fps} = useVideoConfig();
|
||||
|
||||
<Sequence from={1 * fps} durationInFrames={2 * fps} premountFor={1 * fps}>
|
||||
<Title />
|
||||
</Sequence>
|
||||
<Sequence from={2 * fps} durationInFrames={2 * fps} premountFor={1 * fps}>
|
||||
<Subtitle />
|
||||
</Sequence>
|
||||
```
|
||||
|
||||
This will by default wrap the component in an absolute fill element.
|
||||
If the items should not be wrapped, use the `layout` prop:
|
||||
|
||||
```tsx
|
||||
<Sequence layout="none">
|
||||
<Title />
|
||||
</Sequence>
|
||||
```
|
||||
|
||||
## Premounting
|
||||
|
||||
This loads the component in the timeline before it is actually played.
|
||||
Always premount any `<Sequence>`!
|
||||
|
||||
```tsx
|
||||
<Sequence premountFor={1 * fps}>
|
||||
<Title />
|
||||
</Sequence>
|
||||
```
|
||||
|
||||
## Series
|
||||
|
||||
Use `<Series>` when elements should play one after another without overlap.
|
||||
|
||||
```tsx
|
||||
import {Series} from 'remotion';
|
||||
|
||||
<Series>
|
||||
<Series.Sequence durationInFrames={45}>
|
||||
<Intro />
|
||||
</Series.Sequence>
|
||||
<Series.Sequence durationInFrames={60}>
|
||||
<MainContent />
|
||||
</Series.Sequence>
|
||||
<Series.Sequence durationInFrames={30}>
|
||||
<Outro />
|
||||
</Series.Sequence>
|
||||
</Series>;
|
||||
```
|
||||
|
||||
Same as with `<Sequence>`, the items will be wrapped in an absolute fill element by default when using `<Series.Sequence>`, unless the `layout` prop is set to `none`.
|
||||
|
||||
### Series with overlaps
|
||||
|
||||
Use negative offset for overlapping sequences:
|
||||
|
||||
```tsx
|
||||
<Series>
|
||||
<Series.Sequence durationInFrames={60}>
|
||||
<SceneA />
|
||||
</Series.Sequence>
|
||||
<Series.Sequence offset={-15} durationInFrames={60}>
|
||||
{/* Starts 15 frames before SceneA ends */}
|
||||
<SceneB />
|
||||
</Series.Sequence>
|
||||
</Series>
|
||||
```
|
||||
|
||||
## Frame References Inside Sequences
|
||||
|
||||
Inside a Sequence, `useCurrentFrame()` returns the local frame (starting from 0):
|
||||
|
||||
```tsx
|
||||
<Sequence from={60} durationInFrames={30}>
|
||||
<MyComponent />
|
||||
{/* Inside MyComponent, useCurrentFrame() returns 0-29, not 60-89 */}
|
||||
</Sequence>
|
||||
```
|
||||
|
||||
## Nested Sequences
|
||||
|
||||
Sequences can be nested for complex timing:
|
||||
|
||||
```tsx
|
||||
<Sequence from={0} durationInFrames={120}>
|
||||
<Background />
|
||||
<Sequence from={15} durationInFrames={90} layout="none">
|
||||
<Title />
|
||||
</Sequence>
|
||||
<Sequence from={45} durationInFrames={60} layout="none">
|
||||
<Subtitle />
|
||||
</Sequence>
|
||||
</Sequence>
|
||||
```
|
||||
11
skills/remotion-best-practices/rules/tailwind.md
Normal file
11
skills/remotion-best-practices/rules/tailwind.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: tailwind
|
||||
description: Using TailwindCSS in Remotion.
|
||||
metadata:
|
||||
---
|
||||
|
||||
You can and should use TailwindCSS in Remotion, if TailwindCSS is installed in the project.
|
||||
|
||||
Don't use `transition-*` or `animate-*` classes - always animate using the `useCurrentFrame()` hook.
|
||||
|
||||
Tailwind must be installed and enabled first in a Remotion project - fetch https://www.remotion.dev/docs/tailwind using WebFetch for instructions.
|
||||
20
skills/remotion-best-practices/rules/text-animations.md
Normal file
20
skills/remotion-best-practices/rules/text-animations.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: text-animations
|
||||
description: Typography and text animation patterns for Remotion.
|
||||
metadata:
|
||||
tags: typography, text, typewriter, highlighter ken
|
||||
---
|
||||
|
||||
## Text animations
|
||||
|
||||
Based on `useCurrentFrame()`, reduce the string character by character to create a typewriter effect.
|
||||
|
||||
## Typewriter Effect
|
||||
|
||||
See [Typewriter](assets/text-animations-typewriter.tsx) for an advanced example with a blinking cursor and a pause after the first sentence.
|
||||
|
||||
Always use string slicing for typewriter effects. Never use per-character opacity.
|
||||
|
||||
## Word Highlighting
|
||||
|
||||
See [Word Highlight](assets/text-animations-word-highlight.tsx) for an example for how a word highlight is animated, like with a highlighter pen.
|
||||
179
skills/remotion-best-practices/rules/timing.md
Normal file
179
skills/remotion-best-practices/rules/timing.md
Normal file
@@ -0,0 +1,179 @@
|
||||
---
|
||||
name: timing
|
||||
description: Interpolation curves in Remotion - linear, easing, spring animations
|
||||
metadata:
|
||||
tags: spring, bounce, easing, interpolation
|
||||
---
|
||||
|
||||
A simple linear interpolation is done using the `interpolate` function.
|
||||
|
||||
```ts title="Going from 0 to 1 over 100 frames"
|
||||
import {interpolate} from 'remotion';
|
||||
|
||||
const opacity = interpolate(frame, [0, 100], [0, 1]);
|
||||
```
|
||||
|
||||
By default, the values are not clamped, so the value can go outside the range [0, 1].
|
||||
Here is how they can be clamped:
|
||||
|
||||
```ts title="Going from 0 to 1 over 100 frames with extrapolation"
|
||||
const opacity = interpolate(frame, [0, 100], [0, 1], {
|
||||
extrapolateRight: 'clamp',
|
||||
extrapolateLeft: 'clamp',
|
||||
});
|
||||
```
|
||||
|
||||
## Spring animations
|
||||
|
||||
Spring animations have a more natural motion.
|
||||
They go from 0 to 1 over time.
|
||||
|
||||
```ts title="Spring animation from 0 to 1 over 100 frames"
|
||||
import {spring, useCurrentFrame, useVideoConfig} from 'remotion';
|
||||
|
||||
const frame = useCurrentFrame();
|
||||
const {fps} = useVideoConfig();
|
||||
|
||||
const scale = spring({
|
||||
frame,
|
||||
fps,
|
||||
});
|
||||
```
|
||||
|
||||
### Physical properties
|
||||
|
||||
The default configuration is: `mass: 1, damping: 10, stiffness: 100`.
|
||||
This leads to the animation having a bit of bounce before it settles.
|
||||
|
||||
The config can be overwritten like this:
|
||||
|
||||
```ts
|
||||
const scale = spring({
|
||||
frame,
|
||||
fps,
|
||||
config: {damping: 200},
|
||||
});
|
||||
```
|
||||
|
||||
The recommended configuration for a natural motion without a bounce is: `{ damping: 200 }`.
|
||||
|
||||
Here are some common configurations:
|
||||
|
||||
```tsx
|
||||
const smooth = {damping: 200}; // Smooth, no bounce (subtle reveals)
|
||||
const snappy = {damping: 20, stiffness: 200}; // Snappy, minimal bounce (UI elements)
|
||||
const bouncy = {damping: 8}; // Bouncy entrance (playful animations)
|
||||
const heavy = {damping: 15, stiffness: 80, mass: 2}; // Heavy, slow, small bounce
|
||||
```
|
||||
|
||||
### Delay
|
||||
|
||||
The animation starts immediately by default.
|
||||
Use the `delay` parameter to delay the animation by a number of frames.
|
||||
|
||||
```tsx
|
||||
const entrance = spring({
|
||||
frame: frame - ENTRANCE_DELAY,
|
||||
fps,
|
||||
delay: 20,
|
||||
});
|
||||
```
|
||||
|
||||
### Duration
|
||||
|
||||
A `spring()` has a natural duration based on the physical properties.
|
||||
To stretch the animation to a specific duration, use the `durationInFrames` parameter.
|
||||
|
||||
```tsx
|
||||
const spring = spring({
|
||||
frame,
|
||||
fps,
|
||||
durationInFrames: 40,
|
||||
});
|
||||
```
|
||||
|
||||
### Combining spring() with interpolate()
|
||||
|
||||
Map spring output (0-1) to custom ranges:
|
||||
|
||||
```tsx
|
||||
const springProgress = spring({
|
||||
frame,
|
||||
fps,
|
||||
});
|
||||
|
||||
// Map to rotation
|
||||
const rotation = interpolate(springProgress, [0, 1], [0, 360]);
|
||||
|
||||
<div style={{rotate: rotation + 'deg'}} />;
|
||||
```
|
||||
|
||||
### Adding springs
|
||||
|
||||
Springs return just numbers, so math can be performed:
|
||||
|
||||
```tsx
|
||||
const frame = useCurrentFrame();
|
||||
const {fps, durationInFrames} = useVideoConfig();
|
||||
|
||||
const inAnimation = spring({
|
||||
frame,
|
||||
fps,
|
||||
});
|
||||
const outAnimation = spring({
|
||||
frame,
|
||||
fps,
|
||||
durationInFrames: 1 * fps,
|
||||
delay: durationInFrames - 1 * fps,
|
||||
});
|
||||
|
||||
const scale = inAnimation - outAnimation;
|
||||
```
|
||||
|
||||
## Easing
|
||||
|
||||
Easing can be added to the `interpolate` function:
|
||||
|
||||
```ts
|
||||
import {interpolate, Easing} from 'remotion';
|
||||
|
||||
const value1 = interpolate(frame, [0, 100], [0, 1], {
|
||||
easing: Easing.inOut(Easing.quad),
|
||||
extrapolateLeft: 'clamp',
|
||||
extrapolateRight: 'clamp',
|
||||
});
|
||||
```
|
||||
|
||||
The default easing is `Easing.linear`.
|
||||
There are various other convexities:
|
||||
|
||||
- `Easing.in` for starting slow and accelerating
|
||||
- `Easing.out` for starting fast and slowing down
|
||||
- `Easing.inOut`
|
||||
|
||||
and curves (sorted from most linear to most curved):
|
||||
|
||||
- `Easing.quad`
|
||||
- `Easing.sin`
|
||||
- `Easing.exp`
|
||||
- `Easing.circle`
|
||||
|
||||
Convexities and curves need be combined for an easing function:
|
||||
|
||||
```ts
|
||||
const value1 = interpolate(frame, [0, 100], [0, 1], {
|
||||
easing: Easing.inOut(Easing.quad),
|
||||
extrapolateLeft: 'clamp',
|
||||
extrapolateRight: 'clamp',
|
||||
});
|
||||
```
|
||||
|
||||
Cubic bezier curves are also supported:
|
||||
|
||||
```ts
|
||||
const value1 = interpolate(frame, [0, 100], [0, 1], {
|
||||
easing: Easing.bezier(0.8, 0.22, 0.96, 0.65),
|
||||
extrapolateLeft: 'clamp',
|
||||
extrapolateRight: 'clamp',
|
||||
});
|
||||
```
|
||||
19
skills/remotion-best-practices/rules/transcribe-captions.md
Normal file
19
skills/remotion-best-practices/rules/transcribe-captions.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: transcribe-captions
|
||||
description: Transcribing audio to generate captions in Remotion
|
||||
metadata:
|
||||
tags: captions, transcribe, whisper, audio, speech-to-text
|
||||
---
|
||||
|
||||
# Transcribing audio
|
||||
|
||||
Remotion provides several built-in options for transcribing audio to generate captions:
|
||||
|
||||
- `@remotion/install-whisper-cpp` - Transcribe locally on a server using Whisper.cpp. Fast and free, but requires server infrastructure.
|
||||
https://remotion.dev/docs/install-whisper-cpp
|
||||
|
||||
- `@remotion/whisper-web` - Transcribe in the browser using WebAssembly. No server needed and free, but slower due to WASM overhead.
|
||||
https://remotion.dev/docs/whisper-web
|
||||
|
||||
- `@remotion/openai-whisper` - Use OpenAI Whisper API for cloud-based transcription. Fast and no server needed, but requires payment.
|
||||
https://remotion.dev/docs/openai-whisper/openai-whisper-api-to-captions
|
||||
122
skills/remotion-best-practices/rules/transitions.md
Normal file
122
skills/remotion-best-practices/rules/transitions.md
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
name: transitions
|
||||
description: Fullscreen scene transitions for Remotion.
|
||||
metadata:
|
||||
tags: transitions, fade, slide, wipe, scenes
|
||||
---
|
||||
|
||||
## Fullscreen transitions
|
||||
|
||||
Using `<TransitionSeries>` to animate between multiple scenes or clips.
|
||||
This will absolutely position the children.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
First, the @remotion/transitions package needs to be installed.
|
||||
If it is not, use the following command:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/transitions # If project uses npm
|
||||
bunx remotion add @remotion/transitions # If project uses bun
|
||||
yarn remotion add @remotion/transitions # If project uses yarn
|
||||
pnpm exec remotion add @remotion/transitions # If project uses pnpm
|
||||
```
|
||||
|
||||
## Example usage
|
||||
|
||||
```tsx
|
||||
import {TransitionSeries, linearTiming} from '@remotion/transitions';
|
||||
import {fade} from '@remotion/transitions/fade';
|
||||
|
||||
<TransitionSeries>
|
||||
<TransitionSeries.Sequence durationInFrames={60}>
|
||||
<SceneA />
|
||||
</TransitionSeries.Sequence>
|
||||
<TransitionSeries.Transition presentation={fade()} timing={linearTiming({durationInFrames: 15})} />
|
||||
<TransitionSeries.Sequence durationInFrames={60}>
|
||||
<SceneB />
|
||||
</TransitionSeries.Sequence>
|
||||
</TransitionSeries>;
|
||||
```
|
||||
|
||||
## Available Transition Types
|
||||
|
||||
Import transitions from their respective modules:
|
||||
|
||||
```tsx
|
||||
import {fade} from '@remotion/transitions/fade';
|
||||
import {slide} from '@remotion/transitions/slide';
|
||||
import {wipe} from '@remotion/transitions/wipe';
|
||||
import {flip} from '@remotion/transitions/flip';
|
||||
import {clockWipe} from '@remotion/transitions/clock-wipe';
|
||||
```
|
||||
|
||||
## Slide Transition with Direction
|
||||
|
||||
Specify slide direction for enter/exit animations.
|
||||
|
||||
```tsx
|
||||
import {slide} from '@remotion/transitions/slide';
|
||||
|
||||
<TransitionSeries.Transition presentation={slide({direction: 'from-left'})} timing={linearTiming({durationInFrames: 20})} />;
|
||||
```
|
||||
|
||||
Directions: `"from-left"`, `"from-right"`, `"from-top"`, `"from-bottom"`
|
||||
|
||||
## Timing Options
|
||||
|
||||
```tsx
|
||||
import {linearTiming, springTiming} from '@remotion/transitions';
|
||||
|
||||
// Linear timing - constant speed
|
||||
linearTiming({durationInFrames: 20});
|
||||
|
||||
// Spring timing - organic motion
|
||||
springTiming({config: {damping: 200}, durationInFrames: 25});
|
||||
```
|
||||
|
||||
## Duration calculation
|
||||
|
||||
Transitions overlap adjacent scenes, so the total composition length is **shorter** than the sum of all sequence durations.
|
||||
|
||||
For example, with two 60-frame sequences and a 15-frame transition:
|
||||
|
||||
- Without transitions: `60 + 60 = 120` frames
|
||||
- With transition: `60 + 60 - 15 = 105` frames
|
||||
|
||||
The transition duration is subtracted because both scenes play simultaneously during the transition.
|
||||
|
||||
### Getting the duration of a transition
|
||||
|
||||
Use the `getDurationInFrames()` method on the timing object:
|
||||
|
||||
```tsx
|
||||
import {linearTiming, springTiming} from '@remotion/transitions';
|
||||
|
||||
const linearDuration = linearTiming({durationInFrames: 20}).getDurationInFrames({fps: 30});
|
||||
// Returns 20
|
||||
|
||||
const springDuration = springTiming({config: {damping: 200}}).getDurationInFrames({fps: 30});
|
||||
// Returns calculated duration based on spring physics
|
||||
```
|
||||
|
||||
For `springTiming` without an explicit `durationInFrames`, the duration depends on `fps` because it calculates when the spring animation settles.
|
||||
|
||||
### Calculating total composition duration
|
||||
|
||||
```tsx
|
||||
import {linearTiming} from '@remotion/transitions';
|
||||
|
||||
const scene1Duration = 60;
|
||||
const scene2Duration = 60;
|
||||
const scene3Duration = 60;
|
||||
|
||||
const timing1 = linearTiming({durationInFrames: 15});
|
||||
const timing2 = linearTiming({durationInFrames: 20});
|
||||
|
||||
const transition1Duration = timing1.getDurationInFrames({fps: 30});
|
||||
const transition2Duration = timing2.getDurationInFrames({fps: 30});
|
||||
|
||||
const totalDuration = scene1Duration + scene2Duration + scene3Duration - transition1Duration - transition2Duration;
|
||||
// 60 + 60 + 60 - 15 - 20 = 145 frames
|
||||
```
|
||||
53
skills/remotion-best-practices/rules/trimming.md
Normal file
53
skills/remotion-best-practices/rules/trimming.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: trimming
|
||||
description: Trimming patterns for Remotion - cut the beginning or end of animations
|
||||
metadata:
|
||||
tags: sequence, trim, clip, cut, offset
|
||||
---
|
||||
|
||||
Use `<Sequence>` with a negative `from` value to trim the start of an animation.
|
||||
|
||||
## Trim the Beginning
|
||||
|
||||
A negative `from` value shifts time backwards, making the animation start partway through:
|
||||
|
||||
```tsx
|
||||
import { Sequence, useVideoConfig } from "remotion";
|
||||
|
||||
const fps = useVideoConfig();
|
||||
|
||||
<Sequence from={-0.5 * fps}>
|
||||
<MyAnimation />
|
||||
</Sequence>
|
||||
```
|
||||
|
||||
The animation appears 15 frames into its progress - the first 15 frames are trimmed off.
|
||||
Inside `<MyAnimation>`, `useCurrentFrame()` starts at 15 instead of 0.
|
||||
|
||||
## Trim the End
|
||||
|
||||
Use `durationInFrames` to unmount content after a specified duration:
|
||||
|
||||
```tsx
|
||||
|
||||
<Sequence durationInFrames={1.5 * fps}>
|
||||
<MyAnimation />
|
||||
</Sequence>
|
||||
```
|
||||
|
||||
The animation plays for 45 frames, then the component unmounts.
|
||||
|
||||
## Trim and Delay
|
||||
|
||||
Nest sequences to both trim the beginning and delay when it appears:
|
||||
|
||||
```tsx
|
||||
<Sequence from={30}>
|
||||
<Sequence from={-15}>
|
||||
<MyAnimation />
|
||||
</Sequence>
|
||||
</Sequence>
|
||||
```
|
||||
|
||||
The inner sequence trims 15 frames from the start, and the outer sequence delays the result by 30 frames.
|
||||
|
||||
171
skills/remotion-best-practices/rules/videos.md
Normal file
171
skills/remotion-best-practices/rules/videos.md
Normal file
@@ -0,0 +1,171 @@
|
||||
---
|
||||
name: videos
|
||||
description: Embedding videos in Remotion - trimming, volume, speed, looping, pitch
|
||||
metadata:
|
||||
tags: video, media, trim, volume, speed, loop, pitch
|
||||
---
|
||||
|
||||
# Using videos in Remotion
|
||||
|
||||
## Prerequisites
|
||||
|
||||
First, the @remotion/media package needs to be installed.
|
||||
If it is not, use the following command:
|
||||
|
||||
```bash
|
||||
npx remotion add @remotion/media # If project uses npm
|
||||
bunx remotion add @remotion/media # If project uses bun
|
||||
yarn remotion add @remotion/media # If project uses yarn
|
||||
pnpm exec remotion add @remotion/media # If project uses pnpm
|
||||
```
|
||||
|
||||
Use `<Video>` from `@remotion/media` to embed videos into your composition.
|
||||
|
||||
```tsx
|
||||
import { Video } from "@remotion/media";
|
||||
import { staticFile } from "remotion";
|
||||
|
||||
export const MyComposition = () => {
|
||||
return <Video src={staticFile("video.mp4")} />;
|
||||
};
|
||||
```
|
||||
|
||||
Remote URLs are also supported:
|
||||
|
||||
```tsx
|
||||
<Video src="https://remotion.media/video.mp4" />
|
||||
```
|
||||
|
||||
## Trimming
|
||||
|
||||
Use `trimBefore` and `trimAfter` to remove portions of the video. Values are in seconds.
|
||||
|
||||
```tsx
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
return (
|
||||
<Video
|
||||
src={staticFile("video.mp4")}
|
||||
trimBefore={2 * fps} // Skip the first 2 seconds
|
||||
trimAfter={10 * fps} // End at the 10 second mark
|
||||
/>
|
||||
);
|
||||
```
|
||||
|
||||
## Delaying
|
||||
|
||||
Wrap the video in a `<Sequence>` to delay when it appears:
|
||||
|
||||
```tsx
|
||||
import { Sequence, staticFile } from "remotion";
|
||||
import { Video } from "@remotion/media";
|
||||
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
return (
|
||||
<Sequence from={1 * fps}>
|
||||
<Video src={staticFile("video.mp4")} />
|
||||
</Sequence>
|
||||
);
|
||||
```
|
||||
|
||||
The video will appear after 1 second.
|
||||
|
||||
## Sizing and Position
|
||||
|
||||
Use the `style` prop to control size and position:
|
||||
|
||||
```tsx
|
||||
<Video
|
||||
src={staticFile("video.mp4")}
|
||||
style={{
|
||||
width: 500,
|
||||
height: 300,
|
||||
position: "absolute",
|
||||
top: 100,
|
||||
left: 50,
|
||||
objectFit: "cover",
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## Volume
|
||||
|
||||
Set a static volume (0 to 1):
|
||||
|
||||
```tsx
|
||||
<Video src={staticFile("video.mp4")} volume={0.5} />
|
||||
```
|
||||
|
||||
Or use a callback for dynamic volume based on the current frame:
|
||||
|
||||
```tsx
|
||||
import { interpolate } from "remotion";
|
||||
|
||||
const { fps } = useVideoConfig();
|
||||
|
||||
return (
|
||||
<Video
|
||||
src={staticFile("video.mp4")}
|
||||
volume={(f) =>
|
||||
interpolate(f, [0, 1 * fps], [0, 1], { extrapolateRight: "clamp" })
|
||||
}
|
||||
/>
|
||||
);
|
||||
```
|
||||
|
||||
Use `muted` to silence the video entirely:
|
||||
|
||||
```tsx
|
||||
<Video src={staticFile("video.mp4")} muted />
|
||||
```
|
||||
|
||||
## Speed
|
||||
|
||||
Use `playbackRate` to change the playback speed:
|
||||
|
||||
```tsx
|
||||
<Video src={staticFile("video.mp4")} playbackRate={2} /> {/* 2x speed */}
|
||||
<Video src={staticFile("video.mp4")} playbackRate={0.5} /> {/* Half speed */}
|
||||
```
|
||||
|
||||
Reverse playback is not supported.
|
||||
|
||||
## Looping
|
||||
|
||||
Use `loop` to loop the video indefinitely:
|
||||
|
||||
```tsx
|
||||
<Video src={staticFile("video.mp4")} loop />
|
||||
```
|
||||
|
||||
Use `loopVolumeCurveBehavior` to control how the frame count behaves when looping:
|
||||
|
||||
- `"repeat"`: Frame count resets to 0 each loop (for `volume` callback)
|
||||
- `"extend"`: Frame count continues incrementing
|
||||
|
||||
```tsx
|
||||
<Video
|
||||
src={staticFile("video.mp4")}
|
||||
loop
|
||||
loopVolumeCurveBehavior="extend"
|
||||
volume={(f) => interpolate(f, [0, 300], [1, 0])} // Fade out over multiple loops
|
||||
/>
|
||||
```
|
||||
|
||||
## Pitch
|
||||
|
||||
Use `toneFrequency` to adjust the pitch without affecting speed. Values range from 0.01 to 2:
|
||||
|
||||
```tsx
|
||||
<Video
|
||||
src={staticFile("video.mp4")}
|
||||
toneFrequency={1.5} // Higher pitch
|
||||
/>
|
||||
<Video
|
||||
src={staticFile("video.mp4")}
|
||||
toneFrequency={0.8} // Lower pitch
|
||||
/>
|
||||
```
|
||||
|
||||
Pitch shifting only works during server-side rendering, not in the Remotion Studio preview or in the `<Player />`.
|
||||
@@ -221,6 +221,12 @@
|
||||
"name": "agent-manager-skill",
|
||||
"description": "Manage multiple local CLI agents via tmux sessions (start/stop/monitor/assign) with cron-friendly scheduling."
|
||||
},
|
||||
{
|
||||
"id": "agent-memory-mcp",
|
||||
"path": "skills/agent-memory-mcp",
|
||||
"name": "agent-memory-mcp",
|
||||
"description": "A hybrid memory system that provides persistent, searchable knowledge management for AI agents (Architecture, Patterns, Decisions)."
|
||||
},
|
||||
{
|
||||
"id": "agent-memory-systems",
|
||||
"path": "skills/agent-memory-systems",
|
||||
@@ -269,6 +275,12 @@
|
||||
"name": "analytics-tracking",
|
||||
"description": "When the user wants to set up, improve, or audit analytics tracking and measurement. Also use when the user mentions \"set up tracking,\" \"GA4,\" \"Google Analytics,\" \"conversion tracking,\" \"event tracking,\" \"UTM parameters,\" \"tag manager,\" \"GTM,\" \"analytics implementation,\" or \"tracking plan.\" For A/B test measurement, see ab-test-setup."
|
||||
},
|
||||
{
|
||||
"id": "api-documentation-generator",
|
||||
"path": "skills/api-documentation-generator",
|
||||
"name": "api-documentation-generator",
|
||||
"description": "\"Generate comprehensive, developer-friendly API documentation from code, including endpoints, parameters, examples, and best practices\""
|
||||
},
|
||||
{
|
||||
"id": "api-patterns",
|
||||
"path": "skills/api-patterns",
|
||||
@@ -323,6 +335,12 @@
|
||||
"name": "backend-dev-guidelines",
|
||||
"description": "Comprehensive backend development guide for Node.js/Express/TypeScript microservices. Use when creating routes, controllers, services, repositories, middleware, or working with Express APIs, Prisma database access, Sentry error tracking, Zod validation, unifiedConfig, dependency injection, or async patterns. Covers layered architecture (routes \u2192 controllers \u2192 services \u2192 repositories), BaseController pattern, error handling, performance monitoring, testing strategies, and migration from legacy patterns."
|
||||
},
|
||||
{
|
||||
"id": "cc-skill-backend-patterns",
|
||||
"path": "skills/cc-skill-backend-patterns",
|
||||
"name": "backend-patterns",
|
||||
"description": "Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes."
|
||||
},
|
||||
{
|
||||
"id": "bash-linux",
|
||||
"path": "skills/bash-linux",
|
||||
@@ -389,6 +407,24 @@
|
||||
"name": "canvas-design",
|
||||
"description": "Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations."
|
||||
},
|
||||
{
|
||||
"id": "cc-skill-continuous-learning",
|
||||
"path": "skills/cc-skill-continuous-learning",
|
||||
"name": "cc-skill-continuous-learning",
|
||||
"description": "Development skill from everything-claude-code"
|
||||
},
|
||||
{
|
||||
"id": "cc-skill-project-guidelines-example",
|
||||
"path": "skills/cc-skill-project-guidelines-example",
|
||||
"name": "cc-skill-project-guidelines-example",
|
||||
"description": "Project Guidelines Skill (Example)"
|
||||
},
|
||||
{
|
||||
"id": "cc-skill-strategic-compact",
|
||||
"path": "skills/cc-skill-strategic-compact",
|
||||
"name": "cc-skill-strategic-compact",
|
||||
"description": "Development skill from everything-claude-code"
|
||||
},
|
||||
{
|
||||
"id": "clean-code",
|
||||
"path": "skills/clean-code",
|
||||
@@ -401,12 +437,24 @@
|
||||
"name": "clerk-auth",
|
||||
"description": "\"Expert patterns for Clerk auth implementation, middleware, organizations, webhooks, and user sync Use when: adding authentication, clerk auth, user authentication, sign in, sign up.\""
|
||||
},
|
||||
{
|
||||
"id": "cc-skill-clickhouse-io",
|
||||
"path": "skills/cc-skill-clickhouse-io",
|
||||
"name": "clickhouse-io",
|
||||
"description": "ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads."
|
||||
},
|
||||
{
|
||||
"id": "code-review-checklist",
|
||||
"path": "skills/code-review-checklist",
|
||||
"name": "code-review-checklist",
|
||||
"description": "Code review guidelines covering code quality, security, and best practices."
|
||||
},
|
||||
{
|
||||
"id": "cc-skill-coding-standards",
|
||||
"path": "skills/cc-skill-coding-standards",
|
||||
"name": "coding-standards",
|
||||
"description": "Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development."
|
||||
},
|
||||
{
|
||||
"id": "competitor-alternatives",
|
||||
"path": "skills/competitor-alternatives",
|
||||
@@ -587,6 +635,12 @@
|
||||
"name": "frontend-dev-guidelines",
|
||||
"description": "Frontend development guidelines for React/TypeScript applications. Modern patterns including Suspense, lazy loading, useSuspenseQuery, file organization with features directory, MUI v7 styling, TanStack Router, performance optimization, and TypeScript best practices. Use when creating components, pages, features, fetching data, styling, routing, or working with frontend code."
|
||||
},
|
||||
{
|
||||
"id": "cc-skill-frontend-patterns",
|
||||
"path": "skills/cc-skill-frontend-patterns",
|
||||
"name": "frontend-patterns",
|
||||
"description": "Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices."
|
||||
},
|
||||
{
|
||||
"id": "game-art",
|
||||
"path": "skills/game-development/game-art",
|
||||
@@ -1007,6 +1061,12 @@
|
||||
"name": "referral-program",
|
||||
"description": "\"When the user wants to create, optimize, or analyze a referral program, affiliate program, or word-of-mouth strategy. Also use when the user mentions 'referral,' 'affiliate,' 'ambassador,' 'word of mouth,' 'viral loop,' 'refer a friend,' or 'partner program.' This skill covers program design, incentive structure, and growth optimization.\""
|
||||
},
|
||||
{
|
||||
"id": "remotion-best-practices",
|
||||
"path": "skills/remotion-best-practices",
|
||||
"name": "remotion-best-practices",
|
||||
"description": "Best practices for Remotion - Video creation in React"
|
||||
},
|
||||
{
|
||||
"id": "requesting-code-review",
|
||||
"path": "skills/requesting-code-review",
|
||||
@@ -1037,6 +1097,12 @@
|
||||
"name": "scroll-experience",
|
||||
"description": "\"Expert in building immersive scroll-driven experiences - parallax storytelling, scroll animations, interactive narratives, and cinematic web experiences. Like NY Times interactives, Apple product pages, and award-winning web experiences. Makes websites feel like experiences, not just pages. Use when: scroll animation, parallax, scroll storytelling, interactive story, cinematic website.\""
|
||||
},
|
||||
{
|
||||
"id": "cc-skill-security-review",
|
||||
"path": "skills/cc-skill-security-review",
|
||||
"name": "security-review",
|
||||
"description": "Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns."
|
||||
},
|
||||
{
|
||||
"id": "segment-cdp",
|
||||
"path": "skills/segment-cdp",
|
||||
|
||||
Reference in New Issue
Block a user