feat: add 33 skills from vudovn/antigravity-kit
- Added: api-patterns, app-builder, architecture, bash-linux, behavioral-modes, clean-code, code-review-checklist, database-design, deployment-procedures, docker-expert, documentation-templates, game-development, geo-fundamentals, i18n-localization, lint-and-validate, mobile-design, nestjs-expert, nextjs-best-practices, nodejs-best-practices, parallel-agents, performance-profiling, plan-writing, powershell-windows, prisma-expert, python-patterns, react-patterns, red-team-tactics, seo-fundamentals, server-management, tailwind-patterns, tdd-workflow, typescript-expert, vulnerability-scanner - Updated README: skill count 179 → 223 - Added credit for vudovn/antigravity-kit (MIT License) Source: https://github.com/vudovn/antigravity-kit
This commit is contained in:
13
README.md
13
README.md
@@ -1,6 +1,6 @@
|
||||
# 🌌 Antigravity Awesome Skills: 179+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
|
||||
# 🌌 Antigravity Awesome Skills: 223+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
|
||||
|
||||
> **The Ultimate Collection of 179+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode**
|
||||
> **The Ultimate Collection of 223+ 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 **179 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
|
||||
**Antigravity Awesome Skills** is a curated, battle-tested library of **223 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
|
||||
|
||||
- 🟣 **Claude Code** (Anthropic CLI)
|
||||
- 🔵 **Gemini CLI** (Google DeepMind)
|
||||
@@ -46,6 +46,7 @@ This repository provides essential skills to transform your AI assistant into a
|
||||
- **[VISUAL_GUIDE.md](docs/VISUAL_GUIDE.md)** - Visual guide with diagrams
|
||||
|
||||
**Quick Start:**
|
||||
|
||||
```bash
|
||||
# 1. Install skills
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
@@ -54,9 +55,10 @@ 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 179 specialized skills. 🎉
|
||||
That's it! Your AI assistant now has 223 specialized skills. 🎉
|
||||
|
||||
**Additional Resources:**
|
||||
|
||||
- 💡 **[Real-World Examples](docs/EXAMPLES.md)** - See skills in action
|
||||
- ❓ **[FAQ](FAQ.md)** - Common questions answered
|
||||
|
||||
@@ -107,7 +109,7 @@ The repository is organized into several key areas of expertise:
|
||||
|
||||
---
|
||||
|
||||
## Full Skill Registry (179/179)
|
||||
## Full Skill Registry (223/223)
|
||||
|
||||
Below is the complete list of available skills. Each skill folder contains a `SKILL.md` that can be imported into Antigravity or Claude Code.
|
||||
|
||||
@@ -358,6 +360,7 @@ This collection would not be possible without the incredible work of the Claude
|
||||
- **[zircote/.claude](https://github.com/zircote/.claude)**: Shopify development skill reference.
|
||||
- **[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).
|
||||
|
||||
### Inspirations
|
||||
|
||||
|
||||
81
skills/api-patterns/SKILL.md
Normal file
81
skills/api-patterns/SKILL.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
name: api-patterns
|
||||
description: API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning, pagination.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# API Patterns
|
||||
|
||||
> API design principles and decision-making for 2025.
|
||||
> **Learn to THINK, not copy fixed patterns.**
|
||||
|
||||
## 🎯 Selective Reading Rule
|
||||
|
||||
**Read ONLY files relevant to the request!** Check the content map, find what you need.
|
||||
|
||||
---
|
||||
|
||||
## 📑 Content Map
|
||||
|
||||
| File | Description | When to Read |
|
||||
|------|-------------|--------------|
|
||||
| `api-style.md` | REST vs GraphQL vs tRPC decision tree | Choosing API type |
|
||||
| `rest.md` | Resource naming, HTTP methods, status codes | Designing REST API |
|
||||
| `response.md` | Envelope pattern, error format, pagination | Response structure |
|
||||
| `graphql.md` | Schema design, when to use, security | Considering GraphQL |
|
||||
| `trpc.md` | TypeScript monorepo, type safety | TS fullstack projects |
|
||||
| `versioning.md` | URI/Header/Query versioning | API evolution planning |
|
||||
| `auth.md` | JWT, OAuth, Passkey, API Keys | Auth pattern selection |
|
||||
| `rate-limiting.md` | Token bucket, sliding window | API protection |
|
||||
| `documentation.md` | OpenAPI/Swagger best practices | Documentation |
|
||||
| `security-testing.md` | OWASP API Top 10, auth/authz testing | Security audits |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Related Skills
|
||||
|
||||
| Need | Skill |
|
||||
|------|-------|
|
||||
| API implementation | `@[skills/backend-development]` |
|
||||
| Data structure | `@[skills/database-design]` |
|
||||
| Security details | `@[skills/security-hardening]` |
|
||||
|
||||
---
|
||||
|
||||
## ✅ Decision Checklist
|
||||
|
||||
Before designing an API:
|
||||
|
||||
- [ ] **Asked user about API consumers?**
|
||||
- [ ] **Chosen API style for THIS context?** (REST/GraphQL/tRPC)
|
||||
- [ ] **Defined consistent response format?**
|
||||
- [ ] **Planned versioning strategy?**
|
||||
- [ ] **Considered authentication needs?**
|
||||
- [ ] **Planned rate limiting?**
|
||||
- [ ] **Documentation approach defined?**
|
||||
|
||||
---
|
||||
|
||||
## ❌ Anti-Patterns
|
||||
|
||||
**DON'T:**
|
||||
- Default to REST for everything
|
||||
- Use verbs in REST endpoints (/getUsers)
|
||||
- Return inconsistent response formats
|
||||
- Expose internal errors to clients
|
||||
- Skip rate limiting
|
||||
|
||||
**DO:**
|
||||
- Choose API style based on context
|
||||
- Ask about client requirements
|
||||
- Document thoroughly
|
||||
- Use appropriate status codes
|
||||
|
||||
---
|
||||
|
||||
## Script
|
||||
|
||||
| Script | Purpose | Command |
|
||||
|--------|---------|---------|
|
||||
| `scripts/api_validator.py` | API endpoint validation | `python scripts/api_validator.py <project_path>` |
|
||||
|
||||
42
skills/api-patterns/api-style.md
Normal file
42
skills/api-patterns/api-style.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# API Style Selection (2025)
|
||||
|
||||
> REST vs GraphQL vs tRPC - Hangi durumda hangisi?
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```
|
||||
Who are the API consumers?
|
||||
│
|
||||
├── Public API / Multiple platforms
|
||||
│ └── REST + OpenAPI (widest compatibility)
|
||||
│
|
||||
├── Complex data needs / Multiple frontends
|
||||
│ └── GraphQL (flexible queries)
|
||||
│
|
||||
├── TypeScript frontend + backend (monorepo)
|
||||
│ └── tRPC (end-to-end type safety)
|
||||
│
|
||||
├── Real-time / Event-driven
|
||||
│ └── WebSocket + AsyncAPI
|
||||
│
|
||||
└── Internal microservices
|
||||
└── gRPC (performance) or REST (simplicity)
|
||||
```
|
||||
|
||||
## Comparison
|
||||
|
||||
| Factor | REST | GraphQL | tRPC |
|
||||
|--------|------|---------|------|
|
||||
| **Best for** | Public APIs | Complex apps | TS monorepos |
|
||||
| **Learning curve** | Low | Medium | Low (if TS) |
|
||||
| **Over/under fetching** | Common | Solved | Solved |
|
||||
| **Type safety** | Manual (OpenAPI) | Schema-based | Automatic |
|
||||
| **Caching** | HTTP native | Complex | Client-based |
|
||||
|
||||
## Selection Questions
|
||||
|
||||
1. Who are the API consumers?
|
||||
2. Is the frontend TypeScript?
|
||||
3. How complex are the data relationships?
|
||||
4. Is caching critical?
|
||||
5. Public or internal API?
|
||||
24
skills/api-patterns/auth.md
Normal file
24
skills/api-patterns/auth.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Authentication Patterns
|
||||
|
||||
> Choose auth pattern based on use case.
|
||||
|
||||
## Selection Guide
|
||||
|
||||
| Pattern | Best For |
|
||||
|---------|----------|
|
||||
| **JWT** | Stateless, microservices |
|
||||
| **Session** | Traditional web, simple |
|
||||
| **OAuth 2.0** | Third-party integration |
|
||||
| **API Keys** | Server-to-server, public APIs |
|
||||
| **Passkey** | Modern passwordless (2025+) |
|
||||
|
||||
## JWT Principles
|
||||
|
||||
```
|
||||
Important:
|
||||
├── Always verify signature
|
||||
├── Check expiration
|
||||
├── Include minimal claims
|
||||
├── Use short expiry + refresh tokens
|
||||
└── Never store sensitive data in JWT
|
||||
```
|
||||
26
skills/api-patterns/documentation.md
Normal file
26
skills/api-patterns/documentation.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# API Documentation Principles
|
||||
|
||||
> Good docs = happy developers = API adoption.
|
||||
|
||||
## OpenAPI/Swagger Essentials
|
||||
|
||||
```
|
||||
Include:
|
||||
├── All endpoints with examples
|
||||
├── Request/response schemas
|
||||
├── Authentication requirements
|
||||
├── Error response formats
|
||||
└── Rate limiting info
|
||||
```
|
||||
|
||||
## Good Documentation Has
|
||||
|
||||
```
|
||||
Essentials:
|
||||
├── Quick start / Getting started
|
||||
├── Authentication guide
|
||||
├── Complete API reference
|
||||
├── Error handling guide
|
||||
├── Code examples (multiple languages)
|
||||
└── Changelog
|
||||
```
|
||||
41
skills/api-patterns/graphql.md
Normal file
41
skills/api-patterns/graphql.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# GraphQL Principles
|
||||
|
||||
> Flexible queries for complex, interconnected data.
|
||||
|
||||
## When to Use
|
||||
|
||||
```
|
||||
✅ Good fit:
|
||||
├── Complex, interconnected data
|
||||
├── Multiple frontend platforms
|
||||
├── Clients need flexible queries
|
||||
├── Evolving data requirements
|
||||
└── Reducing over-fetching matters
|
||||
|
||||
❌ Poor fit:
|
||||
├── Simple CRUD operations
|
||||
├── File upload heavy
|
||||
├── HTTP caching important
|
||||
└── Team unfamiliar with GraphQL
|
||||
```
|
||||
|
||||
## Schema Design Principles
|
||||
|
||||
```
|
||||
Principles:
|
||||
├── Think in graphs, not endpoints
|
||||
├── Design for evolvability (no versions)
|
||||
├── Use connections for pagination
|
||||
├── Be specific with types (not generic "data")
|
||||
└── Handle nullability thoughtfully
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
```
|
||||
Protect against:
|
||||
├── Query depth attacks → Set max depth
|
||||
├── Query complexity → Calculate cost
|
||||
├── Batching abuse → Limit batch size
|
||||
├── Introspection → Disable in production
|
||||
```
|
||||
31
skills/api-patterns/rate-limiting.md
Normal file
31
skills/api-patterns/rate-limiting.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Rate Limiting Principles
|
||||
|
||||
> Protect your API from abuse and overload.
|
||||
|
||||
## Why Rate Limit
|
||||
|
||||
```
|
||||
Protect against:
|
||||
├── Brute force attacks
|
||||
├── Resource exhaustion
|
||||
├── Cost overruns (if pay-per-use)
|
||||
└── Unfair usage
|
||||
```
|
||||
|
||||
## Strategy Selection
|
||||
|
||||
| Type | How | When |
|
||||
|------|-----|------|
|
||||
| **Token bucket** | Burst allowed, refills over time | Most APIs |
|
||||
| **Sliding window** | Smooth distribution | Strict limits |
|
||||
| **Fixed window** | Simple counters per window | Basic needs |
|
||||
|
||||
## Response Headers
|
||||
|
||||
```
|
||||
Include in headers:
|
||||
├── X-RateLimit-Limit (max requests)
|
||||
├── X-RateLimit-Remaining (requests left)
|
||||
├── X-RateLimit-Reset (when limit resets)
|
||||
└── Return 429 when exceeded
|
||||
```
|
||||
37
skills/api-patterns/response.md
Normal file
37
skills/api-patterns/response.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Response Format Principles
|
||||
|
||||
> Consistency is key - choose a format and stick to it.
|
||||
|
||||
## Common Patterns
|
||||
|
||||
```
|
||||
Choose one:
|
||||
├── Envelope pattern ({ success, data, error })
|
||||
├── Direct data (just return the resource)
|
||||
└── HAL/JSON:API (hypermedia)
|
||||
```
|
||||
|
||||
## Error Response
|
||||
|
||||
```
|
||||
Include:
|
||||
├── Error code (for programmatic handling)
|
||||
├── User message (for display)
|
||||
├── Details (for debugging, field-level errors)
|
||||
├── Request ID (for support)
|
||||
└── NOT internal details (security!)
|
||||
```
|
||||
|
||||
## Pagination Types
|
||||
|
||||
| Type | Best For | Trade-offs |
|
||||
|------|----------|------------|
|
||||
| **Offset** | Simple, jumpable | Performance on large datasets |
|
||||
| **Cursor** | Large datasets | Can't jump to page |
|
||||
| **Keyset** | Performance critical | Requires sortable key |
|
||||
|
||||
### Selection Questions
|
||||
|
||||
1. How large is the dataset?
|
||||
2. Do users need to jump to specific pages?
|
||||
3. Is data frequently changing?
|
||||
40
skills/api-patterns/rest.md
Normal file
40
skills/api-patterns/rest.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# REST Principles
|
||||
|
||||
> Resource-based API design - nouns not verbs.
|
||||
|
||||
## Resource Naming Rules
|
||||
|
||||
```
|
||||
Principles:
|
||||
├── Use NOUNS, not verbs (resources, not actions)
|
||||
├── Use PLURAL forms (/users not /user)
|
||||
├── Use lowercase with hyphens (/user-profiles)
|
||||
├── Nest for relationships (/users/123/posts)
|
||||
└── Keep shallow (max 3 levels deep)
|
||||
```
|
||||
|
||||
## HTTP Method Selection
|
||||
|
||||
| Method | Purpose | Idempotent? | Body? |
|
||||
|--------|---------|-------------|-------|
|
||||
| **GET** | Read resource(s) | Yes | No |
|
||||
| **POST** | Create new resource | No | Yes |
|
||||
| **PUT** | Replace entire resource | Yes | Yes |
|
||||
| **PATCH** | Partial update | No | Yes |
|
||||
| **DELETE** | Remove resource | Yes | No |
|
||||
|
||||
## Status Code Selection
|
||||
|
||||
| Situation | Code | Why |
|
||||
|-----------|------|-----|
|
||||
| Success (read) | 200 | Standard success |
|
||||
| Created | 201 | New resource created |
|
||||
| No content | 204 | Success, nothing to return |
|
||||
| Bad request | 400 | Malformed request |
|
||||
| Unauthorized | 401 | Missing/invalid auth |
|
||||
| Forbidden | 403 | Valid auth, no permission |
|
||||
| Not found | 404 | Resource doesn't exist |
|
||||
| Conflict | 409 | State conflict (duplicate) |
|
||||
| Validation error | 422 | Valid syntax, invalid data |
|
||||
| Rate limited | 429 | Too many requests |
|
||||
| Server error | 500 | Our fault |
|
||||
211
skills/api-patterns/scripts/api_validator.py
Normal file
211
skills/api-patterns/scripts/api_validator.py
Normal file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
API Validator - Checks API endpoints for best practices.
|
||||
Validates OpenAPI specs, response formats, and common issues.
|
||||
"""
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
# Fix Windows console encoding for Unicode output
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
|
||||
except AttributeError:
|
||||
pass # Python < 3.7
|
||||
|
||||
def find_api_files(project_path: Path) -> list:
|
||||
"""Find API-related files."""
|
||||
patterns = [
|
||||
"**/*api*.ts", "**/*api*.js", "**/*api*.py",
|
||||
"**/routes/*.ts", "**/routes/*.js", "**/routes/*.py",
|
||||
"**/controllers/*.ts", "**/controllers/*.js",
|
||||
"**/endpoints/*.ts", "**/endpoints/*.py",
|
||||
"**/*.openapi.json", "**/*.openapi.yaml",
|
||||
"**/swagger.json", "**/swagger.yaml",
|
||||
"**/openapi.json", "**/openapi.yaml"
|
||||
]
|
||||
|
||||
files = []
|
||||
for pattern in patterns:
|
||||
files.extend(project_path.glob(pattern))
|
||||
|
||||
# Exclude node_modules, etc.
|
||||
return [f for f in files if not any(x in str(f) for x in ['node_modules', '.git', 'dist', 'build', '__pycache__'])]
|
||||
|
||||
def check_openapi_spec(file_path: Path) -> dict:
|
||||
"""Check OpenAPI/Swagger specification."""
|
||||
issues = []
|
||||
passed = []
|
||||
|
||||
try:
|
||||
content = file_path.read_text(encoding='utf-8')
|
||||
|
||||
if file_path.suffix == '.json':
|
||||
spec = json.loads(content)
|
||||
else:
|
||||
# Basic YAML check
|
||||
if 'openapi:' in content or 'swagger:' in content:
|
||||
passed.append("[OK] OpenAPI/Swagger version defined")
|
||||
else:
|
||||
issues.append("[X] No OpenAPI version found")
|
||||
|
||||
if 'paths:' in content:
|
||||
passed.append("[OK] Paths section exists")
|
||||
else:
|
||||
issues.append("[X] No paths defined")
|
||||
|
||||
if 'components:' in content or 'definitions:' in content:
|
||||
passed.append("[OK] Schema components defined")
|
||||
|
||||
return {'file': str(file_path), 'passed': passed, 'issues': issues, 'type': 'openapi'}
|
||||
|
||||
# JSON OpenAPI checks
|
||||
if 'openapi' in spec or 'swagger' in spec:
|
||||
passed.append("[OK] OpenAPI version defined")
|
||||
|
||||
if 'info' in spec:
|
||||
if 'title' in spec['info']:
|
||||
passed.append("[OK] API title defined")
|
||||
if 'version' in spec['info']:
|
||||
passed.append("[OK] API version defined")
|
||||
if 'description' not in spec['info']:
|
||||
issues.append("[!] API description missing")
|
||||
|
||||
if 'paths' in spec:
|
||||
path_count = len(spec['paths'])
|
||||
passed.append(f"[OK] {path_count} endpoints defined")
|
||||
|
||||
# Check each path
|
||||
for path, methods in spec['paths'].items():
|
||||
for method, details in methods.items():
|
||||
if method in ['get', 'post', 'put', 'patch', 'delete']:
|
||||
if 'responses' not in details:
|
||||
issues.append(f"[X] {method.upper()} {path}: No responses defined")
|
||||
if 'summary' not in details and 'description' not in details:
|
||||
issues.append(f"[!] {method.upper()} {path}: No description")
|
||||
|
||||
except Exception as e:
|
||||
issues.append(f"[X] Parse error: {e}")
|
||||
|
||||
return {'file': str(file_path), 'passed': passed, 'issues': issues, 'type': 'openapi'}
|
||||
|
||||
def check_api_code(file_path: Path) -> dict:
|
||||
"""Check API code for common issues."""
|
||||
issues = []
|
||||
passed = []
|
||||
|
||||
try:
|
||||
content = file_path.read_text(encoding='utf-8')
|
||||
|
||||
# Check for error handling
|
||||
error_patterns = [
|
||||
r'try\s*{', r'try:', r'\.catch\(',
|
||||
r'except\s+', r'catch\s*\('
|
||||
]
|
||||
has_error_handling = any(re.search(p, content) for p in error_patterns)
|
||||
if has_error_handling:
|
||||
passed.append("[OK] Error handling present")
|
||||
else:
|
||||
issues.append("[X] No error handling found")
|
||||
|
||||
# Check for status codes
|
||||
status_patterns = [
|
||||
r'status\s*\(\s*\d{3}\s*\)', r'statusCode\s*[=:]\s*\d{3}',
|
||||
r'HttpStatus\.', r'status_code\s*=\s*\d{3}',
|
||||
r'\.status\(\d{3}\)', r'res\.status\('
|
||||
]
|
||||
has_status = any(re.search(p, content) for p in status_patterns)
|
||||
if has_status:
|
||||
passed.append("[OK] HTTP status codes used")
|
||||
else:
|
||||
issues.append("[!] No explicit HTTP status codes")
|
||||
|
||||
# Check for validation
|
||||
validation_patterns = [
|
||||
r'validate', r'schema', r'zod', r'joi', r'yup',
|
||||
r'pydantic', r'@Body\(', r'@Query\('
|
||||
]
|
||||
has_validation = any(re.search(p, content, re.I) for p in validation_patterns)
|
||||
if has_validation:
|
||||
passed.append("[OK] Input validation present")
|
||||
else:
|
||||
issues.append("[!] No input validation detected")
|
||||
|
||||
# Check for auth middleware
|
||||
auth_patterns = [
|
||||
r'auth', r'jwt', r'bearer', r'token',
|
||||
r'middleware', r'guard', r'@Authenticated'
|
||||
]
|
||||
has_auth = any(re.search(p, content, re.I) for p in auth_patterns)
|
||||
if has_auth:
|
||||
passed.append("[OK] Authentication/authorization detected")
|
||||
|
||||
# Check for rate limiting
|
||||
rate_patterns = [r'rateLimit', r'throttle', r'rate.?limit']
|
||||
has_rate = any(re.search(p, content, re.I) for p in rate_patterns)
|
||||
if has_rate:
|
||||
passed.append("[OK] Rate limiting present")
|
||||
|
||||
# Check for logging
|
||||
log_patterns = [r'console\.log', r'logger\.', r'logging\.', r'log\.']
|
||||
has_logging = any(re.search(p, content) for p in log_patterns)
|
||||
if has_logging:
|
||||
passed.append("[OK] Logging present")
|
||||
|
||||
except Exception as e:
|
||||
issues.append(f"[X] Read error: {e}")
|
||||
|
||||
return {'file': str(file_path), 'passed': passed, 'issues': issues, 'type': 'code'}
|
||||
|
||||
def main():
|
||||
target = sys.argv[1] if len(sys.argv) > 1 else "."
|
||||
project_path = Path(target)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(" API VALIDATOR - Endpoint Best Practices Check")
|
||||
print("=" * 60 + "\n")
|
||||
|
||||
api_files = find_api_files(project_path)
|
||||
|
||||
if not api_files:
|
||||
print("[!] No API files found.")
|
||||
print(" Looking for: routes/, controllers/, api/, openapi.json/yaml")
|
||||
sys.exit(0)
|
||||
|
||||
results = []
|
||||
for file_path in api_files[:15]: # Limit
|
||||
if 'openapi' in file_path.name.lower() or 'swagger' in file_path.name.lower():
|
||||
result = check_openapi_spec(file_path)
|
||||
else:
|
||||
result = check_api_code(file_path)
|
||||
results.append(result)
|
||||
|
||||
# Print results
|
||||
total_issues = 0
|
||||
total_passed = 0
|
||||
|
||||
for result in results:
|
||||
print(f"\n[FILE] {result['file']} [{result['type']}]")
|
||||
for item in result['passed']:
|
||||
print(f" {item}")
|
||||
total_passed += 1
|
||||
for item in result['issues']:
|
||||
print(f" {item}")
|
||||
if item.startswith("[X]"):
|
||||
total_issues += 1
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"[RESULTS] {total_passed} passed, {total_issues} critical issues")
|
||||
print("=" * 60)
|
||||
|
||||
if total_issues == 0:
|
||||
print("[OK] API validation passed")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("[X] Fix critical issues before deployment")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
122
skills/api-patterns/security-testing.md
Normal file
122
skills/api-patterns/security-testing.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# API Security Testing
|
||||
|
||||
> Principles for testing API security. OWASP API Top 10, authentication, authorization testing.
|
||||
|
||||
---
|
||||
|
||||
## OWASP API Security Top 10
|
||||
|
||||
| Vulnerability | Test Focus |
|
||||
|---------------|------------|
|
||||
| **API1: BOLA** | Access other users' resources |
|
||||
| **API2: Broken Auth** | JWT, session, credentials |
|
||||
| **API3: Property Auth** | Mass assignment, data exposure |
|
||||
| **API4: Resource Consumption** | Rate limiting, DoS |
|
||||
| **API5: Function Auth** | Admin endpoints, role bypass |
|
||||
| **API6: Business Flow** | Logic abuse, automation |
|
||||
| **API7: SSRF** | Internal network access |
|
||||
| **API8: Misconfiguration** | Debug endpoints, CORS |
|
||||
| **API9: Inventory** | Shadow APIs, old versions |
|
||||
| **API10: Unsafe Consumption** | Third-party API trust |
|
||||
|
||||
---
|
||||
|
||||
## Authentication Testing
|
||||
|
||||
### JWT Testing
|
||||
|
||||
| Check | What to Test |
|
||||
|-------|--------------|
|
||||
| Algorithm | None, algorithm confusion |
|
||||
| Secret | Weak secrets, brute force |
|
||||
| Claims | Expiration, issuer, audience |
|
||||
| Signature | Manipulation, key injection |
|
||||
|
||||
### Session Testing
|
||||
|
||||
| Check | What to Test |
|
||||
|-------|--------------|
|
||||
| Generation | Predictability |
|
||||
| Storage | Client-side security |
|
||||
| Expiration | Timeout enforcement |
|
||||
| Invalidation | Logout effectiveness |
|
||||
|
||||
---
|
||||
|
||||
## Authorization Testing
|
||||
|
||||
| Test Type | Approach |
|
||||
|-----------|----------|
|
||||
| **Horizontal** | Access peer users' data |
|
||||
| **Vertical** | Access higher privilege functions |
|
||||
| **Context** | Access outside allowed scope |
|
||||
|
||||
### BOLA/IDOR Testing
|
||||
|
||||
1. Identify resource IDs in requests
|
||||
2. Capture request with user A's session
|
||||
3. Replay with user B's session
|
||||
4. Check for unauthorized access
|
||||
|
||||
---
|
||||
|
||||
## Input Validation Testing
|
||||
|
||||
| Injection Type | Test Focus |
|
||||
|----------------|------------|
|
||||
| SQL | Query manipulation |
|
||||
| NoSQL | Document queries |
|
||||
| Command | System commands |
|
||||
| LDAP | Directory queries |
|
||||
|
||||
**Approach:** Test all parameters, try type coercion, test boundaries, check error messages.
|
||||
|
||||
---
|
||||
|
||||
## Rate Limiting Testing
|
||||
|
||||
| Aspect | Check |
|
||||
|--------|-------|
|
||||
| Existence | Is there any limit? |
|
||||
| Bypass | Headers, IP rotation |
|
||||
| Scope | Per-user, per-IP, global |
|
||||
|
||||
**Bypass techniques:** X-Forwarded-For, different HTTP methods, case variations, API versioning.
|
||||
|
||||
---
|
||||
|
||||
## GraphQL Security
|
||||
|
||||
| Test | Focus |
|
||||
|------|-------|
|
||||
| Introspection | Schema disclosure |
|
||||
| Batching | Query DoS |
|
||||
| Nesting | Depth-based DoS |
|
||||
| Authorization | Field-level access |
|
||||
|
||||
---
|
||||
|
||||
## Security Testing Checklist
|
||||
|
||||
**Authentication:**
|
||||
- [ ] Test for bypass
|
||||
- [ ] Check credential strength
|
||||
- [ ] Verify token security
|
||||
|
||||
**Authorization:**
|
||||
- [ ] Test BOLA/IDOR
|
||||
- [ ] Check privilege escalation
|
||||
- [ ] Verify function access
|
||||
|
||||
**Input:**
|
||||
- [ ] Test all parameters
|
||||
- [ ] Check for injection
|
||||
|
||||
**Config:**
|
||||
- [ ] Check CORS
|
||||
- [ ] Verify headers
|
||||
- [ ] Test error handling
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** APIs are the backbone of modern apps. Test them like attackers will.
|
||||
41
skills/api-patterns/trpc.md
Normal file
41
skills/api-patterns/trpc.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# tRPC Principles
|
||||
|
||||
> End-to-end type safety for TypeScript monorepos.
|
||||
|
||||
## When to Use
|
||||
|
||||
```
|
||||
✅ Perfect fit:
|
||||
├── TypeScript on both ends
|
||||
├── Monorepo structure
|
||||
├── Internal tools
|
||||
├── Rapid development
|
||||
└── Type safety critical
|
||||
|
||||
❌ Poor fit:
|
||||
├── Non-TypeScript clients
|
||||
├── Public API
|
||||
├── Need REST conventions
|
||||
└── Multiple language backends
|
||||
```
|
||||
|
||||
## Key Benefits
|
||||
|
||||
```
|
||||
Why tRPC:
|
||||
├── Zero schema maintenance
|
||||
├── End-to-end type inference
|
||||
├── IDE autocomplete across stack
|
||||
├── Instant API changes reflected
|
||||
└── No code generation step
|
||||
```
|
||||
|
||||
## Integration Patterns
|
||||
|
||||
```
|
||||
Common setups:
|
||||
├── Next.js + tRPC (most common)
|
||||
├── Monorepo with shared types
|
||||
├── Remix + tRPC
|
||||
└── Any TS frontend + backend
|
||||
```
|
||||
22
skills/api-patterns/versioning.md
Normal file
22
skills/api-patterns/versioning.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Versioning Strategies
|
||||
|
||||
> Plan for API evolution from day one.
|
||||
|
||||
## Decision Factors
|
||||
|
||||
| Strategy | Implementation | Trade-offs |
|
||||
|----------|---------------|------------|
|
||||
| **URI** | /v1/users | Clear, easy caching |
|
||||
| **Header** | Accept-Version: 1 | Cleaner URLs, harder discovery |
|
||||
| **Query** | ?version=1 | Easy to add, messy |
|
||||
| **None** | Evolve carefully | Best for internal, risky for public |
|
||||
|
||||
## Versioning Philosophy
|
||||
|
||||
```
|
||||
Consider:
|
||||
├── Public API? → Version in URI
|
||||
├── Internal only? → May not need versioning
|
||||
├── GraphQL? → Typically no versions (evolve schema)
|
||||
├── tRPC? → Types enforce compatibility
|
||||
```
|
||||
75
skills/app-builder/SKILL.md
Normal file
75
skills/app-builder/SKILL.md
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
name: app-builder
|
||||
description: Main application building orchestrator. Creates full-stack applications from natural language requests. Determines project type, selects tech stack, coordinates agents.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Agent
|
||||
---
|
||||
|
||||
# App Builder - Application Building Orchestrator
|
||||
|
||||
> Analyzes user's requests, determines tech stack, plans structure, and coordinates agents.
|
||||
|
||||
## 🎯 Selective Reading Rule
|
||||
|
||||
**Read ONLY files relevant to the request!** Check the content map, find what you need.
|
||||
|
||||
| File | Description | When to Read |
|
||||
|------|-------------|--------------|
|
||||
| `project-detection.md` | Keyword matrix, project type detection | Starting new project |
|
||||
| `tech-stack.md` | 2025 default stack, alternatives | Choosing technologies |
|
||||
| `agent-coordination.md` | Agent pipeline, execution order | Coordinating multi-agent work |
|
||||
| `scaffolding.md` | Directory structure, core files | Creating project structure |
|
||||
| `feature-building.md` | Feature analysis, error handling | Adding features to existing project |
|
||||
| `templates/SKILL.md` | **Project templates** | Scaffolding new project |
|
||||
|
||||
---
|
||||
|
||||
## 📦 Templates (13)
|
||||
|
||||
Quick-start scaffolding for new projects. **Read the matching template only!**
|
||||
|
||||
| Template | Tech Stack | When to Use |
|
||||
|----------|------------|-------------|
|
||||
| [nextjs-fullstack](templates/nextjs-fullstack/TEMPLATE.md) | Next.js + Prisma | Full-stack web app |
|
||||
| [nextjs-saas](templates/nextjs-saas/TEMPLATE.md) | Next.js + Stripe | SaaS product |
|
||||
| [nextjs-static](templates/nextjs-static/TEMPLATE.md) | Next.js + Framer | Landing page |
|
||||
| [nuxt-app](templates/nuxt-app/TEMPLATE.md) | Nuxt 3 + Pinia | Vue full-stack app |
|
||||
| [express-api](templates/express-api/TEMPLATE.md) | Express + JWT | REST API |
|
||||
| [python-fastapi](templates/python-fastapi/TEMPLATE.md) | FastAPI | Python API |
|
||||
| [react-native-app](templates/react-native-app/TEMPLATE.md) | Expo + Zustand | Mobile app |
|
||||
| [flutter-app](templates/flutter-app/TEMPLATE.md) | Flutter + Riverpod | Cross-platform mobile |
|
||||
| [electron-desktop](templates/electron-desktop/TEMPLATE.md) | Electron + React | Desktop app |
|
||||
| [chrome-extension](templates/chrome-extension/TEMPLATE.md) | Chrome MV3 | Browser extension |
|
||||
| [cli-tool](templates/cli-tool/TEMPLATE.md) | Node.js + Commander | CLI app |
|
||||
| [monorepo-turborepo](templates/monorepo-turborepo/TEMPLATE.md) | Turborepo + pnpm | Monorepo |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Related Agents
|
||||
|
||||
| Agent | Role |
|
||||
|-------|------|
|
||||
| `project-planner` | Task breakdown, dependency graph |
|
||||
| `frontend-specialist` | UI components, pages |
|
||||
| `backend-specialist` | API, business logic |
|
||||
| `database-architect` | Schema, migrations |
|
||||
| `devops-engineer` | Deployment, preview |
|
||||
|
||||
---
|
||||
|
||||
## Usage Example
|
||||
|
||||
```
|
||||
User: "Make an Instagram clone with photo sharing and likes"
|
||||
|
||||
App Builder Process:
|
||||
1. Project type: Social Media App
|
||||
2. Tech stack: Next.js + Prisma + Cloudinary + Clerk
|
||||
3. Create plan:
|
||||
├─ Database schema (users, posts, likes, follows)
|
||||
├─ API routes (12 endpoints)
|
||||
├─ Pages (feed, profile, upload)
|
||||
└─ Components (PostCard, Feed, LikeButton)
|
||||
4. Coordinate agents
|
||||
5. Report progress
|
||||
6. Start preview
|
||||
```
|
||||
71
skills/app-builder/agent-coordination.md
Normal file
71
skills/app-builder/agent-coordination.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Agent Coordination
|
||||
|
||||
> How App Builder orchestrates specialist agents.
|
||||
|
||||
## Agent Pipeline
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ APP BUILDER (Orchestrator) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ PROJECT PLANNER │
|
||||
│ • Task breakdown │
|
||||
│ • Dependency graph │
|
||||
│ • File structure planning │
|
||||
│ • Create {task-slug}.md in project root (MANDATORY) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ CHECKPOINT: PLAN VERIFICATION │
|
||||
│ 🔴 VERIFY: Does {task-slug}.md exist in project root? │
|
||||
│ 🔴 If NO → STOP → Create plan file first │
|
||||
│ 🔴 If YES → Proceed to specialist agents │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
▼ ▼ ▼
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ DATABASE │ │ BACKEND │ │ FRONTEND │
|
||||
│ ARCHITECT │ │ SPECIALIST │ │ SPECIALIST │
|
||||
│ │ │ │ │ │
|
||||
│ • Schema design │ │ • API routes │ │ • Components │
|
||||
│ • Migrations │ │ • Controllers │ │ • Pages │
|
||||
│ • Seed data │ │ • Middleware │ │ • Styling │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│ │ │
|
||||
└───────────────────┼───────────────────┘
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ PARALLEL PHASE (Optional) │
|
||||
│ • Security Auditor → Vulnerability check │
|
||||
│ • Test Engineer → Unit tests │
|
||||
│ • Performance Optimizer → Bundle analysis │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ DEVOPS ENGINEER │
|
||||
│ • Environment setup │
|
||||
│ • Preview deployment │
|
||||
│ • Health check │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Execution Order
|
||||
|
||||
| Phase | Agent(s) | Parallel? | Prerequisite | CHECKPOINT |
|
||||
|-------|----------|-----------|--------------|------------|
|
||||
| 0 | Socratic Gate | ❌ | - | ✅ Ask 3 questions |
|
||||
| 1 | Project Planner | ❌ | Questions answered | ✅ **PLAN.md created** |
|
||||
| 1.5 | **PLAN VERIFICATION** | ❌ | PLAN.md exists | ✅ **File exists in root** |
|
||||
| 2 | Database Architect | ❌ | Plan ready | Schema defined |
|
||||
| 3 | Backend Specialist | ❌ | Schema ready | API routes created |
|
||||
| 4 | Frontend Specialist | ✅ | API ready (partial) | UI components ready |
|
||||
| 5 | Security Auditor, Test Engineer | ✅ | Code ready | Tests & audit pass |
|
||||
| 6 | DevOps Engineer | ❌ | All code ready | Deployment ready |
|
||||
|
||||
> 🔴 **CRITICAL:** Phase 1.5 is MANDATORY. No specialist agents proceed without PLAN.md verification.
|
||||
53
skills/app-builder/feature-building.md
Normal file
53
skills/app-builder/feature-building.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Feature Building
|
||||
|
||||
> How to analyze and implement new features.
|
||||
|
||||
## Feature Analysis
|
||||
|
||||
```
|
||||
Request: "add payment system"
|
||||
|
||||
Analysis:
|
||||
├── Required Changes:
|
||||
│ ├── Database: orders, payments tables
|
||||
│ ├── Backend: /api/checkout, /api/webhooks/stripe
|
||||
│ ├── Frontend: CheckoutForm, PaymentSuccess
|
||||
│ └── Config: Stripe API keys
|
||||
│
|
||||
├── Dependencies:
|
||||
│ ├── stripe package
|
||||
│ └── Existing user authentication
|
||||
│
|
||||
└── Estimated Time: 15-20 minutes
|
||||
```
|
||||
|
||||
## Iterative Enhancement Process
|
||||
|
||||
```
|
||||
1. Analyze existing project
|
||||
2. Create change plan
|
||||
3. Present plan to user
|
||||
4. Get approval
|
||||
5. Apply changes
|
||||
6. Test
|
||||
7. Show preview
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error Type | Solution Strategy |
|
||||
|------------|-------------------|
|
||||
| TypeScript Error | Fix type, add missing import |
|
||||
| Missing Dependency | Run npm install |
|
||||
| Port Conflict | Suggest alternative port |
|
||||
| Database Error | Check migration, validate connection |
|
||||
|
||||
## Recovery Strategy
|
||||
|
||||
```
|
||||
1. Detect error
|
||||
2. Try automatic fix
|
||||
3. If failed, report to user
|
||||
4. Suggest alternative
|
||||
5. Rollback if necessary
|
||||
```
|
||||
34
skills/app-builder/project-detection.md
Normal file
34
skills/app-builder/project-detection.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Project Type Detection
|
||||
|
||||
> Analyze user requests to determine project type and template.
|
||||
|
||||
## Keyword Matrix
|
||||
|
||||
| Keywords | Project Type | Template |
|
||||
|----------|--------------|----------|
|
||||
| blog, post, article | Blog | astro-static |
|
||||
| e-commerce, product, cart, payment | E-commerce | nextjs-saas |
|
||||
| dashboard, panel, management | Admin Dashboard | nextjs-fullstack |
|
||||
| api, backend, service, rest | API Service | express-api |
|
||||
| python, fastapi, django | Python API | python-fastapi |
|
||||
| mobile, android, ios, react native | Mobile App (RN) | react-native-app |
|
||||
| flutter, dart | Mobile App (Flutter) | flutter-app |
|
||||
| portfolio, personal, cv | Portfolio | nextjs-static |
|
||||
| crm, customer, sales | CRM | nextjs-fullstack |
|
||||
| saas, subscription, stripe | SaaS | nextjs-saas |
|
||||
| landing, promotional, marketing | Landing Page | nextjs-static |
|
||||
| docs, documentation | Documentation | astro-static |
|
||||
| extension, plugin, chrome | Browser Extension | chrome-extension |
|
||||
| desktop, electron | Desktop App | electron-desktop |
|
||||
| cli, command line, terminal | CLI Tool | cli-tool |
|
||||
| monorepo, workspace | Monorepo | monorepo-turborepo |
|
||||
|
||||
## Detection Process
|
||||
|
||||
```
|
||||
1. Tokenize user request
|
||||
2. Extract keywords
|
||||
3. Determine project type
|
||||
4. Detect missing information → forward to conversation-manager
|
||||
5. Suggest tech stack
|
||||
```
|
||||
118
skills/app-builder/scaffolding.md
Normal file
118
skills/app-builder/scaffolding.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Project Scaffolding
|
||||
|
||||
> Directory structure and core files for new projects.
|
||||
|
||||
---
|
||||
|
||||
## Next.js Full-Stack Structure (2025 Optimized)
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── src/
|
||||
│ ├── app/ # Routes only (thin layer)
|
||||
│ │ ├── layout.tsx
|
||||
│ │ ├── page.tsx
|
||||
│ │ ├── globals.css
|
||||
│ │ ├── (auth)/ # Route group - auth pages
|
||||
│ │ │ ├── login/page.tsx
|
||||
│ │ │ └── register/page.tsx
|
||||
│ │ ├── (dashboard)/ # Route group - dashboard layout
|
||||
│ │ │ ├── layout.tsx
|
||||
│ │ │ └── page.tsx
|
||||
│ │ └── api/
|
||||
│ │ └── [resource]/route.ts
|
||||
│ │
|
||||
│ ├── features/ # Feature-based modules
|
||||
│ │ ├── auth/
|
||||
│ │ │ ├── components/
|
||||
│ │ │ ├── hooks/
|
||||
│ │ │ ├── actions.ts # Server Actions
|
||||
│ │ │ ├── queries.ts # Data fetching
|
||||
│ │ │ └── types.ts
|
||||
│ │ ├── products/
|
||||
│ │ │ ├── components/
|
||||
│ │ │ ├── actions.ts
|
||||
│ │ │ └── queries.ts
|
||||
│ │ └── cart/
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ ├── shared/ # Shared utilities
|
||||
│ │ ├── components/ui/ # Reusable UI components
|
||||
│ │ ├── lib/ # Utils, helpers
|
||||
│ │ └── hooks/ # Global hooks
|
||||
│ │
|
||||
│ └── server/ # Server-only code
|
||||
│ ├── db/ # Database client (Prisma)
|
||||
│ ├── auth/ # Auth config
|
||||
│ └── services/ # External API integrations
|
||||
│
|
||||
├── prisma/
|
||||
│ ├── schema.prisma
|
||||
│ ├── migrations/
|
||||
│ └── seed.ts
|
||||
│
|
||||
├── public/
|
||||
├── .env.example
|
||||
├── .env.local
|
||||
├── package.json
|
||||
├── tailwind.config.ts
|
||||
├── tsconfig.json
|
||||
└── README.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Structure Principles
|
||||
|
||||
| Principle | Implementation |
|
||||
|-----------|----------------|
|
||||
| **Feature isolation** | Each feature in `features/` with its own components, hooks, actions |
|
||||
| **Server/Client separation** | Server-only code in `server/`, prevents accidental client imports |
|
||||
| **Thin routes** | `app/` only for routing, logic lives in `features/` |
|
||||
| **Route groups** | `(groupName)/` for layout sharing without URL impact |
|
||||
| **Shared code** | `shared/` for truly reusable UI and utilities |
|
||||
|
||||
---
|
||||
|
||||
## Core Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `package.json` | Dependencies |
|
||||
| `tsconfig.json` | TypeScript + path aliases (`@/features/*`) |
|
||||
| `tailwind.config.ts` | Tailwind config |
|
||||
| `.env.example` | Environment template |
|
||||
| `README.md` | Project documentation |
|
||||
| `.gitignore` | Git ignore rules |
|
||||
| `prisma/schema.prisma` | Database schema |
|
||||
|
||||
---
|
||||
|
||||
## Path Aliases (tsconfig.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@/features/*": ["./src/features/*"],
|
||||
"@/shared/*": ["./src/shared/*"],
|
||||
"@/server/*": ["./src/server/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## When to Use What
|
||||
|
||||
| Need | Location |
|
||||
|------|----------|
|
||||
| New page/route | `app/(group)/page.tsx` |
|
||||
| Feature component | `features/[name]/components/` |
|
||||
| Server action | `features/[name]/actions.ts` |
|
||||
| Data fetching | `features/[name]/queries.ts` |
|
||||
| Reusable button/input | `shared/components/ui/` |
|
||||
| Database query | `server/db/` |
|
||||
| External API call | `server/services/` |
|
||||
40
skills/app-builder/tech-stack.md
Normal file
40
skills/app-builder/tech-stack.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Tech Stack Selection (2025)
|
||||
|
||||
> Default and alternative technology choices for web applications.
|
||||
|
||||
## Default Stack (Web App - 2025)
|
||||
|
||||
```yaml
|
||||
Frontend:
|
||||
framework: Next.js 16 (Stable)
|
||||
language: TypeScript 5.7+
|
||||
styling: Tailwind CSS v4
|
||||
state: React 19 Actions / Server Components
|
||||
bundler: Turbopack (Stable for Dev)
|
||||
|
||||
Backend:
|
||||
runtime: Node.js 23
|
||||
framework: Next.js API Routes / Hono (for Edge)
|
||||
validation: Zod / TypeBox
|
||||
|
||||
Database:
|
||||
primary: PostgreSQL
|
||||
orm: Prisma / Drizzle
|
||||
hosting: Supabase / Neon
|
||||
|
||||
Auth:
|
||||
provider: Auth.js (v5) / Clerk
|
||||
|
||||
Monorepo:
|
||||
tool: Turborepo 2.0
|
||||
```
|
||||
|
||||
## Alternative Options
|
||||
|
||||
| Need | Default | Alternative |
|
||||
|------|---------|-------------|
|
||||
| Real-time | - | Supabase Realtime, Socket.io |
|
||||
| File storage | - | Cloudinary, S3 |
|
||||
| Payment | Stripe | LemonSqueezy, Paddle |
|
||||
| Email | - | Resend, SendGrid |
|
||||
| Search | - | Algolia, Typesense |
|
||||
39
skills/app-builder/templates/SKILL.md
Normal file
39
skills/app-builder/templates/SKILL.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: templates
|
||||
description: Project scaffolding templates for new applications. Use when creating new projects from scratch. Contains 12 templates for various tech stacks.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Project Templates
|
||||
|
||||
> Quick-start templates for scaffolding new projects.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Selective Reading Rule
|
||||
|
||||
**Read ONLY the template matching user's project type!**
|
||||
|
||||
| Template | Tech Stack | When to Use |
|
||||
|----------|------------|-------------|
|
||||
| [nextjs-fullstack](nextjs-fullstack/TEMPLATE.md) | Next.js + Prisma | Full-stack web app |
|
||||
| [nextjs-saas](nextjs-saas/TEMPLATE.md) | Next.js + Stripe | SaaS product |
|
||||
| [nextjs-static](nextjs-static/TEMPLATE.md) | Next.js + Framer | Landing page |
|
||||
| [express-api](express-api/TEMPLATE.md) | Express + JWT | REST API |
|
||||
| [python-fastapi](python-fastapi/TEMPLATE.md) | FastAPI | Python API |
|
||||
| [react-native-app](react-native-app/TEMPLATE.md) | Expo + Zustand | Mobile app |
|
||||
| [flutter-app](flutter-app/TEMPLATE.md) | Flutter + Riverpod | Cross-platform |
|
||||
| [electron-desktop](electron-desktop/TEMPLATE.md) | Electron + React | Desktop app |
|
||||
| [chrome-extension](chrome-extension/TEMPLATE.md) | Chrome MV3 | Browser extension |
|
||||
| [cli-tool](cli-tool/TEMPLATE.md) | Node.js + Commander | CLI app |
|
||||
| [monorepo-turborepo](monorepo-turborepo/TEMPLATE.md) | Turborepo + pnpm | Monorepo |
|
||||
| [astro-static](astro-static/TEMPLATE.md) | Astro + MDX | Blog / Docs |
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
1. User says "create [type] app"
|
||||
2. Match to appropriate template
|
||||
3. Read ONLY that template's TEMPLATE.md
|
||||
4. Follow its tech stack and structure
|
||||
76
skills/app-builder/templates/astro-static/TEMPLATE.md
Normal file
76
skills/app-builder/templates/astro-static/TEMPLATE.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
name: astro-static
|
||||
description: Astro static site template principles. Content-focused websites, blogs, documentation.
|
||||
---
|
||||
|
||||
# Astro Static Site Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | Astro 4.x |
|
||||
| Content | MDX + Content Collections |
|
||||
| Styling | Tailwind CSS |
|
||||
| Integrations | Sitemap, RSS, SEO |
|
||||
| Output | Static/SSG |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── src/
|
||||
│ ├── components/ # .astro components
|
||||
│ ├── content/ # MDX content
|
||||
│ │ ├── blog/
|
||||
│ │ └── config.ts # Collection schemas
|
||||
│ ├── layouts/ # Page layouts
|
||||
│ ├── pages/ # File-based routing
|
||||
│ └── styles/
|
||||
├── public/ # Static assets
|
||||
├── astro.config.mjs
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Concept | Description |
|
||||
|---------|-------------|
|
||||
| Content Collections | Type-safe content with Zod schemas |
|
||||
| Islands Architecture | Partial hydration for interactivity |
|
||||
| Zero JS by default | Static HTML unless needed |
|
||||
| MDX Support | Markdown with components |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `npm create astro@latest {{name}}`
|
||||
2. Add integrations: `npx astro add mdx tailwind sitemap`
|
||||
3. Configure `astro.config.mjs`
|
||||
4. Create content collections
|
||||
5. `npm run dev`
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
| Platform | Method |
|
||||
|----------|--------|
|
||||
| Vercel | Auto-detected |
|
||||
| Netlify | Auto-detected |
|
||||
| Cloudflare Pages | Auto-detected |
|
||||
| GitHub Pages | Build + deploy action |
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use Content Collections for type safety
|
||||
- Leverage static generation
|
||||
- Add islands only where needed
|
||||
- Optimize images with Astro Image
|
||||
92
skills/app-builder/templates/chrome-extension/TEMPLATE.md
Normal file
92
skills/app-builder/templates/chrome-extension/TEMPLATE.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
name: chrome-extension
|
||||
description: Chrome Extension template principles. Manifest V3, React, TypeScript.
|
||||
---
|
||||
|
||||
# Chrome Extension Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Manifest | V3 |
|
||||
| UI | React 18 |
|
||||
| Language | TypeScript |
|
||||
| Styling | Tailwind CSS |
|
||||
| Bundler | Vite |
|
||||
| Storage | Chrome Storage API |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── src/
|
||||
│ ├── popup/ # Extension popup
|
||||
│ ├── options/ # Options page
|
||||
│ ├── background/ # Service worker
|
||||
│ ├── content/ # Content scripts
|
||||
│ ├── components/
|
||||
│ ├── hooks/
|
||||
│ └── lib/
|
||||
│ ├── storage.ts # Chrome storage helpers
|
||||
│ └── messaging.ts # Message passing
|
||||
├── public/
|
||||
│ ├── icons/
|
||||
│ └── manifest.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Manifest V3 Concepts
|
||||
|
||||
| Component | Purpose |
|
||||
|-----------|---------|
|
||||
| Service Worker | Background processing |
|
||||
| Content Scripts | Page injection |
|
||||
| Popup | User interface |
|
||||
| Options Page | Settings |
|
||||
|
||||
---
|
||||
|
||||
## Permissions
|
||||
|
||||
| Permission | Use |
|
||||
|------------|-----|
|
||||
| storage | Save user data |
|
||||
| activeTab | Current tab access |
|
||||
| scripting | Inject scripts |
|
||||
| host_permissions | Site access |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `npm create vite {{name}} -- --template react-ts`
|
||||
2. Add Chrome types: `npm install -D @types/chrome`
|
||||
3. Configure Vite for multi-entry
|
||||
4. Create manifest.json
|
||||
5. `npm run dev` (watch mode)
|
||||
6. Load in Chrome: `chrome://extensions` → Load unpacked
|
||||
|
||||
---
|
||||
|
||||
## Development Tips
|
||||
|
||||
| Task | Method |
|
||||
|------|--------|
|
||||
| Debug Popup | Right-click icon → Inspect |
|
||||
| Debug Background | Extensions page → Service worker |
|
||||
| Debug Content | DevTools console on page |
|
||||
| Hot Reload | `npm run dev` with watch |
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use type-safe messaging
|
||||
- Wrap Chrome APIs in promises
|
||||
- Minimize permissions
|
||||
- Handle offline gracefully
|
||||
88
skills/app-builder/templates/cli-tool/TEMPLATE.md
Normal file
88
skills/app-builder/templates/cli-tool/TEMPLATE.md
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
name: cli-tool
|
||||
description: Node.js CLI tool template principles. Commander.js, interactive prompts.
|
||||
---
|
||||
|
||||
# CLI Tool Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Runtime | Node.js 20+ |
|
||||
| Language | TypeScript |
|
||||
| CLI Framework | Commander.js |
|
||||
| Prompts | Inquirer.js |
|
||||
| Output | chalk + ora |
|
||||
| Config | cosmiconfig |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── src/
|
||||
│ ├── index.ts # Entry point
|
||||
│ ├── cli.ts # CLI setup
|
||||
│ ├── commands/ # Command handlers
|
||||
│ ├── lib/
|
||||
│ │ ├── config.ts # Config loader
|
||||
│ │ └── logger.ts # Styled output
|
||||
│ └── types/
|
||||
├── bin/
|
||||
│ └── cli.js # Executable
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CLI Design Principles
|
||||
|
||||
| Principle | Description |
|
||||
|-----------|-------------|
|
||||
| Subcommands | Group related actions |
|
||||
| Options | Flags with defaults |
|
||||
| Interactive | Prompts when needed |
|
||||
| Non-interactive | Support --yes flags |
|
||||
|
||||
---
|
||||
|
||||
## Key Components
|
||||
|
||||
| Component | Purpose |
|
||||
|-----------|---------|
|
||||
| Commander | Command parsing |
|
||||
| Inquirer | Interactive prompts |
|
||||
| Chalk | Colored output |
|
||||
| Ora | Spinners/loading |
|
||||
| Cosmiconfig | Config file discovery |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. Create project directory
|
||||
2. `npm init -y`
|
||||
3. Install deps: `npm install commander @inquirer/prompts chalk ora cosmiconfig`
|
||||
4. Configure bin in package.json
|
||||
5. `npm link` for local testing
|
||||
|
||||
---
|
||||
|
||||
## Publishing
|
||||
|
||||
```bash
|
||||
npm login
|
||||
npm publish
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Provide helpful error messages
|
||||
- Support both interactive and non-interactive modes
|
||||
- Use consistent output styling
|
||||
- Validate inputs with Zod
|
||||
- Exit with proper codes (0 success, 1 error)
|
||||
88
skills/app-builder/templates/electron-desktop/TEMPLATE.md
Normal file
88
skills/app-builder/templates/electron-desktop/TEMPLATE.md
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
name: electron-desktop
|
||||
description: Electron desktop app template principles. Cross-platform, React, TypeScript.
|
||||
---
|
||||
|
||||
# Electron Desktop App Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | Electron 28+ |
|
||||
| UI | React 18 |
|
||||
| Language | TypeScript |
|
||||
| Styling | Tailwind CSS |
|
||||
| Bundler | Vite + electron-builder |
|
||||
| IPC | Type-safe communication |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── electron/
|
||||
│ ├── main.ts # Main process
|
||||
│ ├── preload.ts # Preload script
|
||||
│ └── ipc/ # IPC handlers
|
||||
├── src/
|
||||
│ ├── App.tsx
|
||||
│ ├── components/
|
||||
│ │ ├── TitleBar.tsx # Custom title bar
|
||||
│ │ └── ...
|
||||
│ └── hooks/
|
||||
├── public/
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Process Model
|
||||
|
||||
| Process | Role |
|
||||
|---------|------|
|
||||
| Main | Node.js, system access |
|
||||
| Renderer | Chromium, React UI |
|
||||
| Preload | Bridge, context isolation |
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Concept | Purpose |
|
||||
|---------|---------|
|
||||
| contextBridge | Safe API exposure |
|
||||
| ipcMain/ipcRenderer | Process communication |
|
||||
| nodeIntegration: false | Security |
|
||||
| contextIsolation: true | Security |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `npm create vite {{name}} -- --template react-ts`
|
||||
2. Install: `npm install -D electron electron-builder vite-plugin-electron`
|
||||
3. Create electron/ directory
|
||||
4. Configure main process
|
||||
5. `npm run electron:dev`
|
||||
|
||||
---
|
||||
|
||||
## Build Targets
|
||||
|
||||
| Platform | Output |
|
||||
|----------|--------|
|
||||
| Windows | NSIS, Portable |
|
||||
| macOS | DMG, ZIP |
|
||||
| Linux | AppImage, DEB |
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use preload script for main/renderer bridge
|
||||
- Type-safe IPC with typed handlers
|
||||
- Custom title bar for native feel
|
||||
- Handle window state (maximize, minimize)
|
||||
- Auto-updates with electron-updater
|
||||
83
skills/app-builder/templates/express-api/TEMPLATE.md
Normal file
83
skills/app-builder/templates/express-api/TEMPLATE.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
name: express-api
|
||||
description: Express.js REST API template principles. TypeScript, Prisma, JWT.
|
||||
---
|
||||
|
||||
# Express.js API Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Runtime | Node.js 20+ |
|
||||
| Framework | Express.js |
|
||||
| Language | TypeScript |
|
||||
| Database | PostgreSQL + Prisma |
|
||||
| Validation | Zod |
|
||||
| Auth | JWT + bcrypt |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── prisma/
|
||||
│ └── schema.prisma
|
||||
├── src/
|
||||
│ ├── app.ts # Express setup
|
||||
│ ├── config/ # Environment
|
||||
│ ├── routes/ # Route handlers
|
||||
│ ├── controllers/ # Business logic
|
||||
│ ├── services/ # Data access
|
||||
│ ├── middleware/
|
||||
│ │ ├── auth.ts # JWT verify
|
||||
│ │ ├── error.ts # Error handler
|
||||
│ │ └── validate.ts # Zod validation
|
||||
│ ├── schemas/ # Zod schemas
|
||||
│ └── utils/
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Middleware Stack
|
||||
|
||||
| Order | Middleware |
|
||||
|-------|------------|
|
||||
| 1 | helmet (security) |
|
||||
| 2 | cors |
|
||||
| 3 | morgan (logging) |
|
||||
| 4 | body parsing |
|
||||
| 5 | routes |
|
||||
| 6 | error handler |
|
||||
|
||||
---
|
||||
|
||||
## API Response Format
|
||||
|
||||
| Type | Structure |
|
||||
|------|-----------|
|
||||
| Success | `{ success: true, data: {...} }` |
|
||||
| Error | `{ error: "message", details: [...] }` |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. Create project directory
|
||||
2. `npm init -y`
|
||||
3. Install deps: `npm install express prisma zod bcrypt jsonwebtoken`
|
||||
4. Configure Prisma
|
||||
5. `npm run db:push`
|
||||
6. `npm run dev`
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Layer architecture (routes → controllers → services)
|
||||
- Validate all inputs with Zod
|
||||
- Centralized error handling
|
||||
- Environment-based config
|
||||
- Use Prisma for type-safe DB access
|
||||
90
skills/app-builder/templates/flutter-app/TEMPLATE.md
Normal file
90
skills/app-builder/templates/flutter-app/TEMPLATE.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
name: flutter-app
|
||||
description: Flutter mobile app template principles. Riverpod, Go Router, clean architecture.
|
||||
---
|
||||
|
||||
# Flutter App Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | Flutter 3.x |
|
||||
| Language | Dart 3.x |
|
||||
| State | Riverpod 2.0 |
|
||||
| Navigation | Go Router |
|
||||
| HTTP | Dio |
|
||||
| Storage | Hive |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project_name/
|
||||
├── lib/
|
||||
│ ├── main.dart
|
||||
│ ├── app.dart
|
||||
│ ├── core/
|
||||
│ │ ├── constants/
|
||||
│ │ ├── theme/
|
||||
│ │ ├── router/
|
||||
│ │ └── utils/
|
||||
│ ├── features/
|
||||
│ │ ├── auth/
|
||||
│ │ │ ├── data/
|
||||
│ │ │ ├── domain/
|
||||
│ │ │ └── presentation/
|
||||
│ │ └── home/
|
||||
│ ├── shared/
|
||||
│ │ ├── widgets/
|
||||
│ │ └── providers/
|
||||
│ └── services/
|
||||
│ ├── api/
|
||||
│ └── storage/
|
||||
├── test/
|
||||
└── pubspec.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architecture Layers
|
||||
|
||||
| Layer | Contents |
|
||||
|-------|----------|
|
||||
| Presentation | Screens, Widgets, Providers |
|
||||
| Domain | Entities, Use Cases |
|
||||
| Data | Repositories, Models |
|
||||
|
||||
---
|
||||
|
||||
## Key Packages
|
||||
|
||||
| Package | Purpose |
|
||||
|---------|---------|
|
||||
| flutter_riverpod | State management |
|
||||
| riverpod_annotation | Code generation |
|
||||
| go_router | Navigation |
|
||||
| dio | HTTP client |
|
||||
| freezed | Immutable models |
|
||||
| hive | Local storage |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `flutter create {{name}} --org com.{{bundle}}`
|
||||
2. Update `pubspec.yaml`
|
||||
3. `flutter pub get`
|
||||
4. Run code generation: `dart run build_runner build`
|
||||
5. `flutter run`
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Feature-first folder structure
|
||||
- Riverpod for state, React Query pattern for server state
|
||||
- Freezed for immutable data classes
|
||||
- Go Router for declarative navigation
|
||||
- Material 3 theming
|
||||
90
skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md
Normal file
90
skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
name: monorepo-turborepo
|
||||
description: Turborepo monorepo template principles. pnpm workspaces, shared packages.
|
||||
---
|
||||
|
||||
# Turborepo Monorepo Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Build System | Turborepo |
|
||||
| Package Manager | pnpm |
|
||||
| Apps | Next.js, Express |
|
||||
| Packages | Shared UI, Config, Types |
|
||||
| Language | TypeScript |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── apps/
|
||||
│ ├── web/ # Next.js app
|
||||
│ ├── api/ # Express API
|
||||
│ └── docs/ # Documentation
|
||||
├── packages/
|
||||
│ ├── ui/ # Shared components
|
||||
│ ├── config/ # ESLint, TS, Tailwind
|
||||
│ ├── types/ # Shared types
|
||||
│ └── utils/ # Shared utilities
|
||||
├── turbo.json
|
||||
├── pnpm-workspace.yaml
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Concept | Description |
|
||||
|---------|-------------|
|
||||
| Workspaces | pnpm-workspace.yaml |
|
||||
| Pipeline | turbo.json task graph |
|
||||
| Caching | Remote/local task caching |
|
||||
| Dependencies | `workspace:*` protocol |
|
||||
|
||||
---
|
||||
|
||||
## Turbo Pipeline
|
||||
|
||||
| Task | Depends On |
|
||||
|------|------------|
|
||||
| build | ^build (dependencies first) |
|
||||
| dev | cache: false, persistent |
|
||||
| lint | ^build |
|
||||
| test | ^build |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. Create root directory
|
||||
2. `pnpm init`
|
||||
3. Create pnpm-workspace.yaml
|
||||
4. Create turbo.json
|
||||
5. Add apps and packages
|
||||
6. `pnpm install`
|
||||
7. `pnpm dev`
|
||||
|
||||
---
|
||||
|
||||
## Common Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `pnpm dev` | Run all apps |
|
||||
| `pnpm build` | Build all |
|
||||
| `pnpm --filter @name/web dev` | Run specific app |
|
||||
| `pnpm --filter @name/web add axios` | Add dep to app |
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Shared configs in packages/config
|
||||
- Shared types in packages/types
|
||||
- Internal packages with `workspace:*`
|
||||
- Use Turbo remote caching for CI
|
||||
82
skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md
Normal file
82
skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: nextjs-fullstack
|
||||
description: Next.js full-stack template principles. App Router, Prisma, Tailwind.
|
||||
---
|
||||
|
||||
# Next.js Full-Stack Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | Next.js 14 (App Router) |
|
||||
| Language | TypeScript |
|
||||
| Database | PostgreSQL + Prisma |
|
||||
| Styling | Tailwind CSS |
|
||||
| Auth | Clerk (optional) |
|
||||
| Validation | Zod |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── prisma/
|
||||
│ └── schema.prisma
|
||||
├── src/
|
||||
│ ├── app/
|
||||
│ │ ├── layout.tsx
|
||||
│ │ ├── page.tsx
|
||||
│ │ ├── globals.css
|
||||
│ │ └── api/
|
||||
│ ├── components/
|
||||
│ │ └── ui/
|
||||
│ ├── lib/
|
||||
│ │ ├── db.ts # Prisma client
|
||||
│ │ └── utils.ts
|
||||
│ └── types/
|
||||
├── .env.example
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Concept | Description |
|
||||
|---------|-------------|
|
||||
| Server Components | Default, fetch data |
|
||||
| Server Actions | Form mutations |
|
||||
| Route Handlers | API endpoints |
|
||||
| Prisma | Type-safe ORM |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| DATABASE_URL | Prisma connection |
|
||||
| NEXT_PUBLIC_APP_URL | Public URL |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `npx create-next-app {{name}} --typescript --tailwind --app`
|
||||
2. `npm install prisma @prisma/client zod`
|
||||
3. `npx prisma init`
|
||||
4. Configure schema
|
||||
5. `npm run db:push`
|
||||
6. `npm run dev`
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Server Components by default
|
||||
- Server Actions for mutations
|
||||
- Prisma for type-safe DB
|
||||
- Zod for validation
|
||||
- Edge runtime where possible
|
||||
100
skills/app-builder/templates/nextjs-saas/TEMPLATE.md
Normal file
100
skills/app-builder/templates/nextjs-saas/TEMPLATE.md
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
name: nextjs-saas
|
||||
description: Next.js SaaS template principles. Auth, payments, email.
|
||||
---
|
||||
|
||||
# Next.js SaaS Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | Next.js 14 (App Router) |
|
||||
| Auth | NextAuth.js v5 |
|
||||
| Payments | Stripe |
|
||||
| Database | PostgreSQL + Prisma |
|
||||
| Email | Resend |
|
||||
| UI | Tailwind (ASK USER: shadcn/Headless UI/Custom?) |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── prisma/
|
||||
├── src/
|
||||
│ ├── app/
|
||||
│ │ ├── (auth)/ # Login, register
|
||||
│ │ ├── (dashboard)/ # Protected routes
|
||||
│ │ ├── (marketing)/ # Landing, pricing
|
||||
│ │ └── api/
|
||||
│ │ ├── auth/[...nextauth]/
|
||||
│ │ └── webhooks/stripe/
|
||||
│ ├── components/
|
||||
│ │ ├── auth/
|
||||
│ │ ├── billing/
|
||||
│ │ └── dashboard/
|
||||
│ ├── lib/
|
||||
│ │ ├── auth.ts # NextAuth config
|
||||
│ │ ├── stripe.ts # Stripe client
|
||||
│ │ └── email.ts # Resend client
|
||||
│ └── config/
|
||||
│ └── subscriptions.ts
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SaaS Features
|
||||
|
||||
| Feature | Implementation |
|
||||
|---------|---------------|
|
||||
| Auth | NextAuth + OAuth |
|
||||
| Subscriptions | Stripe Checkout |
|
||||
| Billing Portal | Stripe Portal |
|
||||
| Webhooks | Stripe events |
|
||||
| Email | Transactional via Resend |
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
| Model | Fields |
|
||||
|-------|--------|
|
||||
| User | id, email, stripeCustomerId, subscriptionId |
|
||||
| Account | OAuth provider data |
|
||||
| Session | User sessions |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| DATABASE_URL | Prisma |
|
||||
| NEXTAUTH_SECRET | Auth |
|
||||
| STRIPE_SECRET_KEY | Payments |
|
||||
| STRIPE_WEBHOOK_SECRET | Webhooks |
|
||||
| RESEND_API_KEY | Email |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `npx create-next-app {{name}} --typescript --tailwind --app`
|
||||
2. Install: `npm install next-auth @auth/prisma-adapter stripe resend`
|
||||
3. Setup Stripe products/prices
|
||||
4. Configure environment
|
||||
5. `npm run db:push`
|
||||
6. `npm run stripe:listen` (webhooks)
|
||||
7. `npm run dev`
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Route groups for layout separation
|
||||
- Stripe webhooks for subscription sync
|
||||
- NextAuth with Prisma adapter
|
||||
- Email templates with React Email
|
||||
106
skills/app-builder/templates/nextjs-static/TEMPLATE.md
Normal file
106
skills/app-builder/templates/nextjs-static/TEMPLATE.md
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
name: nextjs-static
|
||||
description: Next.js static site template principles. Landing pages, portfolios, marketing.
|
||||
---
|
||||
|
||||
# Next.js Static Site Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | Next.js 14 (Static Export) |
|
||||
| Language | TypeScript |
|
||||
| Styling | Tailwind CSS |
|
||||
| Animations | Framer Motion |
|
||||
| Icons | Lucide React |
|
||||
| SEO | Next SEO |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── src/
|
||||
│ ├── app/
|
||||
│ │ ├── layout.tsx
|
||||
│ │ ├── page.tsx # Landing
|
||||
│ │ ├── about/
|
||||
│ │ ├── contact/
|
||||
│ │ └── blog/
|
||||
│ ├── components/
|
||||
│ │ ├── layout/ # Header, Footer
|
||||
│ │ ├── sections/ # Hero, Features, CTA
|
||||
│ │ └── ui/
|
||||
│ └── lib/
|
||||
├── content/ # Markdown content
|
||||
├── public/
|
||||
└── next.config.js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Static Export Config
|
||||
|
||||
```javascript
|
||||
// next.config.js
|
||||
const nextConfig = {
|
||||
output: 'export',
|
||||
images: { unoptimized: true },
|
||||
trailingSlash: true,
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Landing Page Sections
|
||||
|
||||
| Section | Purpose |
|
||||
|---------|---------|
|
||||
| Hero | Main headline, CTA |
|
||||
| Features | Product benefits |
|
||||
| Testimonials | Social proof |
|
||||
| Pricing | Plans |
|
||||
| CTA | Final conversion |
|
||||
|
||||
---
|
||||
|
||||
## Animation Patterns
|
||||
|
||||
| Pattern | Use |
|
||||
|---------|-----|
|
||||
| Fade up | Content entry |
|
||||
| Stagger | List items |
|
||||
| Scroll reveal | On viewport |
|
||||
| Hover | Interactive feedback |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `npx create-next-app {{name}} --typescript --tailwind --app`
|
||||
2. Install: `npm install framer-motion lucide-react next-seo`
|
||||
3. Configure static export
|
||||
4. Create sections
|
||||
5. `npm run dev`
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
| Platform | Method |
|
||||
|----------|--------|
|
||||
| Vercel | Auto |
|
||||
| Netlify | Auto |
|
||||
| GitHub Pages | gh-pages branch |
|
||||
| Any host | Upload `out` folder |
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Static export for maximum performance
|
||||
- Framer Motion for premium animations
|
||||
- Responsive mobile-first design
|
||||
- SEO metadata on every page
|
||||
101
skills/app-builder/templates/nuxt-app/TEMPLATE.md
Normal file
101
skills/app-builder/templates/nuxt-app/TEMPLATE.md
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
name: nuxt-app
|
||||
description: Nuxt 3 full-stack template. Vue 3, Pinia, Tailwind, Prisma.
|
||||
---
|
||||
|
||||
# Nuxt 3 Full-Stack Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | Nuxt 3 |
|
||||
| Language | TypeScript |
|
||||
| UI | Vue 3 (Composition API) |
|
||||
| State | Pinia |
|
||||
| Database | PostgreSQL + Prisma |
|
||||
| Styling | Tailwind CSS |
|
||||
| Validation | Zod |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── prisma/
|
||||
│ └── schema.prisma
|
||||
├── server/
|
||||
│ ├── api/
|
||||
│ │ └── [resource]/
|
||||
│ │ └── index.ts
|
||||
│ └── utils/
|
||||
│ └── db.ts # Prisma client
|
||||
├── composables/
|
||||
│ └── useAuth.ts
|
||||
├── stores/
|
||||
│ └── user.ts # Pinia store
|
||||
├── components/
|
||||
│ └── ui/
|
||||
├── pages/
|
||||
│ ├── index.vue
|
||||
│ └── [...slug].vue
|
||||
├── layouts/
|
||||
│ └── default.vue
|
||||
├── assets/
|
||||
│ └── css/
|
||||
│ └── main.css
|
||||
├── .env.example
|
||||
├── nuxt.config.ts
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Concept | Description |
|
||||
|---------|-------------|
|
||||
| Auto-imports | Components, composables, utils |
|
||||
| File-based routing | pages/ → routes |
|
||||
| Server Routes | server/api/ → API endpoints |
|
||||
| Composables | Reusable reactive logic |
|
||||
| Pinia | State management |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| DATABASE_URL | Prisma connection |
|
||||
| NUXT_PUBLIC_APP_URL | Public URL |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `npx nuxi@latest init {{name}}`
|
||||
2. `cd {{name}}`
|
||||
3. `npm install @pinia/nuxt @prisma/client prisma zod`
|
||||
4. `npm install -D @nuxtjs/tailwindcss`
|
||||
5. Add modules to `nuxt.config.ts`:
|
||||
```ts
|
||||
modules: ['@pinia/nuxt', '@nuxtjs/tailwindcss']
|
||||
```
|
||||
6. `npx prisma init`
|
||||
7. Configure schema
|
||||
8. `npx prisma db push`
|
||||
9. `npm run dev`
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use `<script setup>` for components
|
||||
- Composables for reusable logic
|
||||
- Pinia stores in `stores/` folder
|
||||
- Server routes for API logic
|
||||
- Auto-import for clean code
|
||||
- TypeScript for type safety
|
||||
- See `@[skills/vue-expert]` for Vue patterns
|
||||
83
skills/app-builder/templates/python-fastapi/TEMPLATE.md
Normal file
83
skills/app-builder/templates/python-fastapi/TEMPLATE.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
name: python-fastapi
|
||||
description: FastAPI REST API template principles. SQLAlchemy, Pydantic, Alembic.
|
||||
---
|
||||
|
||||
# FastAPI API Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | FastAPI |
|
||||
| Language | Python 3.11+ |
|
||||
| ORM | SQLAlchemy 2.0 |
|
||||
| Validation | Pydantic v2 |
|
||||
| Migrations | Alembic |
|
||||
| Auth | JWT + passlib |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── alembic/ # Migrations
|
||||
├── app/
|
||||
│ ├── main.py # FastAPI app
|
||||
│ ├── config.py # Settings
|
||||
│ ├── database.py # DB connection
|
||||
│ ├── models/ # SQLAlchemy models
|
||||
│ ├── schemas/ # Pydantic schemas
|
||||
│ ├── routers/ # API routes
|
||||
│ ├── services/ # Business logic
|
||||
│ ├── dependencies/ # DI
|
||||
│ └── utils/
|
||||
├── tests/
|
||||
├── .env.example
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Concept | Description |
|
||||
|---------|-------------|
|
||||
| Async | async/await throughout |
|
||||
| Dependency Injection | FastAPI Depends |
|
||||
| Pydantic v2 | Validation + serialization |
|
||||
| SQLAlchemy 2.0 | Async sessions |
|
||||
|
||||
---
|
||||
|
||||
## API Structure
|
||||
|
||||
| Layer | Responsibility |
|
||||
|-------|---------------|
|
||||
| Routers | HTTP handling |
|
||||
| Dependencies | Auth, validation |
|
||||
| Services | Business logic |
|
||||
| Models | Database entities |
|
||||
| Schemas | Request/response |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `python -m venv venv`
|
||||
2. `source venv/bin/activate`
|
||||
3. `pip install fastapi uvicorn sqlalchemy alembic pydantic`
|
||||
4. Create `.env`
|
||||
5. `alembic upgrade head`
|
||||
6. `uvicorn app.main:app --reload`
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use async everywhere
|
||||
- Pydantic v2 for validation
|
||||
- SQLAlchemy 2.0 async sessions
|
||||
- Alembic for migrations
|
||||
- pytest-asyncio for tests
|
||||
93
skills/app-builder/templates/react-native-app/TEMPLATE.md
Normal file
93
skills/app-builder/templates/react-native-app/TEMPLATE.md
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
name: react-native-app
|
||||
description: React Native mobile app template principles. Expo, TypeScript, navigation.
|
||||
---
|
||||
|
||||
# React Native App Template
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|------------|
|
||||
| Framework | React Native + Expo |
|
||||
| Language | TypeScript |
|
||||
| Navigation | Expo Router |
|
||||
| State | Zustand + React Query |
|
||||
| Styling | NativeWind |
|
||||
| Testing | Jest + RNTL |
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── app/ # Expo Router (file-based)
|
||||
│ ├── _layout.tsx # Root layout
|
||||
│ ├── index.tsx # Home
|
||||
│ ├── (tabs)/ # Tab navigation
|
||||
│ └── [id].tsx # Dynamic route
|
||||
├── components/
|
||||
│ ├── ui/ # Reusable
|
||||
│ └── features/
|
||||
├── hooks/
|
||||
├── lib/
|
||||
│ ├── api.ts
|
||||
│ └── storage.ts
|
||||
├── store/
|
||||
├── constants/
|
||||
└── app.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Navigation Patterns
|
||||
|
||||
| Pattern | Use |
|
||||
|---------|-----|
|
||||
| Stack | Page hierarchy |
|
||||
| Tabs | Bottom navigation |
|
||||
| Drawer | Side menu |
|
||||
| Modal | Overlay screens |
|
||||
|
||||
---
|
||||
|
||||
## State Management
|
||||
|
||||
| Type | Tool |
|
||||
|------|------|
|
||||
| Local | Zustand |
|
||||
| Server | React Query |
|
||||
| Forms | React Hook Form |
|
||||
| Storage | Expo SecureStore |
|
||||
|
||||
---
|
||||
|
||||
## Key Packages
|
||||
|
||||
| Package | Purpose |
|
||||
|---------|---------|
|
||||
| expo-router | File-based routing |
|
||||
| zustand | Local state |
|
||||
| @tanstack/react-query | Server state |
|
||||
| nativewind | Tailwind styling |
|
||||
| expo-secure-store | Secure storage |
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. `npx create-expo-app {{name}} -t expo-template-blank-typescript`
|
||||
2. `npx expo install expo-router react-native-safe-area-context`
|
||||
3. Install state: `npm install zustand @tanstack/react-query`
|
||||
4. `npx expo start`
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Expo Router for navigation
|
||||
- Zustand for local, React Query for server state
|
||||
- NativeWind for consistent styling
|
||||
- Expo SecureStore for tokens
|
||||
- Test on both iOS and Android
|
||||
55
skills/architecture/SKILL.md
Normal file
55
skills/architecture/SKILL.md
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
name: architecture
|
||||
description: Architectural decision-making framework. Requirements analysis, trade-off evaluation, ADR documentation. Use when making architecture decisions or analyzing system design.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Architecture Decision Framework
|
||||
|
||||
> "Requirements drive architecture. Trade-offs inform decisions. ADRs capture rationale."
|
||||
|
||||
## 🎯 Selective Reading Rule
|
||||
|
||||
**Read ONLY files relevant to the request!** Check the content map, find what you need.
|
||||
|
||||
| File | Description | When to Read |
|
||||
|------|-------------|--------------|
|
||||
| `context-discovery.md` | Questions to ask, project classification | Starting architecture design |
|
||||
| `trade-off-analysis.md` | ADR templates, trade-off framework | Documenting decisions |
|
||||
| `pattern-selection.md` | Decision trees, anti-patterns | Choosing patterns |
|
||||
| `examples.md` | MVP, SaaS, Enterprise examples | Reference implementations |
|
||||
| `patterns-reference.md` | Quick lookup for patterns | Pattern comparison |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Related Skills
|
||||
|
||||
| Skill | Use For |
|
||||
|-------|---------|
|
||||
| `@[skills/database-design]` | Database schema design |
|
||||
| `@[skills/api-patterns]` | API design patterns |
|
||||
| `@[skills/deployment-procedures]` | Deployment architecture |
|
||||
|
||||
---
|
||||
|
||||
## Core Principle
|
||||
|
||||
**"Simplicity is the ultimate sophistication."**
|
||||
|
||||
- Start simple
|
||||
- Add complexity ONLY when proven necessary
|
||||
- You can always add patterns later
|
||||
- Removing complexity is MUCH harder than adding it
|
||||
|
||||
---
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
Before finalizing architecture:
|
||||
|
||||
- [ ] Requirements clearly understood
|
||||
- [ ] Constraints identified
|
||||
- [ ] Each decision has trade-off analysis
|
||||
- [ ] Simpler alternatives considered
|
||||
- [ ] ADRs written for significant decisions
|
||||
- [ ] Team expertise matches chosen patterns
|
||||
43
skills/architecture/context-discovery.md
Normal file
43
skills/architecture/context-discovery.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Context Discovery
|
||||
|
||||
> Before suggesting any architecture, gather context.
|
||||
|
||||
## Question Hierarchy (Ask User FIRST)
|
||||
|
||||
1. **Scale**
|
||||
- How many users? (10, 1K, 100K, 1M+)
|
||||
- Data volume? (MB, GB, TB)
|
||||
- Transaction rate? (per second/minute)
|
||||
|
||||
2. **Team**
|
||||
- Solo developer or team?
|
||||
- Team size and expertise?
|
||||
- Distributed or co-located?
|
||||
|
||||
3. **Timeline**
|
||||
- MVP/Prototype or long-term product?
|
||||
- Time to market pressure?
|
||||
|
||||
4. **Domain**
|
||||
- CRUD-heavy or business logic complex?
|
||||
- Real-time requirements?
|
||||
- Compliance/regulations?
|
||||
|
||||
5. **Constraints**
|
||||
- Budget limitations?
|
||||
- Legacy systems to integrate?
|
||||
- Technology stack preferences?
|
||||
|
||||
## Project Classification Matrix
|
||||
|
||||
```
|
||||
MVP SaaS Enterprise
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Scale │ <1K │ 1K-100K │ 100K+ │
|
||||
│ Team │ Solo │ 2-10 │ 10+ │
|
||||
│ Timeline │ Fast (weeks) │ Medium (months)│ Long (years)│
|
||||
│ Architecture │ Simple │ Modular │ Distributed │
|
||||
│ Patterns │ Minimal │ Selective │ Comprehensive│
|
||||
│ Example │ Next.js API │ NestJS │ Microservices│
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
94
skills/architecture/examples.md
Normal file
94
skills/architecture/examples.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Architecture Examples
|
||||
|
||||
> Real-world architecture decisions by project type.
|
||||
|
||||
---
|
||||
|
||||
## Example 1: MVP E-commerce (Solo Developer)
|
||||
|
||||
```yaml
|
||||
Requirements:
|
||||
- <1000 users initially
|
||||
- Solo developer
|
||||
- Fast to market (8 weeks)
|
||||
- Budget-conscious
|
||||
|
||||
Architecture Decisions:
|
||||
App Structure: Monolith (simpler for solo)
|
||||
Framework: Next.js (full-stack, fast)
|
||||
Data Layer: Prisma direct (no over-abstraction)
|
||||
Authentication: JWT (simpler than OAuth)
|
||||
Payment: Stripe (hosted solution)
|
||||
Database: PostgreSQL (ACID for orders)
|
||||
|
||||
Trade-offs Accepted:
|
||||
- Monolith → Can't scale independently (team doesn't justify it)
|
||||
- No Repository → Less testable (simple CRUD doesn't need it)
|
||||
- JWT → No social login initially (can add later)
|
||||
|
||||
Future Migration Path:
|
||||
- Users > 10K → Extract payment service
|
||||
- Team > 3 → Add Repository pattern
|
||||
- Social login requested → Add OAuth
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example 2: SaaS Product (5-10 Developers)
|
||||
|
||||
```yaml
|
||||
Requirements:
|
||||
- 1K-100K users
|
||||
- 5-10 developers
|
||||
- Long-term (12+ months)
|
||||
- Multiple domains (billing, users, core)
|
||||
|
||||
Architecture Decisions:
|
||||
App Structure: Modular Monolith (team size optimal)
|
||||
Framework: NestJS (modular by design)
|
||||
Data Layer: Repository pattern (testing, flexibility)
|
||||
Domain Model: Partial DDD (rich entities)
|
||||
Authentication: OAuth + JWT
|
||||
Caching: Redis
|
||||
Database: PostgreSQL
|
||||
|
||||
Trade-offs Accepted:
|
||||
- Modular Monolith → Some module coupling (microservices not justified)
|
||||
- Partial DDD → No full aggregates (no domain experts)
|
||||
- RabbitMQ later → Initial synchronous (add when proven needed)
|
||||
|
||||
Migration Path:
|
||||
- Team > 10 → Consider microservices
|
||||
- Domains conflict → Extract bounded contexts
|
||||
- Read performance issues → Add CQRS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example 3: Enterprise (100K+ Users)
|
||||
|
||||
```yaml
|
||||
Requirements:
|
||||
- 100K+ users
|
||||
- 10+ developers
|
||||
- Multiple business domains
|
||||
- Different scaling needs
|
||||
- 24/7 availability
|
||||
|
||||
Architecture Decisions:
|
||||
App Structure: Microservices (independent scale)
|
||||
API Gateway: Kong/AWS API GW
|
||||
Domain Model: Full DDD
|
||||
Consistency: Event-driven (eventual OK)
|
||||
Message Bus: Kafka
|
||||
Authentication: OAuth + SAML (enterprise SSO)
|
||||
Database: Polyglot (right tool per job)
|
||||
CQRS: Selected services
|
||||
|
||||
Operational Requirements:
|
||||
- Service mesh (Istio/Linkerd)
|
||||
- Distributed tracing (Jaeger/Tempo)
|
||||
- Centralized logging (ELK/Loki)
|
||||
- Circuit breakers (Resilience4j)
|
||||
- Kubernetes/Helm
|
||||
```
|
||||
68
skills/architecture/pattern-selection.md
Normal file
68
skills/architecture/pattern-selection.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Pattern Selection Guidelines
|
||||
|
||||
> Decision trees for choosing architectural patterns.
|
||||
|
||||
## Main Decision Tree
|
||||
|
||||
```
|
||||
START: What's your MAIN concern?
|
||||
|
||||
┌─ Data Access Complexity?
|
||||
│ ├─ HIGH (complex queries, testing needed)
|
||||
│ │ → Repository Pattern + Unit of Work
|
||||
│ │ VALIDATE: Will data source change frequently?
|
||||
│ │ ├─ YES → Repository worth the indirection
|
||||
│ │ └─ NO → Consider simpler ORM direct access
|
||||
│ └─ LOW (simple CRUD, single database)
|
||||
│ → ORM directly (Prisma, Drizzle)
|
||||
│ Simpler = Better, Faster
|
||||
│
|
||||
├─ Business Rules Complexity?
|
||||
│ ├─ HIGH (domain logic, rules vary by context)
|
||||
│ │ → Domain-Driven Design
|
||||
│ │ VALIDATE: Do you have domain experts on team?
|
||||
│ │ ├─ YES → Full DDD (Aggregates, Value Objects)
|
||||
│ │ └─ NO → Partial DDD (rich entities, clear boundaries)
|
||||
│ └─ LOW (mostly CRUD, simple validation)
|
||||
│ → Transaction Script pattern
|
||||
│ Simpler = Better, Faster
|
||||
│
|
||||
├─ Independent Scaling Needed?
|
||||
│ ├─ YES (different components scale differently)
|
||||
│ │ → Microservices WORTH the complexity
|
||||
│ │ REQUIREMENTS (ALL must be true):
|
||||
│ │ - Clear domain boundaries
|
||||
│ │ - Team > 10 developers
|
||||
│ │ - Different scaling needs per service
|
||||
│ │ IF NOT ALL MET → Modular Monolith instead
|
||||
│ └─ NO (everything scales together)
|
||||
│ → Modular Monolith
|
||||
│ Can extract services later when proven needed
|
||||
│
|
||||
└─ Real-time Requirements?
|
||||
├─ HIGH (immediate updates, multi-user sync)
|
||||
│ → Event-Driven Architecture
|
||||
│ → Message Queue (RabbitMQ, Redis, Kafka)
|
||||
│ VALIDATE: Can you handle eventual consistency?
|
||||
│ ├─ YES → Event-driven valid
|
||||
│ └─ NO → Synchronous with polling
|
||||
└─ LOW (eventual consistency acceptable)
|
||||
→ Synchronous (REST/GraphQL)
|
||||
Simpler = Better, Faster
|
||||
```
|
||||
|
||||
## The 3 Questions (Before ANY Pattern)
|
||||
|
||||
1. **Problem Solved**: What SPECIFIC problem does this pattern solve?
|
||||
2. **Simpler Alternative**: Is there a simpler solution?
|
||||
3. **Deferred Complexity**: Can we add this LATER when needed?
|
||||
|
||||
## Red Flags (Anti-patterns)
|
||||
|
||||
| Pattern | Anti-pattern | Simpler Alternative |
|
||||
|---------|-------------|-------------------|
|
||||
| Microservices | Premature splitting | Start monolith, extract later |
|
||||
| Clean/Hexagonal | Over-abstraction | Concrete first, interfaces later |
|
||||
| Event Sourcing | Over-engineering | Append-only audit log |
|
||||
| CQRS | Unnecessary complexity | Single model |
|
||||
| Repository | YAGNI for simple CRUD | ORM direct access |
|
||||
50
skills/architecture/patterns-reference.md
Normal file
50
skills/architecture/patterns-reference.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Architecture Patterns Reference
|
||||
|
||||
> Quick reference for common patterns with usage guidance.
|
||||
|
||||
## Data Access Patterns
|
||||
|
||||
| Pattern | When to Use | When NOT to Use | Complexity |
|
||||
|---------|-------------|-----------------|------------|
|
||||
| **Active Record** | Simple CRUD, rapid prototyping | Complex queries, multiple sources | Low |
|
||||
| **Repository** | Testing needed, multiple sources | Simple CRUD, single database | Medium |
|
||||
| **Unit of Work** | Complex transactions | Simple operations | High |
|
||||
| **Data Mapper** | Complex domain, performance | Simple CRUD, rapid dev | High |
|
||||
|
||||
## Domain Logic Patterns
|
||||
|
||||
| Pattern | When to Use | When NOT to Use | Complexity |
|
||||
|---------|-------------|-----------------|------------|
|
||||
| **Transaction Script** | Simple CRUD, procedural | Complex business rules | Low |
|
||||
| **Table Module** | Record-based logic | Rich behavior needed | Low |
|
||||
| **Domain Model** | Complex business logic | Simple CRUD | Medium |
|
||||
| **DDD (Full)** | Complex domain, domain experts | Simple domain, no experts | High |
|
||||
|
||||
## Distributed System Patterns
|
||||
|
||||
| Pattern | When to Use | When NOT to Use | Complexity |
|
||||
|---------|-------------|-----------------|------------|
|
||||
| **Modular Monolith** | Small teams, unclear boundaries | Clear contexts, different scales | Medium |
|
||||
| **Microservices** | Different scales, large teams | Small teams, simple domain | Very High |
|
||||
| **Event-Driven** | Real-time, loose coupling | Simple workflows, strong consistency | High |
|
||||
| **CQRS** | Read/write performance diverges | Simple CRUD, same model | High |
|
||||
| **Saga** | Distributed transactions | Single database, simple ACID | High |
|
||||
|
||||
## API Patterns
|
||||
|
||||
| Pattern | When to Use | When NOT to Use | Complexity |
|
||||
|---------|-------------|-----------------|------------|
|
||||
| **REST** | Standard CRUD, resources | Real-time, complex queries | Low |
|
||||
| **GraphQL** | Flexible queries, multiple clients | Simple CRUD, caching needs | Medium |
|
||||
| **gRPC** | Internal services, performance | Public APIs, browser clients | Medium |
|
||||
| **WebSocket** | Real-time updates | Simple request/response | Medium |
|
||||
|
||||
---
|
||||
|
||||
## Simplicity Principle
|
||||
|
||||
**"Start simple, add complexity only when proven necessary."**
|
||||
|
||||
- You can always add patterns later
|
||||
- Removing complexity is MUCH harder than adding it
|
||||
- When in doubt, choose simpler option
|
||||
77
skills/architecture/trade-off-analysis.md
Normal file
77
skills/architecture/trade-off-analysis.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Trade-off Analysis & ADR
|
||||
|
||||
> Document every architectural decision with trade-offs.
|
||||
|
||||
## Decision Framework
|
||||
|
||||
For EACH architectural component, document:
|
||||
|
||||
```markdown
|
||||
## Architecture Decision Record
|
||||
|
||||
### Context
|
||||
- **Problem**: [What problem are we solving?]
|
||||
- **Constraints**: [Team size, scale, timeline, budget]
|
||||
|
||||
### Options Considered
|
||||
|
||||
| Option | Pros | Cons | Complexity | When Valid |
|
||||
|--------|------|------|------------|-----------|
|
||||
| Option A | Benefit 1 | Cost 1 | Low | [Conditions] |
|
||||
| Option B | Benefit 2 | Cost 2 | High | [Conditions] |
|
||||
|
||||
### Decision
|
||||
**Chosen**: [Option B]
|
||||
|
||||
### Rationale
|
||||
1. [Reason 1 - tied to constraints]
|
||||
2. [Reason 2 - tied to requirements]
|
||||
|
||||
### Trade-offs Accepted
|
||||
- [What we're giving up]
|
||||
- [Why this is acceptable]
|
||||
|
||||
### Consequences
|
||||
- **Positive**: [Benefits we gain]
|
||||
- **Negative**: [Costs/risks we accept]
|
||||
- **Mitigation**: [How we'll address negatives]
|
||||
|
||||
### Revisit Trigger
|
||||
- [When to reconsider this decision]
|
||||
```
|
||||
|
||||
## ADR Template
|
||||
|
||||
```markdown
|
||||
# ADR-[XXX]: [Decision Title]
|
||||
|
||||
## Status
|
||||
Proposed | Accepted | Deprecated | Superseded by [ADR-YYY]
|
||||
|
||||
## Context
|
||||
[What problem? What constraints?]
|
||||
|
||||
## Decision
|
||||
[What we chose - be specific]
|
||||
|
||||
## Rationale
|
||||
[Why - tie to requirements and constraints]
|
||||
|
||||
## Trade-offs
|
||||
[What we're giving up - be honest]
|
||||
|
||||
## Consequences
|
||||
- **Positive**: [Benefits]
|
||||
- **Negative**: [Costs]
|
||||
- **Mitigation**: [How to address]
|
||||
```
|
||||
|
||||
## ADR Storage
|
||||
|
||||
```
|
||||
docs/
|
||||
└── architecture/
|
||||
├── adr-001-use-nextjs.md
|
||||
├── adr-002-postgresql-over-mongodb.md
|
||||
└── adr-003-adopt-repository-pattern.md
|
||||
```
|
||||
199
skills/bash-linux/SKILL.md
Normal file
199
skills/bash-linux/SKILL.md
Normal file
@@ -0,0 +1,199 @@
|
||||
---
|
||||
name: bash-linux
|
||||
description: Bash/Linux terminal patterns. Critical commands, piping, error handling, scripting. Use when working on macOS or Linux systems.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# Bash Linux Patterns
|
||||
|
||||
> Essential patterns for Bash on Linux/macOS.
|
||||
|
||||
---
|
||||
|
||||
## 1. Operator Syntax
|
||||
|
||||
### Chaining Commands
|
||||
|
||||
| Operator | Meaning | Example |
|
||||
|----------|---------|---------|
|
||||
| `;` | Run sequentially | `cmd1; cmd2` |
|
||||
| `&&` | Run if previous succeeded | `npm install && npm run dev` |
|
||||
| `\|\|` | Run if previous failed | `npm test \|\| echo "Tests failed"` |
|
||||
| `\|` | Pipe output | `ls \| grep ".js"` |
|
||||
|
||||
---
|
||||
|
||||
## 2. File Operations
|
||||
|
||||
### Essential Commands
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| List all | `ls -la` |
|
||||
| Find files | `find . -name "*.js" -type f` |
|
||||
| File content | `cat file.txt` |
|
||||
| First N lines | `head -n 20 file.txt` |
|
||||
| Last N lines | `tail -n 20 file.txt` |
|
||||
| Follow log | `tail -f log.txt` |
|
||||
| Search in files | `grep -r "pattern" --include="*.js"` |
|
||||
| File size | `du -sh *` |
|
||||
| Disk usage | `df -h` |
|
||||
|
||||
---
|
||||
|
||||
## 3. Process Management
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| List processes | `ps aux` |
|
||||
| Find by name | `ps aux \| grep node` |
|
||||
| Kill by PID | `kill -9 <PID>` |
|
||||
| Find port user | `lsof -i :3000` |
|
||||
| Kill port | `kill -9 $(lsof -t -i :3000)` |
|
||||
| Background | `npm run dev &` |
|
||||
| Jobs | `jobs -l` |
|
||||
| Bring to front | `fg %1` |
|
||||
|
||||
---
|
||||
|
||||
## 4. Text Processing
|
||||
|
||||
### Core Tools
|
||||
|
||||
| Tool | Purpose | Example |
|
||||
|------|---------|---------|
|
||||
| `grep` | Search | `grep -rn "TODO" src/` |
|
||||
| `sed` | Replace | `sed -i 's/old/new/g' file.txt` |
|
||||
| `awk` | Extract columns | `awk '{print $1}' file.txt` |
|
||||
| `cut` | Cut fields | `cut -d',' -f1 data.csv` |
|
||||
| `sort` | Sort lines | `sort -u file.txt` |
|
||||
| `uniq` | Unique lines | `sort file.txt \| uniq -c` |
|
||||
| `wc` | Count | `wc -l file.txt` |
|
||||
|
||||
---
|
||||
|
||||
## 5. Environment Variables
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| View all | `env` or `printenv` |
|
||||
| View one | `echo $PATH` |
|
||||
| Set temporary | `export VAR="value"` |
|
||||
| Set in script | `VAR="value" command` |
|
||||
| Add to PATH | `export PATH="$PATH:/new/path"` |
|
||||
|
||||
---
|
||||
|
||||
## 6. Network
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Download | `curl -O https://example.com/file` |
|
||||
| API request | `curl -X GET https://api.example.com` |
|
||||
| POST JSON | `curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' URL` |
|
||||
| Check port | `nc -zv localhost 3000` |
|
||||
| Network info | `ifconfig` or `ip addr` |
|
||||
|
||||
---
|
||||
|
||||
## 7. Script Template
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -euo pipefail # Exit on error, undefined var, pipe fail
|
||||
|
||||
# Colors (optional)
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Functions
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
|
||||
|
||||
# Main
|
||||
main() {
|
||||
log_info "Starting..."
|
||||
# Your logic here
|
||||
log_info "Done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Common Patterns
|
||||
|
||||
### Check if command exists
|
||||
|
||||
```bash
|
||||
if command -v node &> /dev/null; then
|
||||
echo "Node is installed"
|
||||
fi
|
||||
```
|
||||
|
||||
### Default variable value
|
||||
|
||||
```bash
|
||||
NAME=${1:-"default_value"}
|
||||
```
|
||||
|
||||
### Read file line by line
|
||||
|
||||
```bash
|
||||
while IFS= read -r line; do
|
||||
echo "$line"
|
||||
done < file.txt
|
||||
```
|
||||
|
||||
### Loop over files
|
||||
|
||||
```bash
|
||||
for file in *.js; do
|
||||
echo "Processing $file"
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Differences from PowerShell
|
||||
|
||||
| Task | PowerShell | Bash |
|
||||
|------|------------|------|
|
||||
| List files | `Get-ChildItem` | `ls -la` |
|
||||
| Find files | `Get-ChildItem -Recurse` | `find . -type f` |
|
||||
| Environment | `$env:VAR` | `$VAR` |
|
||||
| String concat | `"$a$b"` | `"$a$b"` (same) |
|
||||
| Null check | `if ($x)` | `if [ -n "$x" ]` |
|
||||
| Pipeline | Object-based | Text-based |
|
||||
|
||||
---
|
||||
|
||||
## 10. Error Handling
|
||||
|
||||
### Set options
|
||||
|
||||
```bash
|
||||
set -e # Exit on error
|
||||
set -u # Exit on undefined variable
|
||||
set -o pipefail # Exit on pipe failure
|
||||
set -x # Debug: print commands
|
||||
```
|
||||
|
||||
### Trap for cleanup
|
||||
|
||||
```bash
|
||||
cleanup() {
|
||||
echo "Cleaning up..."
|
||||
rm -f /tmp/tempfile
|
||||
}
|
||||
trap cleanup EXIT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Bash is text-based. Use `&&` for success chains, `set -e` for safety, and quote your variables!
|
||||
242
skills/behavioral-modes/SKILL.md
Normal file
242
skills/behavioral-modes/SKILL.md
Normal file
@@ -0,0 +1,242 @@
|
||||
---
|
||||
name: behavioral-modes
|
||||
description: AI operational modes (brainstorm, implement, debug, review, teach, ship, orchestrate). Use to adapt behavior based on task type.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Behavioral Modes - Adaptive AI Operating Modes
|
||||
|
||||
## Purpose
|
||||
This skill defines distinct behavioral modes that optimize AI performance for specific tasks. Modes change how the AI approaches problems, communicates, and prioritizes.
|
||||
|
||||
---
|
||||
|
||||
## Available Modes
|
||||
|
||||
### 1. 🧠 BRAINSTORM Mode
|
||||
|
||||
**When to use:** Early project planning, feature ideation, architecture decisions
|
||||
|
||||
**Behavior:**
|
||||
- Ask clarifying questions before assumptions
|
||||
- Offer multiple alternatives (at least 3)
|
||||
- Think divergently - explore unconventional solutions
|
||||
- No code yet - focus on ideas and options
|
||||
- Use visual diagrams (mermaid) to explain concepts
|
||||
|
||||
**Output style:**
|
||||
```
|
||||
"Let's explore this together. Here are some approaches:
|
||||
|
||||
Option A: [description]
|
||||
✅ Pros: ...
|
||||
❌ Cons: ...
|
||||
|
||||
Option B: [description]
|
||||
✅ Pros: ...
|
||||
❌ Cons: ...
|
||||
|
||||
What resonates with you? Or should we explore a different direction?"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. ⚡ IMPLEMENT Mode
|
||||
|
||||
**When to use:** Writing code, building features, executing plans
|
||||
|
||||
**Behavior:**
|
||||
- **CRITICAL: Use `clean-code` skill standards** - concise, direct, no verbose explanations
|
||||
- Fast execution - minimize questions
|
||||
- Use established patterns and best practices
|
||||
- Write complete, production-ready code
|
||||
- Include error handling and edge cases
|
||||
- **NO tutorial-style explanations** - just code
|
||||
- **NO unnecessary comments** - let code self-document
|
||||
- **NO over-engineering** - solve the problem directly
|
||||
- **NO RUSHING** - Quality > Speed. Read ALL references before coding.
|
||||
|
||||
**Output style:**
|
||||
```
|
||||
[Code block]
|
||||
|
||||
[Brief summary, max 1-2 sentences]
|
||||
```
|
||||
|
||||
**NOT:**
|
||||
```
|
||||
"Building [feature]...
|
||||
|
||||
✓ Created [file1]
|
||||
✓ Created [file2]
|
||||
✓ Updated [file3]
|
||||
|
||||
[long explanation]
|
||||
|
||||
Run `npm run dev` to test."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 🔍 DEBUG Mode
|
||||
|
||||
**When to use:** Fixing bugs, troubleshooting errors, investigating issues
|
||||
|
||||
**Behavior:**
|
||||
- Ask for error messages and reproduction steps
|
||||
- Think systematically - check logs, trace data flow
|
||||
- Form hypothesis → test → verify
|
||||
- Explain the root cause, not just the fix
|
||||
- Prevent future occurrences
|
||||
|
||||
**Output style:**
|
||||
```
|
||||
"Investigating...
|
||||
|
||||
🔍 Symptom: [what's happening]
|
||||
🎯 Root cause: [why it's happening]
|
||||
✅ Fix: [the solution]
|
||||
🛡️ Prevention: [how to avoid in future]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. 📋 REVIEW Mode
|
||||
|
||||
**When to use:** Code review, architecture review, security audit
|
||||
|
||||
**Behavior:**
|
||||
- Be thorough but constructive
|
||||
- Categorize by severity (Critical/High/Medium/Low)
|
||||
- Explain the "why" behind suggestions
|
||||
- Offer improved code examples
|
||||
- Acknowledge what's done well
|
||||
|
||||
**Output style:**
|
||||
```
|
||||
## Code Review: [file/feature]
|
||||
|
||||
### 🔴 Critical
|
||||
- [issue with explanation]
|
||||
|
||||
### 🟠 Improvements
|
||||
- [suggestion with example]
|
||||
|
||||
### 🟢 Good
|
||||
- [positive observation]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. 📚 TEACH Mode
|
||||
|
||||
**When to use:** Explaining concepts, documentation, onboarding
|
||||
|
||||
**Behavior:**
|
||||
- Explain from fundamentals
|
||||
- Use analogies and examples
|
||||
- Progress from simple to complex
|
||||
- Include practical exercises
|
||||
- Check understanding
|
||||
|
||||
**Output style:**
|
||||
```
|
||||
## Understanding [Concept]
|
||||
|
||||
### What is it?
|
||||
[Simple explanation with analogy]
|
||||
|
||||
### How it works
|
||||
[Technical explanation with diagram]
|
||||
|
||||
### Example
|
||||
[Code example with comments]
|
||||
|
||||
### Try it yourself
|
||||
[Exercise or task]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. 🚀 SHIP Mode
|
||||
|
||||
**When to use:** Production deployment, final polish, release preparation
|
||||
|
||||
**Behavior:**
|
||||
- Focus on stability over features
|
||||
- Check for missing error handling
|
||||
- Verify environment configs
|
||||
- Run all tests
|
||||
- Create deployment checklist
|
||||
|
||||
**Output style:**
|
||||
```
|
||||
## Pre-Ship Checklist
|
||||
|
||||
### ✅ Code Quality
|
||||
- [ ] No TypeScript errors
|
||||
- [ ] ESLint passing
|
||||
- [ ] All tests passing
|
||||
|
||||
### ✅ Security
|
||||
- [ ] No exposed secrets
|
||||
- [ ] Input validation complete
|
||||
|
||||
### ✅ Performance
|
||||
- [ ] Bundle size acceptable
|
||||
- [ ] No console.logs
|
||||
|
||||
### 🚀 Ready to deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mode Detection
|
||||
|
||||
The AI should automatically detect the appropriate mode based on:
|
||||
|
||||
| Trigger | Mode |
|
||||
|---------|------|
|
||||
| "what if", "ideas", "options" | BRAINSTORM |
|
||||
| "build", "create", "add" | IMPLEMENT |
|
||||
| "not working", "error", "bug" | DEBUG |
|
||||
| "review", "check", "audit" | REVIEW |
|
||||
| "explain", "how does", "learn" | TEACH |
|
||||
| "deploy", "release", "production" | SHIP |
|
||||
|
||||
---
|
||||
|
||||
## Multi-Agent Collaboration Patterns (2025)
|
||||
|
||||
Modern architectures optimized for agent-to-agent collaboration:
|
||||
|
||||
### 1. 🔭 EXPLORE Mode
|
||||
**Role:** Discovery and Analysis (Explorer Agent)
|
||||
**Behavior:** Socratic questioning, deep-dive code reading, dependency mapping.
|
||||
**Output:** `discovery-report.json`, architectural visualization.
|
||||
|
||||
### 2. 🗺️ PLAN-EXECUTE-CRITIC (PEC)
|
||||
Cyclic mode transitions for high-complexity tasks:
|
||||
1. **Planner:** Decomposes the task into atomic steps (`task.md`).
|
||||
2. **Executor:** Performs the actual coding (`IMPLEMENT`).
|
||||
3. **Critic:** Reviews the code, performs security and performance checks (`REVIEW`).
|
||||
|
||||
### 3. 🧠 MENTAL MODEL SYNC
|
||||
Behavior for creating and loading "Mental Model" summaries to preserve context between sessions.
|
||||
|
||||
---
|
||||
|
||||
## Combining Modes
|
||||
|
||||
---
|
||||
|
||||
## Manual Mode Switching
|
||||
|
||||
Users can explicitly request a mode:
|
||||
|
||||
```
|
||||
/brainstorm new feature ideas
|
||||
/implement the user profile page
|
||||
/debug why login fails
|
||||
/review this pull request
|
||||
```
|
||||
201
skills/clean-code/SKILL.md
Normal file
201
skills/clean-code/SKILL.md
Normal file
@@ -0,0 +1,201 @@
|
||||
---
|
||||
name: clean-code
|
||||
description: Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments
|
||||
allowed-tools: Read, Write, Edit
|
||||
version: 2.0
|
||||
priority: CRITICAL
|
||||
---
|
||||
|
||||
# Clean Code - Pragmatic AI Coding Standards
|
||||
|
||||
> **CRITICAL SKILL** - Be **concise, direct, and solution-focused**.
|
||||
|
||||
---
|
||||
|
||||
## Core Principles
|
||||
|
||||
| Principle | Rule |
|
||||
|-----------|------|
|
||||
| **SRP** | Single Responsibility - each function/class does ONE thing |
|
||||
| **DRY** | Don't Repeat Yourself - extract duplicates, reuse |
|
||||
| **KISS** | Keep It Simple - simplest solution that works |
|
||||
| **YAGNI** | You Aren't Gonna Need It - don't build unused features |
|
||||
| **Boy Scout** | Leave code cleaner than you found it |
|
||||
|
||||
---
|
||||
|
||||
## Naming Rules
|
||||
|
||||
| Element | Convention |
|
||||
|---------|------------|
|
||||
| **Variables** | Reveal intent: `userCount` not `n` |
|
||||
| **Functions** | Verb + noun: `getUserById()` not `user()` |
|
||||
| **Booleans** | Question form: `isActive`, `hasPermission`, `canEdit` |
|
||||
| **Constants** | SCREAMING_SNAKE: `MAX_RETRY_COUNT` |
|
||||
|
||||
> **Rule:** If you need a comment to explain a name, rename it.
|
||||
|
||||
---
|
||||
|
||||
## Function Rules
|
||||
|
||||
| Rule | Description |
|
||||
|------|-------------|
|
||||
| **Small** | Max 20 lines, ideally 5-10 |
|
||||
| **One Thing** | Does one thing, does it well |
|
||||
| **One Level** | One level of abstraction per function |
|
||||
| **Few Args** | Max 3 arguments, prefer 0-2 |
|
||||
| **No Side Effects** | Don't mutate inputs unexpectedly |
|
||||
|
||||
---
|
||||
|
||||
## Code Structure
|
||||
|
||||
| Pattern | Apply |
|
||||
|---------|-------|
|
||||
| **Guard Clauses** | Early returns for edge cases |
|
||||
| **Flat > Nested** | Avoid deep nesting (max 2 levels) |
|
||||
| **Composition** | Small functions composed together |
|
||||
| **Colocation** | Keep related code close |
|
||||
|
||||
---
|
||||
|
||||
## AI Coding Style
|
||||
|
||||
| Situation | Action |
|
||||
|-----------|--------|
|
||||
| User asks for feature | Write it directly |
|
||||
| User reports bug | Fix it, don't explain |
|
||||
| No clear requirement | Ask, don't assume |
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns (DON'T)
|
||||
|
||||
| ❌ Pattern | ✅ Fix |
|
||||
|-----------|-------|
|
||||
| Comment every line | Delete obvious comments |
|
||||
| Helper for one-liner | Inline the code |
|
||||
| Factory for 2 objects | Direct instantiation |
|
||||
| utils.ts with 1 function | Put code where used |
|
||||
| "First we import..." | Just write code |
|
||||
| Deep nesting | Guard clauses |
|
||||
| Magic numbers | Named constants |
|
||||
| God functions | Split by responsibility |
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Before Editing ANY File (THINK FIRST!)
|
||||
|
||||
**Before changing a file, ask yourself:**
|
||||
|
||||
| Question | Why |
|
||||
|----------|-----|
|
||||
| **What imports this file?** | They might break |
|
||||
| **What does this file import?** | Interface changes |
|
||||
| **What tests cover this?** | Tests might fail |
|
||||
| **Is this a shared component?** | Multiple places affected |
|
||||
|
||||
**Quick Check:**
|
||||
```
|
||||
File to edit: UserService.ts
|
||||
└── Who imports this? → UserController.ts, AuthController.ts
|
||||
└── Do they need changes too? → Check function signatures
|
||||
```
|
||||
|
||||
> 🔴 **Rule:** Edit the file + all dependent files in the SAME task.
|
||||
> 🔴 **Never leave broken imports or missing updates.**
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Do | Don't |
|
||||
|----|-------|
|
||||
| Write code directly | Write tutorials |
|
||||
| Let code self-document | Add obvious comments |
|
||||
| Fix bugs immediately | Explain the fix first |
|
||||
| Inline small things | Create unnecessary files |
|
||||
| Name things clearly | Use abbreviations |
|
||||
| Keep functions small | Write 100+ line functions |
|
||||
|
||||
> **Remember: The user wants working code, not a programming lesson.**
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Self-Check Before Completing (MANDATORY)
|
||||
|
||||
**Before saying "task complete", verify:**
|
||||
|
||||
| Check | Question |
|
||||
|-------|----------|
|
||||
| ✅ **Goal met?** | Did I do exactly what user asked? |
|
||||
| ✅ **Files edited?** | Did I modify all necessary files? |
|
||||
| ✅ **Code works?** | Did I test/verify the change? |
|
||||
| ✅ **No errors?** | Lint and TypeScript pass? |
|
||||
| ✅ **Nothing forgotten?** | Any edge cases missed? |
|
||||
|
||||
> 🔴 **Rule:** If ANY check fails, fix it before completing.
|
||||
|
||||
---
|
||||
|
||||
## Verification Scripts (MANDATORY)
|
||||
|
||||
> 🔴 **CRITICAL:** Each agent runs ONLY their own skill's scripts after completing work.
|
||||
|
||||
### Agent → Script Mapping
|
||||
|
||||
| Agent | Script | Command |
|
||||
|-------|--------|---------|
|
||||
| **frontend-specialist** | UX Audit | `python ~/.claude/skills/frontend-design/scripts/ux_audit.py .` |
|
||||
| **frontend-specialist** | A11y Check | `python ~/.claude/skills/frontend-design/scripts/accessibility_checker.py .` |
|
||||
| **backend-specialist** | API Validator | `python ~/.claude/skills/api-patterns/scripts/api_validator.py .` |
|
||||
| **mobile-developer** | Mobile Audit | `python ~/.claude/skills/mobile-design/scripts/mobile_audit.py .` |
|
||||
| **database-architect** | Schema Validate | `python ~/.claude/skills/database-design/scripts/schema_validator.py .` |
|
||||
| **security-auditor** | Security Scan | `python ~/.claude/skills/vulnerability-scanner/scripts/security_scan.py .` |
|
||||
| **seo-specialist** | SEO Check | `python ~/.claude/skills/seo-fundamentals/scripts/seo_checker.py .` |
|
||||
| **seo-specialist** | GEO Check | `python ~/.claude/skills/geo-fundamentals/scripts/geo_checker.py .` |
|
||||
| **performance-optimizer** | Lighthouse | `python ~/.claude/skills/performance-profiling/scripts/lighthouse_audit.py <url>` |
|
||||
| **test-engineer** | Test Runner | `python ~/.claude/skills/testing-patterns/scripts/test_runner.py .` |
|
||||
| **test-engineer** | Playwright | `python ~/.claude/skills/webapp-testing/scripts/playwright_runner.py <url>` |
|
||||
| **Any agent** | Lint Check | `python ~/.claude/skills/lint-and-validate/scripts/lint_runner.py .` |
|
||||
| **Any agent** | Type Coverage | `python ~/.claude/skills/lint-and-validate/scripts/type_coverage.py .` |
|
||||
| **Any agent** | i18n Check | `python ~/.claude/skills/i18n-localization/scripts/i18n_checker.py .` |
|
||||
|
||||
> ❌ **WRONG:** `test-engineer` running `ux_audit.py`
|
||||
> ✅ **CORRECT:** `frontend-specialist` running `ux_audit.py`
|
||||
|
||||
---
|
||||
|
||||
### 🔴 Script Output Handling (READ → SUMMARIZE → ASK)
|
||||
|
||||
**When running a validation script, you MUST:**
|
||||
|
||||
1. **Run the script** and capture ALL output
|
||||
2. **Parse the output** - identify errors, warnings, and passes
|
||||
3. **Summarize to user** in this format:
|
||||
|
||||
```markdown
|
||||
## Script Results: [script_name.py]
|
||||
|
||||
### ❌ Errors Found (X items)
|
||||
- [File:Line] Error description 1
|
||||
- [File:Line] Error description 2
|
||||
|
||||
### ⚠️ Warnings (Y items)
|
||||
- [File:Line] Warning description
|
||||
|
||||
### ✅ Passed (Z items)
|
||||
- Check 1 passed
|
||||
- Check 2 passed
|
||||
|
||||
**Should I fix the X errors?**
|
||||
```
|
||||
|
||||
4. **Wait for user confirmation** before fixing
|
||||
5. **After fixing** → Re-run script to confirm
|
||||
|
||||
> 🔴 **VIOLATION:** Running script and ignoring output = FAILED task.
|
||||
> 🔴 **VIOLATION:** Auto-fixing without asking = Not allowed.
|
||||
> 🔴 **Rule:** Always READ output → SUMMARIZE → ASK → then fix.
|
||||
|
||||
109
skills/code-review-checklist/SKILL.md
Normal file
109
skills/code-review-checklist/SKILL.md
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
name: code-review-checklist
|
||||
description: Code review guidelines covering code quality, security, and best practices.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Code Review Checklist
|
||||
|
||||
## Quick Review Checklist
|
||||
|
||||
### Correctness
|
||||
- [ ] Code does what it's supposed to do
|
||||
- [ ] Edge cases handled
|
||||
- [ ] Error handling in place
|
||||
- [ ] No obvious bugs
|
||||
|
||||
### Security
|
||||
- [ ] Input validated and sanitized
|
||||
- [ ] No SQL/NoSQL injection vulnerabilities
|
||||
- [ ] No XSS or CSRF vulnerabilities
|
||||
- [ ] No hardcoded secrets or sensitive credentials
|
||||
- [ ] **AI-Specific:** Protection against Prompt Injection (if applicable)
|
||||
- [ ] **AI-Specific:** Outputs are sanitized before being used in critical sinks
|
||||
|
||||
### Performance
|
||||
- [ ] No N+1 queries
|
||||
- [ ] No unnecessary loops
|
||||
- [ ] Appropriate caching
|
||||
- [ ] Bundle size impact considered
|
||||
|
||||
### Code Quality
|
||||
- [ ] Clear naming
|
||||
- [ ] DRY - no duplicate code
|
||||
- [ ] SOLID principles followed
|
||||
- [ ] Appropriate abstraction level
|
||||
|
||||
### Testing
|
||||
- [ ] Unit tests for new code
|
||||
- [ ] Edge cases tested
|
||||
- [ ] Tests readable and maintainable
|
||||
|
||||
### Documentation
|
||||
- [ ] Complex logic commented
|
||||
- [ ] Public APIs documented
|
||||
- [ ] README updated if needed
|
||||
|
||||
## AI & LLM Review Patterns (2025)
|
||||
|
||||
### Logic & Hallucinations
|
||||
- [ ] **Chain of Thought:** Does the logic follow a verifiable path?
|
||||
- [ ] **Edge Cases:** Did the AI account for empty states, timeouts, and partial failures?
|
||||
- [ ] **External State:** Is the code making safe assumptions about file systems or networks?
|
||||
|
||||
### Prompt Engineering Review
|
||||
```markdown
|
||||
// ❌ Vague prompt in code
|
||||
const response = await ai.generate(userInput);
|
||||
|
||||
// ✅ Structured & Safe prompt
|
||||
const response = await ai.generate({
|
||||
system: "You are a specialized parser...",
|
||||
input: sanitize(userInput),
|
||||
schema: ResponseSchema
|
||||
});
|
||||
```
|
||||
|
||||
## Anti-Patterns to Flag
|
||||
|
||||
```typescript
|
||||
// ❌ Magic numbers
|
||||
if (status === 3) { ... }
|
||||
|
||||
// ✅ Named constants
|
||||
if (status === Status.ACTIVE) { ... }
|
||||
|
||||
// ❌ Deep nesting
|
||||
if (a) { if (b) { if (c) { ... } } }
|
||||
|
||||
// ✅ Early returns
|
||||
if (!a) return;
|
||||
if (!b) return;
|
||||
if (!c) return;
|
||||
// do work
|
||||
|
||||
// ❌ Long functions (100+ lines)
|
||||
// ✅ Small, focused functions
|
||||
|
||||
// ❌ any type
|
||||
const data: any = ...
|
||||
|
||||
// ✅ Proper types
|
||||
const data: UserData = ...
|
||||
```
|
||||
|
||||
## Review Comments Guide
|
||||
|
||||
```
|
||||
// Blocking issues use 🔴
|
||||
🔴 BLOCKING: SQL injection vulnerability here
|
||||
|
||||
// Important suggestions use 🟡
|
||||
🟡 SUGGESTION: Consider using useMemo for performance
|
||||
|
||||
// Minor nits use 🟢
|
||||
🟢 NIT: Prefer const over let for immutable variable
|
||||
|
||||
// Questions use ❓
|
||||
❓ QUESTION: What happens if user is null here?
|
||||
```
|
||||
52
skills/database-design/SKILL.md
Normal file
52
skills/database-design/SKILL.md
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: database-design
|
||||
description: Database design principles and decision-making. Schema design, indexing strategy, ORM selection, serverless databases.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# Database Design
|
||||
|
||||
> **Learn to THINK, not copy SQL patterns.**
|
||||
|
||||
## 🎯 Selective Reading Rule
|
||||
|
||||
**Read ONLY files relevant to the request!** Check the content map, find what you need.
|
||||
|
||||
| File | Description | When to Read |
|
||||
|------|-------------|--------------|
|
||||
| `database-selection.md` | PostgreSQL vs Neon vs Turso vs SQLite | Choosing database |
|
||||
| `orm-selection.md` | Drizzle vs Prisma vs Kysely | Choosing ORM |
|
||||
| `schema-design.md` | Normalization, PKs, relationships | Designing schema |
|
||||
| `indexing.md` | Index types, composite indexes | Performance tuning |
|
||||
| `optimization.md` | N+1, EXPLAIN ANALYZE | Query optimization |
|
||||
| `migrations.md` | Safe migrations, serverless DBs | Schema changes |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Core Principle
|
||||
|
||||
- ASK user for database preferences when unclear
|
||||
- Choose database/ORM based on CONTEXT
|
||||
- Don't default to PostgreSQL for everything
|
||||
|
||||
---
|
||||
|
||||
## Decision Checklist
|
||||
|
||||
Before designing schema:
|
||||
|
||||
- [ ] Asked user about database preference?
|
||||
- [ ] Chosen database for THIS context?
|
||||
- [ ] Considered deployment environment?
|
||||
- [ ] Planned index strategy?
|
||||
- [ ] Defined relationship types?
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
❌ Default to PostgreSQL for simple apps (SQLite may suffice)
|
||||
❌ Skip indexing
|
||||
❌ Use SELECT * in production
|
||||
❌ Store JSON when structured data is better
|
||||
❌ Ignore N+1 queries
|
||||
43
skills/database-design/database-selection.md
Normal file
43
skills/database-design/database-selection.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Database Selection (2025)
|
||||
|
||||
> Choose database based on context, not default.
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```
|
||||
What are your requirements?
|
||||
│
|
||||
├── Full relational features needed
|
||||
│ ├── Self-hosted → PostgreSQL
|
||||
│ └── Serverless → Neon, Supabase
|
||||
│
|
||||
├── Edge deployment / Ultra-low latency
|
||||
│ └── Turso (edge SQLite)
|
||||
│
|
||||
├── AI / Vector search
|
||||
│ └── PostgreSQL + pgvector
|
||||
│
|
||||
├── Simple / Embedded / Local
|
||||
│ └── SQLite
|
||||
│
|
||||
└── Global distribution
|
||||
└── PlanetScale, CockroachDB, Turso
|
||||
```
|
||||
|
||||
## Comparison
|
||||
|
||||
| Database | Best For | Trade-offs |
|
||||
|----------|----------|------------|
|
||||
| **PostgreSQL** | Full features, complex queries | Needs hosting |
|
||||
| **Neon** | Serverless PG, branching | PG complexity |
|
||||
| **Turso** | Edge, low latency | SQLite limitations |
|
||||
| **SQLite** | Simple, embedded, local | Single-writer |
|
||||
| **PlanetScale** | MySQL, global scale | No foreign keys |
|
||||
|
||||
## Questions to Ask
|
||||
|
||||
1. What's the deployment environment?
|
||||
2. How complex are the queries?
|
||||
3. Is edge/serverless important?
|
||||
4. Vector search needed?
|
||||
5. Global distribution required?
|
||||
39
skills/database-design/indexing.md
Normal file
39
skills/database-design/indexing.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Indexing Principles
|
||||
|
||||
> When and how to create indexes effectively.
|
||||
|
||||
## When to Create Indexes
|
||||
|
||||
```
|
||||
Index these:
|
||||
├── Columns in WHERE clauses
|
||||
├── Columns in JOIN conditions
|
||||
├── Columns in ORDER BY
|
||||
├── Foreign key columns
|
||||
└── Unique constraints
|
||||
|
||||
Don't over-index:
|
||||
├── Write-heavy tables (slower inserts)
|
||||
├── Low-cardinality columns
|
||||
├── Columns rarely queried
|
||||
```
|
||||
|
||||
## Index Type Selection
|
||||
|
||||
| Type | Use For |
|
||||
|------|---------|
|
||||
| **B-tree** | General purpose, equality & range |
|
||||
| **Hash** | Equality only, faster |
|
||||
| **GIN** | JSONB, arrays, full-text |
|
||||
| **GiST** | Geometric, range types |
|
||||
| **HNSW/IVFFlat** | Vector similarity (pgvector) |
|
||||
|
||||
## Composite Index Principles
|
||||
|
||||
```
|
||||
Order matters for composite indexes:
|
||||
├── Equality columns first
|
||||
├── Range columns last
|
||||
├── Most selective first
|
||||
└── Match query pattern
|
||||
```
|
||||
48
skills/database-design/migrations.md
Normal file
48
skills/database-design/migrations.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Migration Principles
|
||||
|
||||
> Safe migration strategy for zero-downtime changes.
|
||||
|
||||
## Safe Migration Strategy
|
||||
|
||||
```
|
||||
For zero-downtime changes:
|
||||
│
|
||||
├── Adding column
|
||||
│ └── Add as nullable → backfill → add NOT NULL
|
||||
│
|
||||
├── Removing column
|
||||
│ └── Stop using → deploy → remove column
|
||||
│
|
||||
├── Adding index
|
||||
│ └── CREATE INDEX CONCURRENTLY (non-blocking)
|
||||
│
|
||||
└── Renaming column
|
||||
└── Add new → migrate data → deploy → drop old
|
||||
```
|
||||
|
||||
## Migration Philosophy
|
||||
|
||||
- Never make breaking changes in one step
|
||||
- Test migrations on data copy first
|
||||
- Have rollback plan
|
||||
- Run in transaction when possible
|
||||
|
||||
## Serverless Databases
|
||||
|
||||
### Neon (Serverless PostgreSQL)
|
||||
|
||||
| Feature | Benefit |
|
||||
|---------|---------|
|
||||
| Scale to zero | Cost savings |
|
||||
| Instant branching | Dev/preview |
|
||||
| Full PostgreSQL | Compatibility |
|
||||
| Autoscaling | Traffic handling |
|
||||
|
||||
### Turso (Edge SQLite)
|
||||
|
||||
| Feature | Benefit |
|
||||
|---------|---------|
|
||||
| Edge locations | Ultra-low latency |
|
||||
| SQLite compatible | Simple |
|
||||
| Generous free tier | Cost |
|
||||
| Global distribution | Performance |
|
||||
36
skills/database-design/optimization.md
Normal file
36
skills/database-design/optimization.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Query Optimization
|
||||
|
||||
> N+1 problem, EXPLAIN ANALYZE, optimization priorities.
|
||||
|
||||
## N+1 Problem
|
||||
|
||||
```
|
||||
What is N+1?
|
||||
├── 1 query to get parent records
|
||||
├── N queries to get related records
|
||||
└── Very slow!
|
||||
|
||||
Solutions:
|
||||
├── JOIN → Single query with all data
|
||||
├── Eager loading → ORM handles JOIN
|
||||
├── DataLoader → Batch and cache (GraphQL)
|
||||
└── Subquery → Fetch related in one query
|
||||
```
|
||||
|
||||
## Query Analysis Mindset
|
||||
|
||||
```
|
||||
Before optimizing:
|
||||
├── EXPLAIN ANALYZE the query
|
||||
├── Look for Seq Scan (full table scan)
|
||||
├── Check actual vs estimated rows
|
||||
└── Identify missing indexes
|
||||
```
|
||||
|
||||
## Optimization Priorities
|
||||
|
||||
1. **Add missing indexes** (most common issue)
|
||||
2. **Select only needed columns** (not SELECT *)
|
||||
3. **Use proper JOINs** (avoid subqueries when possible)
|
||||
4. **Limit early** (pagination at database level)
|
||||
5. **Cache** (when appropriate)
|
||||
30
skills/database-design/orm-selection.md
Normal file
30
skills/database-design/orm-selection.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# ORM Selection (2025)
|
||||
|
||||
> Choose ORM based on deployment and DX needs.
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```
|
||||
What's the context?
|
||||
│
|
||||
├── Edge deployment / Bundle size matters
|
||||
│ └── Drizzle (smallest, SQL-like)
|
||||
│
|
||||
├── Best DX / Schema-first
|
||||
│ └── Prisma (migrations, studio)
|
||||
│
|
||||
├── Maximum control
|
||||
│ └── Raw SQL with query builder
|
||||
│
|
||||
└── Python ecosystem
|
||||
└── SQLAlchemy 2.0 (async support)
|
||||
```
|
||||
|
||||
## Comparison
|
||||
|
||||
| ORM | Best For | Trade-offs |
|
||||
|-----|----------|------------|
|
||||
| **Drizzle** | Edge, TypeScript | Newer, less examples |
|
||||
| **Prisma** | DX, schema management | Heavier, not edge-ready |
|
||||
| **Kysely** | Type-safe SQL builder | Manual migrations |
|
||||
| **Raw SQL** | Complex queries, control | Manual type safety |
|
||||
56
skills/database-design/schema-design.md
Normal file
56
skills/database-design/schema-design.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Schema Design Principles
|
||||
|
||||
> Normalization, primary keys, timestamps, relationships.
|
||||
|
||||
## Normalization Decision
|
||||
|
||||
```
|
||||
When to normalize (separate tables):
|
||||
├── Data is repeated across rows
|
||||
├── Updates would need multiple changes
|
||||
├── Relationships are clear
|
||||
└── Query patterns benefit
|
||||
|
||||
When to denormalize (embed/duplicate):
|
||||
├── Read performance critical
|
||||
├── Data rarely changes
|
||||
├── Always fetched together
|
||||
└── Simpler queries needed
|
||||
```
|
||||
|
||||
## Primary Key Selection
|
||||
|
||||
| Type | Use When |
|
||||
|------|----------|
|
||||
| **UUID** | Distributed systems, security |
|
||||
| **ULID** | UUID + sortable by time |
|
||||
| **Auto-increment** | Simple apps, single database |
|
||||
| **Natural key** | Rarely (business meaning) |
|
||||
|
||||
## Timestamp Strategy
|
||||
|
||||
```
|
||||
For every table:
|
||||
├── created_at → When created
|
||||
├── updated_at → Last modified
|
||||
└── deleted_at → Soft delete (if needed)
|
||||
|
||||
Use TIMESTAMPTZ (with timezone) not TIMESTAMP
|
||||
```
|
||||
|
||||
## Relationship Types
|
||||
|
||||
| Type | When | Implementation |
|
||||
|------|------|----------------|
|
||||
| **One-to-One** | Extension data | Separate table with FK |
|
||||
| **One-to-Many** | Parent-children | FK on child table |
|
||||
| **Many-to-Many** | Both sides have many | Junction table |
|
||||
|
||||
## Foreign Key ON DELETE
|
||||
|
||||
```
|
||||
├── CASCADE → Delete children with parent
|
||||
├── SET NULL → Children become orphans
|
||||
├── RESTRICT → Prevent delete if children exist
|
||||
└── SET DEFAULT → Children get default value
|
||||
```
|
||||
172
skills/database-design/scripts/schema_validator.py
Normal file
172
skills/database-design/scripts/schema_validator.py
Normal file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Schema Validator - Database schema validation
|
||||
Validates Prisma schemas and checks for common issues.
|
||||
|
||||
Usage:
|
||||
python schema_validator.py <project_path>
|
||||
|
||||
Checks:
|
||||
- Prisma schema syntax
|
||||
- Missing relations
|
||||
- Index recommendations
|
||||
- Naming conventions
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Fix Windows console encoding
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def find_schema_files(project_path: Path) -> list:
|
||||
"""Find database schema files."""
|
||||
schemas = []
|
||||
|
||||
# Prisma schema
|
||||
prisma_files = list(project_path.glob('**/prisma/schema.prisma'))
|
||||
schemas.extend([('prisma', f) for f in prisma_files])
|
||||
|
||||
# Drizzle schema files
|
||||
drizzle_files = list(project_path.glob('**/drizzle/*.ts'))
|
||||
drizzle_files.extend(project_path.glob('**/schema/*.ts'))
|
||||
for f in drizzle_files:
|
||||
if 'schema' in f.name.lower() or 'table' in f.name.lower():
|
||||
schemas.append(('drizzle', f))
|
||||
|
||||
return schemas[:10] # Limit
|
||||
|
||||
|
||||
def validate_prisma_schema(file_path: Path) -> list:
|
||||
"""Validate Prisma schema file."""
|
||||
issues = []
|
||||
|
||||
try:
|
||||
content = file_path.read_text(encoding='utf-8', errors='ignore')
|
||||
|
||||
# Find all models
|
||||
models = re.findall(r'model\s+(\w+)\s*{([^}]+)}', content, re.DOTALL)
|
||||
|
||||
for model_name, model_body in models:
|
||||
# Check naming convention (PascalCase)
|
||||
if not model_name[0].isupper():
|
||||
issues.append(f"Model '{model_name}' should be PascalCase")
|
||||
|
||||
# Check for id field
|
||||
if '@id' not in model_body and 'id' not in model_body.lower():
|
||||
issues.append(f"Model '{model_name}' might be missing @id field")
|
||||
|
||||
# Check for createdAt/updatedAt
|
||||
if 'createdAt' not in model_body and 'created_at' not in model_body:
|
||||
issues.append(f"Model '{model_name}' missing createdAt field (recommended)")
|
||||
|
||||
# Check for @relation without fields
|
||||
relations = re.findall(r'@relation\([^)]*\)', model_body)
|
||||
for rel in relations:
|
||||
if 'fields:' not in rel and 'references:' not in rel:
|
||||
pass # Implicit relation, ok
|
||||
|
||||
# Check for @@index suggestions
|
||||
foreign_keys = re.findall(r'(\w+Id)\s+\w+', model_body)
|
||||
for fk in foreign_keys:
|
||||
if f'@@index([{fk}])' not in content and f'@@index(["{fk}"])' not in content:
|
||||
issues.append(f"Consider adding @@index([{fk}]) for better query performance in {model_name}")
|
||||
|
||||
# Check for enum definitions
|
||||
enums = re.findall(r'enum\s+(\w+)\s*{', content)
|
||||
for enum_name in enums:
|
||||
if not enum_name[0].isupper():
|
||||
issues.append(f"Enum '{enum_name}' should be PascalCase")
|
||||
|
||||
except Exception as e:
|
||||
issues.append(f"Error reading schema: {str(e)[:50]}")
|
||||
|
||||
return issues
|
||||
|
||||
|
||||
def main():
|
||||
project_path = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"[SCHEMA VALIDATOR] Database Schema Validation")
|
||||
print(f"{'='*60}")
|
||||
print(f"Project: {project_path}")
|
||||
print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print("-"*60)
|
||||
|
||||
# Find schema files
|
||||
schemas = find_schema_files(project_path)
|
||||
print(f"Found {len(schemas)} schema files")
|
||||
|
||||
if not schemas:
|
||||
output = {
|
||||
"script": "schema_validator",
|
||||
"project": str(project_path),
|
||||
"schemas_checked": 0,
|
||||
"issues_found": 0,
|
||||
"passed": True,
|
||||
"message": "No schema files found"
|
||||
}
|
||||
print(json.dumps(output, indent=2))
|
||||
sys.exit(0)
|
||||
|
||||
# Validate each schema
|
||||
all_issues = []
|
||||
|
||||
for schema_type, file_path in schemas:
|
||||
print(f"\nValidating: {file_path.name} ({schema_type})")
|
||||
|
||||
if schema_type == 'prisma':
|
||||
issues = validate_prisma_schema(file_path)
|
||||
else:
|
||||
issues = [] # Drizzle validation could be added
|
||||
|
||||
if issues:
|
||||
all_issues.append({
|
||||
"file": str(file_path.name),
|
||||
"type": schema_type,
|
||||
"issues": issues
|
||||
})
|
||||
|
||||
# Summary
|
||||
print("\n" + "="*60)
|
||||
print("SCHEMA ISSUES")
|
||||
print("="*60)
|
||||
|
||||
if all_issues:
|
||||
for item in all_issues:
|
||||
print(f"\n{item['file']} ({item['type']}):")
|
||||
for issue in item["issues"][:5]: # Limit per file
|
||||
print(f" - {issue}")
|
||||
if len(item["issues"]) > 5:
|
||||
print(f" ... and {len(item['issues']) - 5} more issues")
|
||||
else:
|
||||
print("No schema issues found!")
|
||||
|
||||
total_issues = sum(len(item["issues"]) for item in all_issues)
|
||||
# Schema issues are warnings, not failures
|
||||
passed = True
|
||||
|
||||
output = {
|
||||
"script": "schema_validator",
|
||||
"project": str(project_path),
|
||||
"schemas_checked": len(schemas),
|
||||
"issues_found": total_issues,
|
||||
"passed": passed,
|
||||
"issues": all_issues
|
||||
}
|
||||
|
||||
print("\n" + json.dumps(output, indent=2))
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
241
skills/deployment-procedures/SKILL.md
Normal file
241
skills/deployment-procedures/SKILL.md
Normal file
@@ -0,0 +1,241 @@
|
||||
---
|
||||
name: deployment-procedures
|
||||
description: Production deployment principles and decision-making. Safe deployment workflows, rollback strategies, and verification. Teaches thinking, not scripts.
|
||||
allowed-tools: Read, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# Deployment Procedures
|
||||
|
||||
> Deployment principles and decision-making for safe production releases.
|
||||
> **Learn to THINK, not memorize scripts.**
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ How to Use This Skill
|
||||
|
||||
This skill teaches **deployment principles**, not bash scripts to copy.
|
||||
|
||||
- Every deployment is unique
|
||||
- Understand the WHY behind each step
|
||||
- Adapt procedures to your platform
|
||||
|
||||
---
|
||||
|
||||
## 1. Platform Selection
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
What are you deploying?
|
||||
│
|
||||
├── Static site / JAMstack
|
||||
│ └── Vercel, Netlify, Cloudflare Pages
|
||||
│
|
||||
├── Simple web app
|
||||
│ ├── Managed → Railway, Render, Fly.io
|
||||
│ └── Control → VPS + PM2/Docker
|
||||
│
|
||||
├── Microservices
|
||||
│ └── Container orchestration
|
||||
│
|
||||
└── Serverless
|
||||
└── Edge functions, Lambda
|
||||
```
|
||||
|
||||
### Each Platform Has Different Procedures
|
||||
|
||||
| Platform | Deployment Method |
|
||||
|----------|------------------|
|
||||
| **Vercel/Netlify** | Git push, auto-deploy |
|
||||
| **Railway/Render** | Git push or CLI |
|
||||
| **VPS + PM2** | SSH + manual steps |
|
||||
| **Docker** | Image push + orchestration |
|
||||
| **Kubernetes** | kubectl apply |
|
||||
|
||||
---
|
||||
|
||||
## 2. Pre-Deployment Principles
|
||||
|
||||
### The 4 Verification Categories
|
||||
|
||||
| Category | What to Check |
|
||||
|----------|--------------|
|
||||
| **Code Quality** | Tests passing, linting clean, reviewed |
|
||||
| **Build** | Production build works, no warnings |
|
||||
| **Environment** | Env vars set, secrets current |
|
||||
| **Safety** | Backup done, rollback plan ready |
|
||||
|
||||
### Pre-Deployment Checklist
|
||||
|
||||
- [ ] All tests passing
|
||||
- [ ] Code reviewed and approved
|
||||
- [ ] Production build successful
|
||||
- [ ] Environment variables verified
|
||||
- [ ] Database migrations ready (if any)
|
||||
- [ ] Rollback plan documented
|
||||
- [ ] Team notified
|
||||
- [ ] Monitoring ready
|
||||
|
||||
---
|
||||
|
||||
## 3. Deployment Workflow Principles
|
||||
|
||||
### The 5-Phase Process
|
||||
|
||||
```
|
||||
1. PREPARE
|
||||
└── Verify code, build, env vars
|
||||
|
||||
2. BACKUP
|
||||
└── Save current state before changing
|
||||
|
||||
3. DEPLOY
|
||||
└── Execute with monitoring open
|
||||
|
||||
4. VERIFY
|
||||
└── Health check, logs, key flows
|
||||
|
||||
5. CONFIRM or ROLLBACK
|
||||
└── All good? Confirm. Issues? Rollback.
|
||||
```
|
||||
|
||||
### Phase Principles
|
||||
|
||||
| Phase | Principle |
|
||||
|-------|-----------|
|
||||
| **Prepare** | Never deploy untested code |
|
||||
| **Backup** | Can't rollback without backup |
|
||||
| **Deploy** | Watch it happen, don't walk away |
|
||||
| **Verify** | Trust but verify |
|
||||
| **Confirm** | Have rollback trigger ready |
|
||||
|
||||
---
|
||||
|
||||
## 4. Post-Deployment Verification
|
||||
|
||||
### What to Verify
|
||||
|
||||
| Check | Why |
|
||||
|-------|-----|
|
||||
| **Health endpoint** | Service is running |
|
||||
| **Error logs** | No new errors |
|
||||
| **Key user flows** | Critical features work |
|
||||
| **Performance** | Response times acceptable |
|
||||
|
||||
### Verification Window
|
||||
|
||||
- **First 5 minutes**: Active monitoring
|
||||
- **15 minutes**: Confirm stable
|
||||
- **1 hour**: Final verification
|
||||
- **Next day**: Review metrics
|
||||
|
||||
---
|
||||
|
||||
## 5. Rollback Principles
|
||||
|
||||
### When to Rollback
|
||||
|
||||
| Symptom | Action |
|
||||
|---------|--------|
|
||||
| Service down | Rollback immediately |
|
||||
| Critical errors | Rollback |
|
||||
| Performance >50% degraded | Consider rollback |
|
||||
| Minor issues | Fix forward if quick |
|
||||
|
||||
### Rollback Strategy by Platform
|
||||
|
||||
| Platform | Rollback Method |
|
||||
|----------|----------------|
|
||||
| **Vercel/Netlify** | Redeploy previous commit |
|
||||
| **Railway/Render** | Rollback in dashboard |
|
||||
| **VPS + PM2** | Restore backup, restart |
|
||||
| **Docker** | Previous image tag |
|
||||
| **K8s** | kubectl rollout undo |
|
||||
|
||||
### Rollback Principles
|
||||
|
||||
1. **Speed over perfection**: Rollback first, debug later
|
||||
2. **Don't compound errors**: One rollback, not multiple changes
|
||||
3. **Communicate**: Tell team what happened
|
||||
4. **Post-mortem**: Understand why after stable
|
||||
|
||||
---
|
||||
|
||||
## 6. Zero-Downtime Deployment
|
||||
|
||||
### Strategies
|
||||
|
||||
| Strategy | How It Works |
|
||||
|----------|--------------|
|
||||
| **Rolling** | Replace instances one by one |
|
||||
| **Blue-Green** | Switch traffic between environments |
|
||||
| **Canary** | Gradual traffic shift |
|
||||
|
||||
### Selection Principles
|
||||
|
||||
| Scenario | Strategy |
|
||||
|----------|----------|
|
||||
| Standard release | Rolling |
|
||||
| High-risk change | Blue-green (easy rollback) |
|
||||
| Need validation | Canary (test with real traffic) |
|
||||
|
||||
---
|
||||
|
||||
## 7. Emergency Procedures
|
||||
|
||||
### Service Down Priority
|
||||
|
||||
1. **Assess**: What's the symptom?
|
||||
2. **Quick fix**: Restart if unclear
|
||||
3. **Rollback**: If restart doesn't help
|
||||
4. **Investigate**: After stable
|
||||
|
||||
### Investigation Order
|
||||
|
||||
| Check | Common Issues |
|
||||
|-------|--------------|
|
||||
| **Logs** | Errors, exceptions |
|
||||
| **Resources** | Disk full, memory |
|
||||
| **Network** | DNS, firewall |
|
||||
| **Dependencies** | Database, APIs |
|
||||
|
||||
---
|
||||
|
||||
## 8. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Deploy on Friday | Deploy early in week |
|
||||
| Rush deployment | Follow the process |
|
||||
| Skip staging | Always test first |
|
||||
| Deploy without backup | Backup before deploy |
|
||||
| Walk away after deploy | Monitor for 15+ min |
|
||||
| Multiple changes at once | One change at a time |
|
||||
|
||||
---
|
||||
|
||||
## 9. Decision Checklist
|
||||
|
||||
Before deploying:
|
||||
|
||||
- [ ] **Platform-appropriate procedure?**
|
||||
- [ ] **Backup strategy ready?**
|
||||
- [ ] **Rollback plan documented?**
|
||||
- [ ] **Monitoring configured?**
|
||||
- [ ] **Team notified?**
|
||||
- [ ] **Time to monitor after?**
|
||||
|
||||
---
|
||||
|
||||
## 10. Best Practices
|
||||
|
||||
1. **Small, frequent deploys** over big releases
|
||||
2. **Feature flags** for risky changes
|
||||
3. **Automate** repetitive steps
|
||||
4. **Document** every deployment
|
||||
5. **Review** what went wrong after issues
|
||||
6. **Test rollback** before you need it
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Every deployment is a risk. Minimize risk through preparation, not speed.
|
||||
409
skills/docker-expert/SKILL.md
Normal file
409
skills/docker-expert/SKILL.md
Normal file
@@ -0,0 +1,409 @@
|
||||
---
|
||||
name: docker-expert
|
||||
description: 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.
|
||||
category: devops
|
||||
color: blue
|
||||
displayName: Docker Expert
|
||||
---
|
||||
|
||||
# Docker Expert
|
||||
|
||||
You are an advanced Docker containerization expert with comprehensive, practical knowledge of container optimization, security hardening, multi-stage builds, orchestration patterns, and production deployment strategies based on current industry best practices.
|
||||
|
||||
## When invoked:
|
||||
|
||||
0. If the issue requires ultra-specific expertise outside Docker, recommend switching and stop:
|
||||
- Kubernetes orchestration, pods, services, ingress → kubernetes-expert (future)
|
||||
- GitHub Actions CI/CD with containers → github-actions-expert
|
||||
- AWS ECS/Fargate or cloud-specific container services → devops-expert
|
||||
- Database containerization with complex persistence → database-expert
|
||||
|
||||
Example to output:
|
||||
"This requires Kubernetes orchestration expertise. Please invoke: 'Use the kubernetes-expert subagent.' Stopping here."
|
||||
|
||||
1. Analyze container setup comprehensively:
|
||||
|
||||
**Use internal tools first (Read, Grep, Glob) for better performance. Shell commands are fallbacks.**
|
||||
|
||||
```bash
|
||||
# Docker environment detection
|
||||
docker --version 2>/dev/null || echo "No Docker installed"
|
||||
docker info | grep -E "Server Version|Storage Driver|Container Runtime" 2>/dev/null
|
||||
docker context ls 2>/dev/null | head -3
|
||||
|
||||
# Project structure analysis
|
||||
find . -name "Dockerfile*" -type f | head -10
|
||||
find . -name "*compose*.yml" -o -name "*compose*.yaml" -type f | head -5
|
||||
find . -name ".dockerignore" -type f | head -3
|
||||
|
||||
# Container status if running
|
||||
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" 2>/dev/null | head -10
|
||||
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" 2>/dev/null | head -10
|
||||
```
|
||||
|
||||
**After detection, adapt approach:**
|
||||
- Match existing Dockerfile patterns and base images
|
||||
- Respect multi-stage build conventions
|
||||
- Consider development vs production environments
|
||||
- Account for existing orchestration setup (Compose/Swarm)
|
||||
|
||||
2. Identify the specific problem category and complexity level
|
||||
|
||||
3. Apply the appropriate solution strategy from my expertise
|
||||
|
||||
4. Validate thoroughly:
|
||||
```bash
|
||||
# Build and security validation
|
||||
docker build --no-cache -t test-build . 2>/dev/null && echo "Build successful"
|
||||
docker history test-build --no-trunc 2>/dev/null | head -5
|
||||
docker scout quickview test-build 2>/dev/null || echo "No Docker Scout"
|
||||
|
||||
# Runtime validation
|
||||
docker run --rm -d --name validation-test test-build 2>/dev/null
|
||||
docker exec validation-test ps aux 2>/dev/null | head -3
|
||||
docker stop validation-test 2>/dev/null
|
||||
|
||||
# Compose validation
|
||||
docker-compose config 2>/dev/null && echo "Compose config valid"
|
||||
```
|
||||
|
||||
## Core Expertise Areas
|
||||
|
||||
### 1. Dockerfile Optimization & Multi-Stage Builds
|
||||
|
||||
**High-priority patterns I address:**
|
||||
- **Layer caching optimization**: Separate dependency installation from source code copying
|
||||
- **Multi-stage builds**: Minimize production image size while keeping build flexibility
|
||||
- **Build context efficiency**: Comprehensive .dockerignore and build context management
|
||||
- **Base image selection**: Alpine vs distroless vs scratch image strategies
|
||||
|
||||
**Key techniques:**
|
||||
```dockerfile
|
||||
# Optimized multi-stage pattern
|
||||
FROM node:18-alpine AS deps
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production && npm cache clean --force
|
||||
|
||||
FROM node:18-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build && npm prune --production
|
||||
|
||||
FROM node:18-alpine AS runtime
|
||||
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
|
||||
WORKDIR /app
|
||||
COPY --from=deps --chown=nextjs:nodejs /app/node_modules ./node_modules
|
||||
COPY --from=build --chown=nextjs:nodejs /app/dist ./dist
|
||||
COPY --from=build --chown=nextjs:nodejs /app/package*.json ./
|
||||
USER nextjs
|
||||
EXPOSE 3000
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:3000/health || exit 1
|
||||
CMD ["node", "dist/index.js"]
|
||||
```
|
||||
|
||||
### 2. Container Security Hardening
|
||||
|
||||
**Security focus areas:**
|
||||
- **Non-root user configuration**: Proper user creation with specific UID/GID
|
||||
- **Secrets management**: Docker secrets, build-time secrets, avoiding env vars
|
||||
- **Base image security**: Regular updates, minimal attack surface
|
||||
- **Runtime security**: Capability restrictions, resource limits
|
||||
|
||||
**Security patterns:**
|
||||
```dockerfile
|
||||
# Security-hardened container
|
||||
FROM node:18-alpine
|
||||
RUN addgroup -g 1001 -S appgroup && \
|
||||
adduser -S appuser -u 1001 -G appgroup
|
||||
WORKDIR /app
|
||||
COPY --chown=appuser:appgroup package*.json ./
|
||||
RUN npm ci --only=production
|
||||
COPY --chown=appuser:appgroup . .
|
||||
USER 1001
|
||||
# Drop capabilities, set read-only root filesystem
|
||||
```
|
||||
|
||||
### 3. Docker Compose Orchestration
|
||||
|
||||
**Orchestration expertise:**
|
||||
- **Service dependency management**: Health checks, startup ordering
|
||||
- **Network configuration**: Custom networks, service discovery
|
||||
- **Environment management**: Dev/staging/prod configurations
|
||||
- **Volume strategies**: Named volumes, bind mounts, data persistence
|
||||
|
||||
**Production-ready compose pattern:**
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
target: production
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 256M
|
||||
|
||||
db:
|
||||
image: postgres:15-alpine
|
||||
environment:
|
||||
POSTGRES_DB_FILE: /run/secrets/db_name
|
||||
POSTGRES_USER_FILE: /run/secrets/db_user
|
||||
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
|
||||
secrets:
|
||||
- db_name
|
||||
- db_user
|
||||
- db_password
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- backend
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
networks:
|
||||
frontend:
|
||||
driver: bridge
|
||||
backend:
|
||||
driver: bridge
|
||||
internal: true
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
||||
secrets:
|
||||
db_name:
|
||||
external: true
|
||||
db_user:
|
||||
external: true
|
||||
db_password:
|
||||
external: true
|
||||
```
|
||||
|
||||
### 4. Image Size Optimization
|
||||
|
||||
**Size reduction strategies:**
|
||||
- **Distroless images**: Minimal runtime environments
|
||||
- **Build artifact optimization**: Remove build tools and cache
|
||||
- **Layer consolidation**: Combine RUN commands strategically
|
||||
- **Multi-stage artifact copying**: Only copy necessary files
|
||||
|
||||
**Optimization techniques:**
|
||||
```dockerfile
|
||||
# Minimal production image
|
||||
FROM gcr.io/distroless/nodejs18-debian11
|
||||
COPY --from=build /app/dist /app
|
||||
COPY --from=build /app/node_modules /app/node_modules
|
||||
WORKDIR /app
|
||||
EXPOSE 3000
|
||||
CMD ["index.js"]
|
||||
```
|
||||
|
||||
### 5. Development Workflow Integration
|
||||
|
||||
**Development patterns:**
|
||||
- **Hot reloading setup**: Volume mounting and file watching
|
||||
- **Debug configuration**: Port exposure and debugging tools
|
||||
- **Testing integration**: Test-specific containers and environments
|
||||
- **Development containers**: Remote development container support via CLI tools
|
||||
|
||||
**Development workflow:**
|
||||
```yaml
|
||||
# Development override
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
target: development
|
||||
volumes:
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
- /app/dist
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- DEBUG=app:*
|
||||
ports:
|
||||
- "9229:9229" # Debug port
|
||||
command: npm run dev
|
||||
```
|
||||
|
||||
### 6. Performance & Resource Management
|
||||
|
||||
**Performance optimization:**
|
||||
- **Resource limits**: CPU, memory constraints for stability
|
||||
- **Build performance**: Parallel builds, cache utilization
|
||||
- **Runtime performance**: Process management, signal handling
|
||||
- **Monitoring integration**: Health checks, metrics exposure
|
||||
|
||||
**Resource management:**
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
window: 120s
|
||||
```
|
||||
|
||||
## Advanced Problem-Solving Patterns
|
||||
|
||||
### Cross-Platform Builds
|
||||
```bash
|
||||
# Multi-architecture builds
|
||||
docker buildx create --name multiarch-builder --use
|
||||
docker buildx build --platform linux/amd64,linux/arm64 \
|
||||
-t myapp:latest --push .
|
||||
```
|
||||
|
||||
### Build Cache Optimization
|
||||
```dockerfile
|
||||
# Mount build cache for package managers
|
||||
FROM node:18-alpine AS deps
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN --mount=type=cache,target=/root/.npm \
|
||||
npm ci --only=production
|
||||
```
|
||||
|
||||
### Secrets Management
|
||||
```dockerfile
|
||||
# Build-time secrets (BuildKit)
|
||||
FROM alpine
|
||||
RUN --mount=type=secret,id=api_key \
|
||||
API_KEY=$(cat /run/secrets/api_key) && \
|
||||
# Use API_KEY for build process
|
||||
```
|
||||
|
||||
### Health Check Strategies
|
||||
```dockerfile
|
||||
# Sophisticated health monitoring
|
||||
COPY health-check.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/health-check.sh
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD ["/usr/local/bin/health-check.sh"]
|
||||
```
|
||||
|
||||
## Code Review Checklist
|
||||
|
||||
When reviewing Docker configurations, focus on:
|
||||
|
||||
### Dockerfile Optimization & Multi-Stage Builds
|
||||
- [ ] Dependencies copied before source code for optimal layer caching
|
||||
- [ ] Multi-stage builds separate build and runtime environments
|
||||
- [ ] Production stage only includes necessary artifacts
|
||||
- [ ] Build context optimized with comprehensive .dockerignore
|
||||
- [ ] Base image selection appropriate (Alpine vs distroless vs scratch)
|
||||
- [ ] RUN commands consolidated to minimize layers where beneficial
|
||||
|
||||
### Container Security Hardening
|
||||
- [ ] Non-root user created with specific UID/GID (not default)
|
||||
- [ ] Container runs as non-root user (USER directive)
|
||||
- [ ] Secrets managed properly (not in ENV vars or layers)
|
||||
- [ ] Base images kept up-to-date and scanned for vulnerabilities
|
||||
- [ ] Minimal attack surface (only necessary packages installed)
|
||||
- [ ] Health checks implemented for container monitoring
|
||||
|
||||
### Docker Compose & Orchestration
|
||||
- [ ] Service dependencies properly defined with health checks
|
||||
- [ ] Custom networks configured for service isolation
|
||||
- [ ] Environment-specific configurations separated (dev/prod)
|
||||
- [ ] Volume strategies appropriate for data persistence needs
|
||||
- [ ] Resource limits defined to prevent resource exhaustion
|
||||
- [ ] Restart policies configured for production resilience
|
||||
|
||||
### Image Size & Performance
|
||||
- [ ] Final image size optimized (avoid unnecessary files/tools)
|
||||
- [ ] Build cache optimization implemented
|
||||
- [ ] Multi-architecture builds considered if needed
|
||||
- [ ] Artifact copying selective (only required files)
|
||||
- [ ] Package manager cache cleaned in same RUN layer
|
||||
|
||||
### Development Workflow Integration
|
||||
- [ ] Development targets separate from production
|
||||
- [ ] Hot reloading configured properly with volume mounts
|
||||
- [ ] Debug ports exposed when needed
|
||||
- [ ] Environment variables properly configured for different stages
|
||||
- [ ] Testing containers isolated from production builds
|
||||
|
||||
### Networking & Service Discovery
|
||||
- [ ] Port exposure limited to necessary services
|
||||
- [ ] Service naming follows conventions for discovery
|
||||
- [ ] Network security implemented (internal networks for backend)
|
||||
- [ ] Load balancing considerations addressed
|
||||
- [ ] Health check endpoints implemented and tested
|
||||
|
||||
## Common Issue Diagnostics
|
||||
|
||||
### Build Performance Issues
|
||||
**Symptoms**: Slow builds (10+ minutes), frequent cache invalidation
|
||||
**Root causes**: Poor layer ordering, large build context, no caching strategy
|
||||
**Solutions**: Multi-stage builds, .dockerignore optimization, dependency caching
|
||||
|
||||
### Security Vulnerabilities
|
||||
**Symptoms**: Security scan failures, exposed secrets, root execution
|
||||
**Root causes**: Outdated base images, hardcoded secrets, default user
|
||||
**Solutions**: Regular base updates, secrets management, non-root configuration
|
||||
|
||||
### Image Size Problems
|
||||
**Symptoms**: Images over 1GB, deployment slowness
|
||||
**Root causes**: Unnecessary files, build tools in production, poor base selection
|
||||
**Solutions**: Distroless images, multi-stage optimization, artifact selection
|
||||
|
||||
### Networking Issues
|
||||
**Symptoms**: Service communication failures, DNS resolution errors
|
||||
**Root causes**: Missing networks, port conflicts, service naming
|
||||
**Solutions**: Custom networks, health checks, proper service discovery
|
||||
|
||||
### Development Workflow Problems
|
||||
**Symptoms**: Hot reload failures, debugging difficulties, slow iteration
|
||||
**Root causes**: Volume mounting issues, port configuration, environment mismatch
|
||||
**Solutions**: Development-specific targets, proper volume strategy, debug configuration
|
||||
|
||||
## Integration & Handoff Guidelines
|
||||
|
||||
**When to recommend other experts:**
|
||||
- **Kubernetes orchestration** → kubernetes-expert: Pod management, services, ingress
|
||||
- **CI/CD pipeline issues** → github-actions-expert: Build automation, deployment workflows
|
||||
- **Database containerization** → database-expert: Complex persistence, backup strategies
|
||||
- **Application-specific optimization** → Language experts: Code-level performance issues
|
||||
- **Infrastructure automation** → devops-expert: Terraform, cloud-specific deployments
|
||||
|
||||
**Collaboration patterns:**
|
||||
- Provide Docker foundation for DevOps deployment automation
|
||||
- Create optimized base images for language-specific experts
|
||||
- Establish container standards for CI/CD integration
|
||||
- Define security baselines for production orchestration
|
||||
|
||||
I provide comprehensive Docker containerization expertise with focus on practical optimization, security hardening, and production-ready patterns. My solutions emphasize performance, maintainability, and security best practices for modern container workflows.
|
||||
194
skills/documentation-templates/SKILL.md
Normal file
194
skills/documentation-templates/SKILL.md
Normal file
@@ -0,0 +1,194 @@
|
||||
---
|
||||
name: documentation-templates
|
||||
description: Documentation templates and structure guidelines. README, API docs, code comments, and AI-friendly documentation.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Documentation Templates
|
||||
|
||||
> Templates and structure guidelines for common documentation types.
|
||||
|
||||
---
|
||||
|
||||
## 1. README Structure
|
||||
|
||||
### Essential Sections (Priority Order)
|
||||
|
||||
| Section | Purpose |
|
||||
|---------|---------|
|
||||
| **Title + One-liner** | What is this? |
|
||||
| **Quick Start** | Running in <5 min |
|
||||
| **Features** | What can I do? |
|
||||
| **Configuration** | How to customize |
|
||||
| **API Reference** | Link to detailed docs |
|
||||
| **Contributing** | How to help |
|
||||
| **License** | Legal |
|
||||
|
||||
### README Template
|
||||
|
||||
```markdown
|
||||
# Project Name
|
||||
|
||||
Brief one-line description.
|
||||
|
||||
## Quick Start
|
||||
|
||||
[Minimum steps to run]
|
||||
|
||||
## Features
|
||||
|
||||
- Feature 1
|
||||
- Feature 2
|
||||
|
||||
## Configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| PORT | Server port | 3000 |
|
||||
|
||||
## Documentation
|
||||
|
||||
- [API Reference](./docs/api.md)
|
||||
- [Architecture](./docs/architecture.md)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. API Documentation Structure
|
||||
|
||||
### Per-Endpoint Template
|
||||
|
||||
```markdown
|
||||
## GET /users/:id
|
||||
|
||||
Get a user by ID.
|
||||
|
||||
**Parameters:**
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| id | string | Yes | User ID |
|
||||
|
||||
**Response:**
|
||||
- 200: User object
|
||||
- 404: User not found
|
||||
|
||||
**Example:**
|
||||
[Request and response example]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Code Comment Guidelines
|
||||
|
||||
### JSDoc/TSDoc Template
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Brief description of what the function does.
|
||||
*
|
||||
* @param paramName - Description of parameter
|
||||
* @returns Description of return value
|
||||
* @throws ErrorType - When this error occurs
|
||||
*
|
||||
* @example
|
||||
* const result = functionName(input);
|
||||
*/
|
||||
```
|
||||
|
||||
### When to Comment
|
||||
|
||||
| ✅ Comment | ❌ Don't Comment |
|
||||
|-----------|-----------------|
|
||||
| Why (business logic) | What (obvious) |
|
||||
| Complex algorithms | Every line |
|
||||
| Non-obvious behavior | Self-explanatory code |
|
||||
| API contracts | Implementation details |
|
||||
|
||||
---
|
||||
|
||||
## 4. Changelog Template (Keep a Changelog)
|
||||
|
||||
```markdown
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- New feature
|
||||
|
||||
## [1.0.0] - 2025-01-01
|
||||
### Added
|
||||
- Initial release
|
||||
### Changed
|
||||
- Updated dependency
|
||||
### Fixed
|
||||
- Bug fix
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Architecture Decision Record (ADR)
|
||||
|
||||
```markdown
|
||||
# ADR-001: [Title]
|
||||
|
||||
## Status
|
||||
Accepted / Deprecated / Superseded
|
||||
|
||||
## Context
|
||||
Why are we making this decision?
|
||||
|
||||
## Decision
|
||||
What did we decide?
|
||||
|
||||
## Consequences
|
||||
What are the trade-offs?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. AI-Friendly Documentation (2025)
|
||||
|
||||
### llms.txt Template
|
||||
|
||||
For AI crawlers and agents:
|
||||
|
||||
```markdown
|
||||
# Project Name
|
||||
> One-line objective.
|
||||
|
||||
## Core Files
|
||||
- [src/index.ts]: Main entry
|
||||
- [src/api/]: API routes
|
||||
- [docs/]: Documentation
|
||||
|
||||
## Key Concepts
|
||||
- Concept 1: Brief explanation
|
||||
- Concept 2: Brief explanation
|
||||
```
|
||||
|
||||
### MCP-Ready Documentation
|
||||
|
||||
For RAG indexing:
|
||||
- Clear H1-H3 hierarchy
|
||||
- JSON/YAML examples for data structures
|
||||
- Mermaid diagrams for flows
|
||||
- Self-contained sections
|
||||
|
||||
---
|
||||
|
||||
## 7. Structure Principles
|
||||
|
||||
| Principle | Why |
|
||||
|-----------|-----|
|
||||
| **Scannable** | Headers, lists, tables |
|
||||
| **Examples first** | Show, don't just tell |
|
||||
| **Progressive detail** | Simple → Complex |
|
||||
| **Up to date** | Outdated = misleading |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Templates are starting points. Adapt to your project's needs.
|
||||
119
skills/game-development/2d-games/SKILL.md
Normal file
119
skills/game-development/2d-games/SKILL.md
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
name: 2d-games
|
||||
description: 2D game development principles. Sprites, tilemaps, physics, camera.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# 2D Game Development
|
||||
|
||||
> Principles for 2D game systems.
|
||||
|
||||
---
|
||||
|
||||
## 1. Sprite Systems
|
||||
|
||||
### Sprite Organization
|
||||
|
||||
| Component | Purpose |
|
||||
|-----------|---------|
|
||||
| **Atlas** | Combine textures, reduce draw calls |
|
||||
| **Animation** | Frame sequences |
|
||||
| **Pivot** | Rotation/scale origin |
|
||||
| **Layering** | Z-order control |
|
||||
|
||||
### Animation Principles
|
||||
|
||||
- Frame rate: 8-24 FPS typical
|
||||
- Squash and stretch for impact
|
||||
- Anticipation before action
|
||||
- Follow-through after action
|
||||
|
||||
---
|
||||
|
||||
## 2. Tilemap Design
|
||||
|
||||
### Tile Considerations
|
||||
|
||||
| Factor | Recommendation |
|
||||
|--------|----------------|
|
||||
| **Size** | 16x16, 32x32, 64x64 |
|
||||
| **Auto-tiling** | Use for terrain |
|
||||
| **Collision** | Simplified shapes |
|
||||
|
||||
### Layers
|
||||
|
||||
| Layer | Content |
|
||||
|-------|---------|
|
||||
| Background | Non-interactive scenery |
|
||||
| Terrain | Walkable ground |
|
||||
| Props | Interactive objects |
|
||||
| Foreground | Parallax overlay |
|
||||
|
||||
---
|
||||
|
||||
## 3. 2D Physics
|
||||
|
||||
### Collision Shapes
|
||||
|
||||
| Shape | Use Case |
|
||||
|-------|----------|
|
||||
| Box | Rectangular objects |
|
||||
| Circle | Balls, rounded |
|
||||
| Capsule | Characters |
|
||||
| Polygon | Complex shapes |
|
||||
|
||||
### Physics Considerations
|
||||
|
||||
- Pixel-perfect vs physics-based
|
||||
- Fixed timestep for consistency
|
||||
- Layers for filtering
|
||||
|
||||
---
|
||||
|
||||
## 4. Camera Systems
|
||||
|
||||
### Camera Types
|
||||
|
||||
| Type | Use |
|
||||
|------|-----|
|
||||
| **Follow** | Track player |
|
||||
| **Look-ahead** | Anticipate movement |
|
||||
| **Multi-target** | Two-player |
|
||||
| **Room-based** | Metroidvania |
|
||||
|
||||
### Screen Shake
|
||||
|
||||
- Short duration (50-200ms)
|
||||
- Diminishing intensity
|
||||
- Use sparingly
|
||||
|
||||
---
|
||||
|
||||
## 5. Genre Patterns
|
||||
|
||||
### Platformer
|
||||
|
||||
- Coyote time (leniency after edge)
|
||||
- Jump buffering
|
||||
- Variable jump height
|
||||
|
||||
### Top-down
|
||||
|
||||
- 8-directional or free movement
|
||||
- Aim-based or auto-aim
|
||||
- Consider rotation or not
|
||||
|
||||
---
|
||||
|
||||
## 6. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Separate textures | Use atlases |
|
||||
| Complex collision shapes | Simplified collision |
|
||||
| Jittery camera | Smooth following |
|
||||
| Pixel-perfect on physics | Choose one approach |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** 2D is about clarity. Every pixel should communicate.
|
||||
135
skills/game-development/3d-games/SKILL.md
Normal file
135
skills/game-development/3d-games/SKILL.md
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
name: 3d-games
|
||||
description: 3D game development principles. Rendering, shaders, physics, cameras.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# 3D Game Development
|
||||
|
||||
> Principles for 3D game systems.
|
||||
|
||||
---
|
||||
|
||||
## 1. Rendering Pipeline
|
||||
|
||||
### Stages
|
||||
|
||||
```
|
||||
1. Vertex Processing → Transform geometry
|
||||
2. Rasterization → Convert to pixels
|
||||
3. Fragment Processing → Color pixels
|
||||
4. Output → To screen
|
||||
```
|
||||
|
||||
### Optimization Principles
|
||||
|
||||
| Technique | Purpose |
|
||||
|-----------|---------|
|
||||
| **Frustum culling** | Don't render off-screen |
|
||||
| **Occlusion culling** | Don't render hidden |
|
||||
| **LOD** | Less detail at distance |
|
||||
| **Batching** | Combine draw calls |
|
||||
|
||||
---
|
||||
|
||||
## 2. Shader Principles
|
||||
|
||||
### Shader Types
|
||||
|
||||
| Type | Purpose |
|
||||
|------|---------|
|
||||
| **Vertex** | Position, normals |
|
||||
| **Fragment/Pixel** | Color, lighting |
|
||||
| **Compute** | General computation |
|
||||
|
||||
### When to Write Custom Shaders
|
||||
|
||||
- Special effects (water, fire, portals)
|
||||
- Stylized rendering (toon, sketch)
|
||||
- Performance optimization
|
||||
- Unique visual identity
|
||||
|
||||
---
|
||||
|
||||
## 3. 3D Physics
|
||||
|
||||
### Collision Shapes
|
||||
|
||||
| Shape | Use Case |
|
||||
|-------|----------|
|
||||
| **Box** | Buildings, crates |
|
||||
| **Sphere** | Balls, quick checks |
|
||||
| **Capsule** | Characters |
|
||||
| **Mesh** | Terrain (expensive) |
|
||||
|
||||
### Principles
|
||||
|
||||
- Simple colliders, complex visuals
|
||||
- Layer-based filtering
|
||||
- Raycasting for line-of-sight
|
||||
|
||||
---
|
||||
|
||||
## 4. Camera Systems
|
||||
|
||||
### Camera Types
|
||||
|
||||
| Type | Use |
|
||||
|------|-----|
|
||||
| **Third-person** | Action, adventure |
|
||||
| **First-person** | Immersive, FPS |
|
||||
| **Isometric** | Strategy, RPG |
|
||||
| **Orbital** | Inspection, editors |
|
||||
|
||||
### Camera Feel
|
||||
|
||||
- Smooth following (lerp)
|
||||
- Collision avoidance
|
||||
- Look-ahead for movement
|
||||
- FOV changes for speed
|
||||
|
||||
---
|
||||
|
||||
## 5. Lighting
|
||||
|
||||
### Light Types
|
||||
|
||||
| Type | Use |
|
||||
|------|-----|
|
||||
| **Directional** | Sun, moon |
|
||||
| **Point** | Lamps, torches |
|
||||
| **Spot** | Flashlight, stage |
|
||||
| **Ambient** | Base illumination |
|
||||
|
||||
### Performance Consideration
|
||||
|
||||
- Real-time shadows are expensive
|
||||
- Bake when possible
|
||||
- Shadow cascades for large worlds
|
||||
|
||||
---
|
||||
|
||||
## 6. Level of Detail (LOD)
|
||||
|
||||
### LOD Strategy
|
||||
|
||||
| Distance | Model |
|
||||
|----------|-------|
|
||||
| Near | Full detail |
|
||||
| Medium | 50% triangles |
|
||||
| Far | 25% or billboard |
|
||||
|
||||
---
|
||||
|
||||
## 7. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Mesh colliders everywhere | Simple shapes |
|
||||
| Real-time shadows on mobile | Baked or blob shadows |
|
||||
| One LOD for all distances | Distance-based LOD |
|
||||
| Unoptimized shaders | Profile and simplify |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** 3D is about illusion. Create the impression of detail, not the detail itself.
|
||||
167
skills/game-development/SKILL.md
Normal file
167
skills/game-development/SKILL.md
Normal file
@@ -0,0 +1,167 @@
|
||||
---
|
||||
name: game-development
|
||||
description: Game development orchestrator. Routes to platform-specific skills based on project needs.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# Game Development
|
||||
|
||||
> **Orchestrator skill** that provides core principles and routes to specialized sub-skills.
|
||||
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
You are working on a game development project. This skill teaches the PRINCIPLES of game development and directs you to the right sub-skill based on context.
|
||||
|
||||
---
|
||||
|
||||
## Sub-Skill Routing
|
||||
|
||||
### Platform Selection
|
||||
|
||||
| If the game targets... | Use Sub-Skill |
|
||||
|------------------------|---------------|
|
||||
| Web browsers (HTML5, WebGL) | `game-development/web-games` |
|
||||
| Mobile (iOS, Android) | `game-development/mobile-games` |
|
||||
| PC (Steam, Desktop) | `game-development/pc-games` |
|
||||
| VR/AR headsets | `game-development/vr-ar` |
|
||||
|
||||
### Dimension Selection
|
||||
|
||||
| If the game is... | Use Sub-Skill |
|
||||
|-------------------|---------------|
|
||||
| 2D (sprites, tilemaps) | `game-development/2d-games` |
|
||||
| 3D (meshes, shaders) | `game-development/3d-games` |
|
||||
|
||||
### Specialty Areas
|
||||
|
||||
| If you need... | Use Sub-Skill |
|
||||
|----------------|---------------|
|
||||
| GDD, balancing, player psychology | `game-development/game-design` |
|
||||
| Multiplayer, networking | `game-development/multiplayer` |
|
||||
| Visual style, asset pipeline, animation | `game-development/game-art` |
|
||||
| Sound design, music, adaptive audio | `game-development/game-audio` |
|
||||
|
||||
---
|
||||
|
||||
## Core Principles (All Platforms)
|
||||
|
||||
### 1. The Game Loop
|
||||
|
||||
Every game, regardless of platform, follows this pattern:
|
||||
|
||||
```
|
||||
INPUT → Read player actions
|
||||
UPDATE → Process game logic (fixed timestep)
|
||||
RENDER → Draw the frame (interpolated)
|
||||
```
|
||||
|
||||
**Fixed Timestep Rule:**
|
||||
- Physics/logic: Fixed rate (e.g., 50Hz)
|
||||
- Rendering: As fast as possible
|
||||
- Interpolate between states for smooth visuals
|
||||
|
||||
---
|
||||
|
||||
### 2. Pattern Selection Matrix
|
||||
|
||||
| Pattern | Use When | Example |
|
||||
|---------|----------|---------|
|
||||
| **State Machine** | 3-5 discrete states | Player: Idle→Walk→Jump |
|
||||
| **Object Pooling** | Frequent spawn/destroy | Bullets, particles |
|
||||
| **Observer/Events** | Cross-system communication | Health→UI updates |
|
||||
| **ECS** | Thousands of similar entities | RTS units, particles |
|
||||
| **Command** | Undo, replay, networking | Input recording |
|
||||
| **Behavior Tree** | Complex AI decisions | Enemy AI |
|
||||
|
||||
**Decision Rule:** Start with State Machine. Add ECS only when performance demands.
|
||||
|
||||
---
|
||||
|
||||
### 3. Input Abstraction
|
||||
|
||||
Abstract input into ACTIONS, not raw keys:
|
||||
|
||||
```
|
||||
"jump" → Space, Gamepad A, Touch tap
|
||||
"move" → WASD, Left stick, Virtual joystick
|
||||
```
|
||||
|
||||
**Why:** Enables multi-platform, rebindable controls.
|
||||
|
||||
---
|
||||
|
||||
### 4. Performance Budget (60 FPS = 16.67ms)
|
||||
|
||||
| System | Budget |
|
||||
|--------|--------|
|
||||
| Input | 1ms |
|
||||
| Physics | 3ms |
|
||||
| AI | 2ms |
|
||||
| Game Logic | 4ms |
|
||||
| Rendering | 5ms |
|
||||
| Buffer | 1.67ms |
|
||||
|
||||
**Optimization Priority:**
|
||||
1. Algorithm (O(n²) → O(n log n))
|
||||
2. Batching (reduce draw calls)
|
||||
3. Pooling (avoid GC spikes)
|
||||
4. LOD (detail by distance)
|
||||
5. Culling (skip invisible)
|
||||
|
||||
---
|
||||
|
||||
### 5. AI Selection by Complexity
|
||||
|
||||
| AI Type | Complexity | Use When |
|
||||
|---------|------------|----------|
|
||||
| **FSM** | Simple | 3-5 states, predictable behavior |
|
||||
| **Behavior Tree** | Medium | Modular, designer-friendly |
|
||||
| **GOAP** | High | Emergent, planning-based |
|
||||
| **Utility AI** | High | Scoring-based decisions |
|
||||
|
||||
---
|
||||
|
||||
### 6. Collision Strategy
|
||||
|
||||
| Type | Best For |
|
||||
|------|----------|
|
||||
| **AABB** | Rectangles, fast checks |
|
||||
| **Circle** | Round objects, cheap |
|
||||
| **Spatial Hash** | Many similar-sized objects |
|
||||
| **Quadtree** | Large worlds, varying sizes |
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns (Universal)
|
||||
|
||||
| Don't | Do |
|
||||
|-------|-----|
|
||||
| Update everything every frame | Use events, dirty flags |
|
||||
| Create objects in hot loops | Object pooling |
|
||||
| Cache nothing | Cache references |
|
||||
| Optimize without profiling | Profile first |
|
||||
| Mix input with logic | Abstract input layer |
|
||||
|
||||
---
|
||||
|
||||
## Routing Examples
|
||||
|
||||
### Example 1: "I want to make a browser-based 2D platformer"
|
||||
→ Start with `game-development/web-games` for framework selection
|
||||
→ Then `game-development/2d-games` for sprite/tilemap patterns
|
||||
→ Reference `game-development/game-design` for level design
|
||||
|
||||
### Example 2: "Mobile puzzle game for iOS and Android"
|
||||
→ Start with `game-development/mobile-games` for touch input and stores
|
||||
→ Use `game-development/game-design` for puzzle balancing
|
||||
|
||||
### Example 3: "Multiplayer VR shooter"
|
||||
→ `game-development/vr-ar` for comfort and immersion
|
||||
→ `game-development/3d-games` for rendering
|
||||
→ `game-development/multiplayer` for networking
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Great games come from iteration, not perfection. Prototype fast, then polish.
|
||||
185
skills/game-development/game-art/SKILL.md
Normal file
185
skills/game-development/game-art/SKILL.md
Normal file
@@ -0,0 +1,185 @@
|
||||
---
|
||||
name: game-art
|
||||
description: Game art principles. Visual style selection, asset pipeline, animation workflow.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Game Art Principles
|
||||
|
||||
> Visual design thinking for games - style selection, asset pipelines, and art direction.
|
||||
|
||||
---
|
||||
|
||||
## 1. Art Style Selection
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
What feeling should the game evoke?
|
||||
│
|
||||
├── Nostalgic / Retro
|
||||
│ ├── Limited palette? → Pixel Art
|
||||
│ └── Hand-drawn feel? → Vector / Flash style
|
||||
│
|
||||
├── Realistic / Immersive
|
||||
│ ├── High budget? → PBR 3D
|
||||
│ └── Stylized realism? → Hand-painted textures
|
||||
│
|
||||
├── Approachable / Casual
|
||||
│ ├── Clean shapes? → Flat / Minimalist
|
||||
│ └── Soft feel? → Gradient / Soft shadows
|
||||
│
|
||||
└── Unique / Experimental
|
||||
└── Define custom style guide
|
||||
```
|
||||
|
||||
### Style Comparison Matrix
|
||||
|
||||
| Style | Production Speed | Skill Floor | Scalability | Best For |
|
||||
|-------|------------------|-------------|-------------|----------|
|
||||
| **Pixel Art** | Medium | Medium | Hard to hire | Indie, retro |
|
||||
| **Vector/Flat** | Fast | Low | Easy | Mobile, casual |
|
||||
| **Hand-painted** | Slow | High | Medium | Fantasy, stylized |
|
||||
| **PBR 3D** | Slow | High | AAA pipeline | Realistic games |
|
||||
| **Low-poly** | Fast | Medium | Easy | Indie 3D |
|
||||
| **Cel-shaded** | Medium | Medium | Medium | Anime, cartoon |
|
||||
|
||||
---
|
||||
|
||||
## 2. Asset Pipeline Decisions
|
||||
|
||||
### 2D Pipeline
|
||||
|
||||
| Phase | Tool Options | Output |
|
||||
|-------|--------------|--------|
|
||||
| **Concept** | Paper, Procreate, Photoshop | Reference sheet |
|
||||
| **Creation** | Aseprite, Photoshop, Krita | Individual sprites |
|
||||
| **Atlas** | TexturePacker, Aseprite | Spritesheet |
|
||||
| **Animation** | Spine, DragonBones, Frame-by-frame | Animation data |
|
||||
| **Integration** | Engine import | Game-ready assets |
|
||||
|
||||
### 3D Pipeline
|
||||
|
||||
| Phase | Tool Options | Output |
|
||||
|-------|--------------|--------|
|
||||
| **Concept** | 2D art, Blockout | Reference |
|
||||
| **Modeling** | Blender, Maya, 3ds Max | High-poly mesh |
|
||||
| **Retopology** | Blender, ZBrush | Game-ready mesh |
|
||||
| **UV/Texturing** | Substance Painter, Blender | Texture maps |
|
||||
| **Rigging** | Blender, Maya | Skeletal rig |
|
||||
| **Animation** | Blender, Maya, Mixamo | Animation clips |
|
||||
| **Export** | FBX, glTF | Engine-ready |
|
||||
|
||||
---
|
||||
|
||||
## 3. Color Theory Decisions
|
||||
|
||||
### Palette Selection
|
||||
|
||||
| Goal | Strategy | Example |
|
||||
|------|----------|---------|
|
||||
| **Harmony** | Complementary or analogous | Nature games |
|
||||
| **Contrast** | High saturation differences | Action games |
|
||||
| **Mood** | Warm/cool temperature | Horror, cozy |
|
||||
| **Readability** | Value contrast over hue | Gameplay clarity |
|
||||
|
||||
### Color Principles
|
||||
|
||||
- **Hierarchy:** Important elements should pop
|
||||
- **Consistency:** Same object = same color family
|
||||
- **Context:** Colors read differently on backgrounds
|
||||
- **Accessibility:** Don't rely only on color
|
||||
|
||||
---
|
||||
|
||||
## 4. Animation Principles
|
||||
|
||||
### The 12 Principles (Applied to Games)
|
||||
|
||||
| Principle | Game Application |
|
||||
|-----------|------------------|
|
||||
| **Squash & Stretch** | Jump arcs, impacts |
|
||||
| **Anticipation** | Wind-up before attack |
|
||||
| **Staging** | Clear silhouettes |
|
||||
| **Follow-through** | Hair, capes after movement |
|
||||
| **Slow in/out** | Easing on transitions |
|
||||
| **Arcs** | Natural movement paths |
|
||||
| **Secondary Action** | Breathing, blinking |
|
||||
| **Timing** | Frame count = weight/speed |
|
||||
| **Exaggeration** | Readable from distance |
|
||||
| **Appeal** | Memorable design |
|
||||
|
||||
### Frame Count Guidelines
|
||||
|
||||
| Action Type | Typical Frames | Feel |
|
||||
|-------------|----------------|------|
|
||||
| Idle breathing | 4-8 | Subtle |
|
||||
| Walk cycle | 6-12 | Smooth |
|
||||
| Run cycle | 4-8 | Energetic |
|
||||
| Attack | 3-6 | Snappy |
|
||||
| Death | 8-16 | Dramatic |
|
||||
|
||||
---
|
||||
|
||||
## 5. Resolution & Scale Decisions
|
||||
|
||||
### 2D Resolution by Platform
|
||||
|
||||
| Platform | Base Resolution | Sprite Scale |
|
||||
|----------|-----------------|--------------|
|
||||
| Mobile | 1080p | 64-128px characters |
|
||||
| Desktop | 1080p-4K | 128-256px characters |
|
||||
| Pixel art | 320x180 to 640x360 | 16-32px characters |
|
||||
|
||||
### Consistency Rule
|
||||
|
||||
Choose a base unit and stick to it:
|
||||
- Pixel art: Work at 1x, scale up (never down)
|
||||
- HD art: Define DPI, maintain ratio
|
||||
- 3D: 1 unit = 1 meter (industry standard)
|
||||
|
||||
---
|
||||
|
||||
## 6. Asset Organization
|
||||
|
||||
### Naming Convention
|
||||
|
||||
```
|
||||
[type]_[object]_[variant]_[state].[ext]
|
||||
|
||||
Examples:
|
||||
spr_player_idle_01.png
|
||||
tex_stone_wall_normal.png
|
||||
mesh_tree_oak_lod2.fbx
|
||||
```
|
||||
|
||||
### Folder Structure Principle
|
||||
|
||||
```
|
||||
assets/
|
||||
├── characters/
|
||||
│ ├── player/
|
||||
│ └── enemies/
|
||||
├── environment/
|
||||
│ ├── props/
|
||||
│ └── tiles/
|
||||
├── ui/
|
||||
├── effects/
|
||||
└── audio/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Anti-Patterns
|
||||
|
||||
| Don't | Do |
|
||||
|-------|-----|
|
||||
| Mix art styles randomly | Define and follow style guide |
|
||||
| Work at final resolution only | Create at source resolution |
|
||||
| Ignore silhouette readability | Test at gameplay distance |
|
||||
| Over-detail background | Focus detail on player area |
|
||||
| Skip color testing | Test on target display |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Art serves gameplay. If it doesn't help the player, it's decoration.
|
||||
190
skills/game-development/game-audio/SKILL.md
Normal file
190
skills/game-development/game-audio/SKILL.md
Normal file
@@ -0,0 +1,190 @@
|
||||
---
|
||||
name: game-audio
|
||||
description: Game audio principles. Sound design, music integration, adaptive audio systems.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Game Audio Principles
|
||||
|
||||
> Sound design and music integration for immersive game experiences.
|
||||
|
||||
---
|
||||
|
||||
## 1. Audio Category System
|
||||
|
||||
### Category Definitions
|
||||
|
||||
| Category | Behavior | Examples |
|
||||
|----------|----------|----------|
|
||||
| **Music** | Looping, crossfade, ducking | BGM, combat music |
|
||||
| **SFX** | One-shot, 3D positioned | Footsteps, impacts |
|
||||
| **Ambient** | Looping, background layer | Wind, crowd, forest |
|
||||
| **UI** | Immediate, non-3D | Button clicks, notifications |
|
||||
| **Voice** | Priority, ducking trigger | Dialogue, announcer |
|
||||
|
||||
### Priority Hierarchy
|
||||
|
||||
```
|
||||
When sounds compete for channels:
|
||||
|
||||
1. Voice (highest - always audible)
|
||||
2. Player SFX (feedback critical)
|
||||
3. Enemy SFX (gameplay important)
|
||||
4. Music (mood, but duckable)
|
||||
5. Ambient (lowest - can drop)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Sound Design Decisions
|
||||
|
||||
### SFX Creation Approach
|
||||
|
||||
| Approach | When to Use | Trade-offs |
|
||||
|----------|-------------|------------|
|
||||
| **Recording** | Realistic needs | High quality, time intensive |
|
||||
| **Synthesis** | Sci-fi, retro, UI | Unique, requires skill |
|
||||
| **Library samples** | Fast production | Common sounds, licensing |
|
||||
| **Layering** | Complex sounds | Best results, more work |
|
||||
|
||||
### Layering Structure
|
||||
|
||||
| Layer | Purpose | Example: Gunshot |
|
||||
|-------|---------|------------------|
|
||||
| **Attack** | Initial transient | Click, snap |
|
||||
| **Body** | Main character | Boom, blast |
|
||||
| **Tail** | Decay, room | Reverb, echo |
|
||||
| **Sweetener** | Special sauce | Shell casing, mechanical |
|
||||
|
||||
---
|
||||
|
||||
## 3. Music Integration
|
||||
|
||||
### Music State System
|
||||
|
||||
```
|
||||
Game State → Music Response
|
||||
│
|
||||
├── Menu → Calm, loopable theme
|
||||
├── Exploration → Ambient, atmospheric
|
||||
├── Combat detected → Transition to tension
|
||||
├── Combat engaged → Full battle music
|
||||
├── Victory → Stinger + calm transition
|
||||
├── Defeat → Somber stinger
|
||||
└── Boss → Unique, multi-phase track
|
||||
```
|
||||
|
||||
### Transition Techniques
|
||||
|
||||
| Technique | Use When | Feel |
|
||||
|-----------|----------|------|
|
||||
| **Crossfade** | Smooth mood shift | Gradual |
|
||||
| **Stinger** | Immediate event | Dramatic |
|
||||
| **Stem mixing** | Dynamic intensity | Seamless |
|
||||
| **Beat-synced** | Rhythmic gameplay | Musical |
|
||||
| **Queue point** | Next natural break | Clean |
|
||||
|
||||
---
|
||||
|
||||
## 4. Adaptive Audio Decisions
|
||||
|
||||
### Intensity Parameters
|
||||
|
||||
| Parameter | Affects | Example |
|
||||
|-----------|---------|---------|
|
||||
| **Threat level** | Music intensity | Enemy count |
|
||||
| **Health** | Filter, reverb | Low health = muffled |
|
||||
| **Speed** | Tempo, energy | Racing speed |
|
||||
| **Environment** | Reverb, EQ | Cave vs outdoor |
|
||||
| **Time of day** | Mood, volume | Night = quieter |
|
||||
|
||||
### Vertical vs Horizontal
|
||||
|
||||
| System | What Changes | Best For |
|
||||
|--------|--------------|----------|
|
||||
| **Vertical (layers)** | Add/remove instrument layers | Intensity scaling |
|
||||
| **Horizontal (segments)** | Different music sections | State changes |
|
||||
| **Combined** | Both | AAA adaptive scores |
|
||||
|
||||
---
|
||||
|
||||
## 5. 3D Audio Decisions
|
||||
|
||||
### Spatialization
|
||||
|
||||
| Element | 3D Positioned? | Reason |
|
||||
|---------|----------------|--------|
|
||||
| Player footsteps | No (or subtle) | Always audible |
|
||||
| Enemy footsteps | Yes | Directional awareness |
|
||||
| Gunfire | Yes | Combat awareness |
|
||||
| Music | No | Mood, non-diegetic |
|
||||
| Ambient zone | Yes (area) | Environmental |
|
||||
| UI sounds | No | Interface feedback |
|
||||
|
||||
### Distance Behavior
|
||||
|
||||
| Distance | Sound Behavior |
|
||||
|----------|----------------|
|
||||
| **Near** | Full volume, full frequency |
|
||||
| **Medium** | Volume falloff, high-freq rolloff |
|
||||
| **Far** | Low volume, low-pass filter |
|
||||
| **Max** | Silent or ambient hint |
|
||||
|
||||
---
|
||||
|
||||
## 6. Platform Considerations
|
||||
|
||||
### Format Selection
|
||||
|
||||
| Platform | Recommended Format | Reason |
|
||||
|----------|-------------------|--------|
|
||||
| PC | OGG Vorbis, WAV | Quality, no licensing |
|
||||
| Console | Platform-specific | Certification |
|
||||
| Mobile | MP3, AAC | Size, compatibility |
|
||||
| Web | WebM/Opus, MP3 fallback | Browser support |
|
||||
|
||||
### Memory Budget
|
||||
|
||||
| Game Type | Audio Budget | Strategy |
|
||||
|-----------|--------------|----------|
|
||||
| Mobile casual | 10-50 MB | Compressed, fewer variants |
|
||||
| PC indie | 100-500 MB | Quality focus |
|
||||
| AAA | 1+ GB | Full quality, many variants |
|
||||
|
||||
---
|
||||
|
||||
## 7. Mix Hierarchy
|
||||
|
||||
### Volume Balance Reference
|
||||
|
||||
| Category | Relative Level | Notes |
|
||||
|----------|----------------|-------|
|
||||
| **Voice** | 0 dB (reference) | Always clear |
|
||||
| **Player SFX** | -3 to -6 dB | Prominent but not harsh |
|
||||
| **Music** | -6 to -12 dB | Foundation, ducks for voice |
|
||||
| **Enemy SFX** | -6 to -9 dB | Important but not dominant |
|
||||
| **Ambient** | -12 to -18 dB | Subtle background |
|
||||
|
||||
### Ducking Rules
|
||||
|
||||
| When | Duck What | Amount |
|
||||
|------|-----------|--------|
|
||||
| Voice plays | Music, Ambient | -6 to -9 dB |
|
||||
| Explosion | All except explosion | Brief duck |
|
||||
| Menu open | Gameplay audio | -3 to -6 dB |
|
||||
|
||||
---
|
||||
|
||||
## 8. Anti-Patterns
|
||||
|
||||
| Don't | Do |
|
||||
|-------|-----|
|
||||
| Play same sound repeatedly | Use variations (3-5 per sound) |
|
||||
| Max volume everything | Use proper mix hierarchy |
|
||||
| Ignore silence | Silence creates contrast |
|
||||
| One music track loops forever | Provide variety, transitions |
|
||||
| Skip audio in prototype | Placeholder audio matters |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** 50% of the game experience is audio. A muted game loses half its soul.
|
||||
129
skills/game-development/game-design/SKILL.md
Normal file
129
skills/game-development/game-design/SKILL.md
Normal file
@@ -0,0 +1,129 @@
|
||||
---
|
||||
name: game-design
|
||||
description: Game design principles. GDD structure, balancing, player psychology, progression.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Game Design Principles
|
||||
|
||||
> Design thinking for engaging games.
|
||||
|
||||
---
|
||||
|
||||
## 1. Core Loop Design
|
||||
|
||||
### The 30-Second Test
|
||||
|
||||
```
|
||||
Every game needs a fun 30-second loop:
|
||||
1. ACTION → Player does something
|
||||
2. FEEDBACK → Game responds
|
||||
3. REWARD → Player feels good
|
||||
4. REPEAT
|
||||
```
|
||||
|
||||
### Loop Examples
|
||||
|
||||
| Genre | Core Loop |
|
||||
|-------|-----------|
|
||||
| Platformer | Run → Jump → Land → Collect |
|
||||
| Shooter | Aim → Shoot → Kill → Loot |
|
||||
| Puzzle | Observe → Think → Solve → Advance |
|
||||
| RPG | Explore → Fight → Level → Gear |
|
||||
|
||||
---
|
||||
|
||||
## 2. Game Design Document (GDD)
|
||||
|
||||
### Essential Sections
|
||||
|
||||
| Section | Content |
|
||||
|---------|---------|
|
||||
| **Pitch** | One-sentence description |
|
||||
| **Core Loop** | 30-second gameplay |
|
||||
| **Mechanics** | How systems work |
|
||||
| **Progression** | How player advances |
|
||||
| **Art Style** | Visual direction |
|
||||
| **Audio** | Sound direction |
|
||||
|
||||
### Principles
|
||||
|
||||
- Keep it living (update regularly)
|
||||
- Visuals help communicate
|
||||
- Less is more (start small)
|
||||
|
||||
---
|
||||
|
||||
## 3. Player Psychology
|
||||
|
||||
### Motivation Types
|
||||
|
||||
| Type | Driven By |
|
||||
|------|-----------|
|
||||
| **Achiever** | Goals, completion |
|
||||
| **Explorer** | Discovery, secrets |
|
||||
| **Socializer** | Interaction, community |
|
||||
| **Killer** | Competition, dominance |
|
||||
|
||||
### Reward Schedules
|
||||
|
||||
| Schedule | Effect | Use |
|
||||
|----------|--------|-----|
|
||||
| **Fixed** | Predictable | Milestone rewards |
|
||||
| **Variable** | Addictive | Loot drops |
|
||||
| **Ratio** | Effort-based | Grind games |
|
||||
|
||||
---
|
||||
|
||||
## 4. Difficulty Balancing
|
||||
|
||||
### Flow State
|
||||
|
||||
```
|
||||
Too Hard → Frustration → Quit
|
||||
Too Easy → Boredom → Quit
|
||||
Just Right → Flow → Engagement
|
||||
```
|
||||
|
||||
### Balancing Strategies
|
||||
|
||||
| Strategy | How |
|
||||
|----------|-----|
|
||||
| **Dynamic** | Adjust to player skill |
|
||||
| **Selection** | Let player choose |
|
||||
| **Accessibility** | Options for all |
|
||||
|
||||
---
|
||||
|
||||
## 5. Progression Design
|
||||
|
||||
### Progression Types
|
||||
|
||||
| Type | Example |
|
||||
|------|---------|
|
||||
| **Skill** | Player gets better |
|
||||
| **Power** | Character gets stronger |
|
||||
| **Content** | New areas unlock |
|
||||
| **Story** | Narrative advances |
|
||||
|
||||
### Pacing Principles
|
||||
|
||||
- Early wins (hook quickly)
|
||||
- Gradually increase challenge
|
||||
- Rest beats between intensity
|
||||
- Meaningful choices
|
||||
|
||||
---
|
||||
|
||||
## 6. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Design in isolation | Playtest constantly |
|
||||
| Polish before fun | Prototype first |
|
||||
| Force one way to play | Allow player expression |
|
||||
| Punish excessively | Reward progress |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Fun is discovered through iteration, not designed on paper.
|
||||
108
skills/game-development/mobile-games/SKILL.md
Normal file
108
skills/game-development/mobile-games/SKILL.md
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
name: mobile-games
|
||||
description: Mobile game development principles. Touch input, battery, performance, app stores.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# Mobile Game Development
|
||||
|
||||
> Platform constraints and optimization principles.
|
||||
|
||||
---
|
||||
|
||||
## 1. Platform Considerations
|
||||
|
||||
### Key Constraints
|
||||
|
||||
| Constraint | Strategy |
|
||||
|------------|----------|
|
||||
| **Touch input** | Large hit areas, gestures |
|
||||
| **Battery** | Limit CPU/GPU usage |
|
||||
| **Thermal** | Throttle when hot |
|
||||
| **Screen size** | Responsive UI |
|
||||
| **Interruptions** | Pause on background |
|
||||
|
||||
---
|
||||
|
||||
## 2. Touch Input Principles
|
||||
|
||||
### Touch vs Controller
|
||||
|
||||
| Touch | Desktop/Console |
|
||||
|-------|-----------------|
|
||||
| Imprecise | Precise |
|
||||
| Occludes screen | No occlusion |
|
||||
| Limited buttons | Many buttons |
|
||||
| Gestures available | Buttons/sticks |
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Minimum touch target: 44x44 points
|
||||
- Visual feedback on touch
|
||||
- Avoid precise timing requirements
|
||||
- Support both portrait and landscape
|
||||
|
||||
---
|
||||
|
||||
## 3. Performance Targets
|
||||
|
||||
### Thermal Management
|
||||
|
||||
| Action | Trigger |
|
||||
|--------|---------|
|
||||
| Reduce quality | Device warm |
|
||||
| Limit FPS | Device hot |
|
||||
| Pause effects | Critical temp |
|
||||
|
||||
### Battery Optimization
|
||||
|
||||
- 30 FPS often sufficient
|
||||
- Sleep when paused
|
||||
- Minimize GPS/network
|
||||
- Dark mode saves OLED battery
|
||||
|
||||
---
|
||||
|
||||
## 4. App Store Requirements
|
||||
|
||||
### iOS (App Store)
|
||||
|
||||
| Requirement | Note |
|
||||
|-------------|------|
|
||||
| Privacy labels | Required |
|
||||
| Account deletion | If account creation exists |
|
||||
| Screenshots | For all device sizes |
|
||||
|
||||
### Android (Google Play)
|
||||
|
||||
| Requirement | Note |
|
||||
|-------------|------|
|
||||
| Target API | Current year's SDK |
|
||||
| 64-bit | Required |
|
||||
| App bundles | Recommended |
|
||||
|
||||
---
|
||||
|
||||
## 5. Monetization Models
|
||||
|
||||
| Model | Best For |
|
||||
|-------|----------|
|
||||
| **Premium** | Quality games, loyal audience |
|
||||
| **Free + IAP** | Casual, progression-based |
|
||||
| **Ads** | Hyper-casual, high volume |
|
||||
| **Subscription** | Content updates, multiplayer |
|
||||
|
||||
---
|
||||
|
||||
## 6. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Desktop controls on mobile | Design for touch |
|
||||
| Ignore battery drain | Monitor thermals |
|
||||
| Force landscape | Support player preference |
|
||||
| Always-on network | Cache and sync |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Mobile is the most constrained platform. Respect battery and attention.
|
||||
132
skills/game-development/multiplayer/SKILL.md
Normal file
132
skills/game-development/multiplayer/SKILL.md
Normal file
@@ -0,0 +1,132 @@
|
||||
---
|
||||
name: multiplayer
|
||||
description: Multiplayer game development principles. Architecture, networking, synchronization.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# Multiplayer Game Development
|
||||
|
||||
> Networking architecture and synchronization principles.
|
||||
|
||||
---
|
||||
|
||||
## 1. Architecture Selection
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
What type of multiplayer?
|
||||
│
|
||||
├── Competitive / Real-time
|
||||
│ └── Dedicated Server (authoritative)
|
||||
│
|
||||
├── Cooperative / Casual
|
||||
│ └── Host-based (one player is server)
|
||||
│
|
||||
├── Turn-based
|
||||
│ └── Client-server (simple)
|
||||
│
|
||||
└── Massive (MMO)
|
||||
└── Distributed servers
|
||||
```
|
||||
|
||||
### Comparison
|
||||
|
||||
| Architecture | Latency | Cost | Security |
|
||||
|--------------|---------|------|----------|
|
||||
| **Dedicated** | Low | High | Strong |
|
||||
| **P2P** | Variable | Low | Weak |
|
||||
| **Host-based** | Medium | Low | Medium |
|
||||
|
||||
---
|
||||
|
||||
## 2. Synchronization Principles
|
||||
|
||||
### State vs Input
|
||||
|
||||
| Approach | Sync What | Best For |
|
||||
|----------|-----------|----------|
|
||||
| **State Sync** | Game state | Simple, few objects |
|
||||
| **Input Sync** | Player inputs | Action games |
|
||||
| **Hybrid** | Both | Most games |
|
||||
|
||||
### Lag Compensation
|
||||
|
||||
| Technique | Purpose |
|
||||
|-----------|---------|
|
||||
| **Prediction** | Client predicts server |
|
||||
| **Interpolation** | Smooth remote players |
|
||||
| **Reconciliation** | Fix mispredictions |
|
||||
| **Lag compensation** | Rewind for hit detection |
|
||||
|
||||
---
|
||||
|
||||
## 3. Network Optimization
|
||||
|
||||
### Bandwidth Reduction
|
||||
|
||||
| Technique | Savings |
|
||||
|-----------|---------|
|
||||
| **Delta compression** | Send only changes |
|
||||
| **Quantization** | Reduce precision |
|
||||
| **Priority** | Important data first |
|
||||
| **Area of interest** | Only nearby entities |
|
||||
|
||||
### Update Rates
|
||||
|
||||
| Type | Rate |
|
||||
|------|------|
|
||||
| Position | 20-60 Hz |
|
||||
| Health | On change |
|
||||
| Inventory | On change |
|
||||
| Chat | On send |
|
||||
|
||||
---
|
||||
|
||||
## 4. Security Principles
|
||||
|
||||
### Server Authority
|
||||
|
||||
```
|
||||
Client: "I hit the enemy"
|
||||
Server: Validate → did projectile actually hit?
|
||||
→ was player in valid state?
|
||||
→ was timing possible?
|
||||
```
|
||||
|
||||
### Anti-Cheat
|
||||
|
||||
| Cheat | Prevention |
|
||||
|-------|------------|
|
||||
| Speed hack | Server validates movement |
|
||||
| Aimbot | Server validates sight line |
|
||||
| Item dupe | Server owns inventory |
|
||||
| Wall hack | Don't send hidden data |
|
||||
|
||||
---
|
||||
|
||||
## 5. Matchmaking
|
||||
|
||||
### Considerations
|
||||
|
||||
| Factor | Impact |
|
||||
|--------|--------|
|
||||
| **Skill** | Fair matches |
|
||||
| **Latency** | Playable connection |
|
||||
| **Wait time** | Player patience |
|
||||
| **Party size** | Group play |
|
||||
|
||||
---
|
||||
|
||||
## 6. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Trust the client | Server is authority |
|
||||
| Send everything | Send only necessary |
|
||||
| Ignore latency | Design for 100-200ms |
|
||||
| Sync exact positions | Interpolate/predict |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Never trust the client. The server is the source of truth.
|
||||
144
skills/game-development/pc-games/SKILL.md
Normal file
144
skills/game-development/pc-games/SKILL.md
Normal file
@@ -0,0 +1,144 @@
|
||||
---
|
||||
name: pc-games
|
||||
description: PC and console game development principles. Engine selection, platform features, optimization strategies.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# PC/Console Game Development
|
||||
|
||||
> Engine selection and platform-specific principles.
|
||||
|
||||
---
|
||||
|
||||
## 1. Engine Selection
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
What are you building?
|
||||
│
|
||||
├── 2D Game
|
||||
│ ├── Open source important? → Godot
|
||||
│ └── Large team/assets? → Unity
|
||||
│
|
||||
├── 3D Game
|
||||
│ ├── AAA visual quality? → Unreal
|
||||
│ ├── Cross-platform priority? → Unity
|
||||
│ └── Indie/open source? → Godot 4
|
||||
│
|
||||
└── Specific Needs
|
||||
├── DOTS performance? → Unity
|
||||
├── Nanite/Lumen? → Unreal
|
||||
└── Lightweight? → Godot
|
||||
```
|
||||
|
||||
### Comparison
|
||||
|
||||
| Factor | Unity 6 | Godot 4 | Unreal 5 |
|
||||
|--------|---------|---------|----------|
|
||||
| 2D | Good | Excellent | Limited |
|
||||
| 3D | Good | Good | Excellent |
|
||||
| Learning | Medium | Easy | Hard |
|
||||
| Cost | Revenue share | Free | 5% after $1M |
|
||||
| Team | Any | Solo-Medium | Medium-Large |
|
||||
|
||||
---
|
||||
|
||||
## 2. Platform Features
|
||||
|
||||
### Steam Integration
|
||||
|
||||
| Feature | Purpose |
|
||||
|---------|---------|
|
||||
| Achievements | Player goals |
|
||||
| Cloud Saves | Cross-device progress |
|
||||
| Leaderboards | Competition |
|
||||
| Workshop | User mods |
|
||||
| Rich Presence | Show in-game status |
|
||||
|
||||
### Console Requirements
|
||||
|
||||
| Platform | Certification |
|
||||
|----------|--------------|
|
||||
| PlayStation | TRC compliance |
|
||||
| Xbox | XR compliance |
|
||||
| Nintendo | Lotcheck |
|
||||
|
||||
---
|
||||
|
||||
## 3. Controller Support
|
||||
|
||||
### Input Abstraction
|
||||
|
||||
```
|
||||
Map ACTIONS, not buttons:
|
||||
- "confirm" → A (Xbox), Cross (PS), B (Nintendo)
|
||||
- "cancel" → B (Xbox), Circle (PS), A (Nintendo)
|
||||
```
|
||||
|
||||
### Haptic Feedback
|
||||
|
||||
| Intensity | Use |
|
||||
|-----------|-----|
|
||||
| Light | UI feedback |
|
||||
| Medium | Impacts |
|
||||
| Heavy | Major events |
|
||||
|
||||
---
|
||||
|
||||
## 4. Performance Optimization
|
||||
|
||||
### Profiling First
|
||||
|
||||
| Engine | Tool |
|
||||
|--------|------|
|
||||
| Unity | Profiler Window |
|
||||
| Godot | Debugger → Profiler |
|
||||
| Unreal | Unreal Insights |
|
||||
|
||||
### Common Bottlenecks
|
||||
|
||||
| Bottleneck | Solution |
|
||||
|------------|----------|
|
||||
| Draw calls | Batching, atlases |
|
||||
| GC spikes | Object pooling |
|
||||
| Physics | Simpler colliders |
|
||||
| Shaders | LOD shaders |
|
||||
|
||||
---
|
||||
|
||||
## 5. Engine-Specific Principles
|
||||
|
||||
### Unity 6
|
||||
|
||||
- DOTS for performance-critical systems
|
||||
- Burst compiler for hot paths
|
||||
- Addressables for asset streaming
|
||||
|
||||
### Godot 4
|
||||
|
||||
- GDScript for rapid iteration
|
||||
- C# for complex logic
|
||||
- Signals for decoupling
|
||||
|
||||
### Unreal 5
|
||||
|
||||
- Blueprint for designers
|
||||
- C++ for performance
|
||||
- Nanite for high-poly environments
|
||||
- Lumen for dynamic lighting
|
||||
|
||||
---
|
||||
|
||||
## 6. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Choose engine by hype | Choose by project needs |
|
||||
| Ignore platform guidelines | Study certification requirements |
|
||||
| Hardcode input buttons | Abstract to actions |
|
||||
| Skip profiling | Profile early and often |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Engine is a tool. Master the principles, then adapt to any engine.
|
||||
123
skills/game-development/vr-ar/SKILL.md
Normal file
123
skills/game-development/vr-ar/SKILL.md
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
name: vr-ar
|
||||
description: VR/AR development principles. Comfort, interaction, performance requirements.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# VR/AR Development
|
||||
|
||||
> Immersive experience principles.
|
||||
|
||||
---
|
||||
|
||||
## 1. Platform Selection
|
||||
|
||||
### VR Platforms
|
||||
|
||||
| Platform | Use Case |
|
||||
|----------|----------|
|
||||
| **Quest** | Standalone, wireless |
|
||||
| **PCVR** | High fidelity |
|
||||
| **PSVR** | Console market |
|
||||
| **WebXR** | Browser-based |
|
||||
|
||||
### AR Platforms
|
||||
|
||||
| Platform | Use Case |
|
||||
|----------|----------|
|
||||
| **ARKit** | iOS devices |
|
||||
| **ARCore** | Android devices |
|
||||
| **WebXR** | Browser AR |
|
||||
| **HoloLens** | Enterprise |
|
||||
|
||||
---
|
||||
|
||||
## 2. Comfort Principles
|
||||
|
||||
### Motion Sickness Prevention
|
||||
|
||||
| Cause | Solution |
|
||||
|-------|----------|
|
||||
| **Locomotion** | Teleport, snap turn |
|
||||
| **Low FPS** | Maintain 90 FPS |
|
||||
| **Camera shake** | Avoid or minimize |
|
||||
| **Rapid acceleration** | Gradual movement |
|
||||
|
||||
### Comfort Settings
|
||||
|
||||
- Vignette during movement
|
||||
- Snap vs smooth turning
|
||||
- Seated vs standing modes
|
||||
- Height calibration
|
||||
|
||||
---
|
||||
|
||||
## 3. Performance Requirements
|
||||
|
||||
### Target Metrics
|
||||
|
||||
| Platform | FPS | Resolution |
|
||||
|----------|-----|------------|
|
||||
| Quest 2 | 72-90 | 1832x1920 |
|
||||
| Quest 3 | 90-120 | 2064x2208 |
|
||||
| PCVR | 90 | 2160x2160+ |
|
||||
| PSVR2 | 90-120 | 2000x2040 |
|
||||
|
||||
### Frame Budget
|
||||
|
||||
- VR requires consistent frame times
|
||||
- Single dropped frame = visible judder
|
||||
- 90 FPS = 11.11ms budget
|
||||
|
||||
---
|
||||
|
||||
## 4. Interaction Principles
|
||||
|
||||
### Controller Interaction
|
||||
|
||||
| Type | Use |
|
||||
|------|-----|
|
||||
| **Point + click** | UI, distant objects |
|
||||
| **Grab** | Manipulation |
|
||||
| **Gesture** | Magic, special actions |
|
||||
| **Physical** | Throwing, swinging |
|
||||
|
||||
### Hand Tracking
|
||||
|
||||
- More immersive but less precise
|
||||
- Good for: social, casual
|
||||
- Challenging for: action, precision
|
||||
|
||||
---
|
||||
|
||||
## 5. Spatial Design
|
||||
|
||||
### World Scale
|
||||
|
||||
- 1 unit = 1 meter (critical)
|
||||
- Objects must feel right size
|
||||
- Test with real measurements
|
||||
|
||||
### Depth Cues
|
||||
|
||||
| Cue | Importance |
|
||||
|-----|------------|
|
||||
| Stereo | Primary depth |
|
||||
| Motion parallax | Secondary |
|
||||
| Shadows | Grounding |
|
||||
| Occlusion | Layering |
|
||||
|
||||
---
|
||||
|
||||
## 6. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Move camera without player | Player controls camera |
|
||||
| Drop below 90 FPS | Maintain frame rate |
|
||||
| Use tiny UI text | Large, readable text |
|
||||
| Ignore arm length | Scale to player reach |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Comfort is not optional. Sick players don't play.
|
||||
150
skills/game-development/web-games/SKILL.md
Normal file
150
skills/game-development/web-games/SKILL.md
Normal file
@@ -0,0 +1,150 @@
|
||||
---
|
||||
name: web-games
|
||||
description: Web browser game development principles. Framework selection, WebGPU, optimization, PWA.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# Web Browser Game Development
|
||||
|
||||
> Framework selection and browser-specific principles.
|
||||
|
||||
---
|
||||
|
||||
## 1. Framework Selection
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
What type of game?
|
||||
│
|
||||
├── 2D Game
|
||||
│ ├── Full game engine features? → Phaser
|
||||
│ └── Raw rendering power? → PixiJS
|
||||
│
|
||||
├── 3D Game
|
||||
│ ├── Full engine (physics, XR)? → Babylon.js
|
||||
│ └── Rendering focused? → Three.js
|
||||
│
|
||||
└── Hybrid / Canvas
|
||||
└── Custom → Raw Canvas/WebGL
|
||||
```
|
||||
|
||||
### Comparison (2025)
|
||||
|
||||
| Framework | Type | Best For |
|
||||
|-----------|------|----------|
|
||||
| **Phaser 4** | 2D | Full game features |
|
||||
| **PixiJS 8** | 2D | Rendering, UI |
|
||||
| **Three.js** | 3D | Visualizations, lightweight |
|
||||
| **Babylon.js 7** | 3D | Full engine, XR |
|
||||
|
||||
---
|
||||
|
||||
## 2. WebGPU Adoption
|
||||
|
||||
### Browser Support (2025)
|
||||
|
||||
| Browser | Support |
|
||||
|---------|---------|
|
||||
| Chrome | ✅ Since v113 |
|
||||
| Edge | ✅ Since v113 |
|
||||
| Firefox | ✅ Since v131 |
|
||||
| Safari | ✅ Since 18.0 |
|
||||
| **Total** | **~73%** global |
|
||||
|
||||
### Decision
|
||||
|
||||
- **New projects**: Use WebGPU with WebGL fallback
|
||||
- **Legacy support**: Start with WebGL
|
||||
- **Feature detection**: Check `navigator.gpu`
|
||||
|
||||
---
|
||||
|
||||
## 3. Performance Principles
|
||||
|
||||
### Browser Constraints
|
||||
|
||||
| Constraint | Strategy |
|
||||
|------------|----------|
|
||||
| No local file access | Asset bundling, CDN |
|
||||
| Tab throttling | Pause when hidden |
|
||||
| Mobile data limits | Compress assets |
|
||||
| Audio autoplay | Require user interaction |
|
||||
|
||||
### Optimization Priority
|
||||
|
||||
1. **Asset compression** - KTX2, Draco, WebP
|
||||
2. **Lazy loading** - Load on demand
|
||||
3. **Object pooling** - Avoid GC
|
||||
4. **Draw call batching** - Reduce state changes
|
||||
5. **Web Workers** - Offload heavy computation
|
||||
|
||||
---
|
||||
|
||||
## 4. Asset Strategy
|
||||
|
||||
### Compression Formats
|
||||
|
||||
| Type | Format |
|
||||
|------|--------|
|
||||
| Textures | KTX2 + Basis Universal |
|
||||
| Audio | WebM/Opus (fallback: MP3) |
|
||||
| 3D Models | glTF + Draco/Meshopt |
|
||||
|
||||
### Loading Strategy
|
||||
|
||||
| Phase | Load |
|
||||
|-------|------|
|
||||
| Startup | Core assets, <2MB |
|
||||
| Gameplay | Stream on demand |
|
||||
| Background | Prefetch next level |
|
||||
|
||||
---
|
||||
|
||||
## 5. PWA for Games
|
||||
|
||||
### Benefits
|
||||
|
||||
- Offline play
|
||||
- Install to home screen
|
||||
- Full screen mode
|
||||
- Push notifications
|
||||
|
||||
### Requirements
|
||||
|
||||
- Service worker for caching
|
||||
- Web app manifest
|
||||
- HTTPS
|
||||
|
||||
---
|
||||
|
||||
## 6. Audio Handling
|
||||
|
||||
### Browser Requirements
|
||||
|
||||
- Audio context requires user interaction
|
||||
- Create AudioContext on first click/tap
|
||||
- Resume context if suspended
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Use Web Audio API
|
||||
- Pool audio sources
|
||||
- Preload common sounds
|
||||
- Compress with WebM/Opus
|
||||
|
||||
---
|
||||
|
||||
## 7. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Load all assets upfront | Progressive loading |
|
||||
| Ignore tab visibility | Pause when hidden |
|
||||
| Block on audio load | Lazy load audio |
|
||||
| Skip compression | Compress everything |
|
||||
| Assume fast connection | Handle slow networks |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Browser is the most accessible platform. Respect its constraints.
|
||||
156
skills/geo-fundamentals/SKILL.md
Normal file
156
skills/geo-fundamentals/SKILL.md
Normal file
@@ -0,0 +1,156 @@
|
||||
---
|
||||
name: geo-fundamentals
|
||||
description: Generative Engine Optimization for AI search engines (ChatGPT, Claude, Perplexity).
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# GEO Fundamentals
|
||||
|
||||
> Optimization for AI-powered search engines.
|
||||
|
||||
---
|
||||
|
||||
## 1. What is GEO?
|
||||
|
||||
**GEO** = Generative Engine Optimization
|
||||
|
||||
| Goal | Platform |
|
||||
|------|----------|
|
||||
| Be cited in AI responses | ChatGPT, Claude, Perplexity, Gemini |
|
||||
|
||||
### SEO vs GEO
|
||||
|
||||
| Aspect | SEO | GEO |
|
||||
|--------|-----|-----|
|
||||
| Goal | #1 ranking | AI citations |
|
||||
| Platform | Google | AI engines |
|
||||
| Metrics | Rankings, CTR | Citation rate |
|
||||
| Focus | Keywords | Entities, data |
|
||||
|
||||
---
|
||||
|
||||
## 2. AI Engine Landscape
|
||||
|
||||
| Engine | Citation Style | Opportunity |
|
||||
|--------|----------------|-------------|
|
||||
| **Perplexity** | Numbered [1][2] | Highest citation rate |
|
||||
| **ChatGPT** | Inline/footnotes | Custom GPTs |
|
||||
| **Claude** | Contextual | Long-form content |
|
||||
| **Gemini** | Sources section | SEO crossover |
|
||||
|
||||
---
|
||||
|
||||
## 3. RAG Retrieval Factors
|
||||
|
||||
How AI engines select content to cite:
|
||||
|
||||
| Factor | Weight |
|
||||
|--------|--------|
|
||||
| Semantic relevance | ~40% |
|
||||
| Keyword match | ~20% |
|
||||
| Authority signals | ~15% |
|
||||
| Freshness | ~10% |
|
||||
| Source diversity | ~15% |
|
||||
|
||||
---
|
||||
|
||||
## 4. Content That Gets Cited
|
||||
|
||||
| Element | Why It Works |
|
||||
|---------|--------------|
|
||||
| **Original statistics** | Unique, citable data |
|
||||
| **Expert quotes** | Authority transfer |
|
||||
| **Clear definitions** | Easy to extract |
|
||||
| **Step-by-step guides** | Actionable value |
|
||||
| **Comparison tables** | Structured info |
|
||||
| **FAQ sections** | Direct answers |
|
||||
|
||||
---
|
||||
|
||||
## 5. GEO Content Checklist
|
||||
|
||||
### Content Elements
|
||||
|
||||
- [ ] Question-based titles
|
||||
- [ ] Summary/TL;DR at top
|
||||
- [ ] Original data with sources
|
||||
- [ ] Expert quotes (name, title)
|
||||
- [ ] FAQ section (3-5 Q&A)
|
||||
- [ ] Clear definitions
|
||||
- [ ] "Last updated" timestamp
|
||||
- [ ] Author with credentials
|
||||
|
||||
### Technical Elements
|
||||
|
||||
- [ ] Article schema with dates
|
||||
- [ ] Person schema for author
|
||||
- [ ] FAQPage schema
|
||||
- [ ] Fast loading (< 2.5s)
|
||||
- [ ] Clean HTML structure
|
||||
|
||||
---
|
||||
|
||||
## 6. Entity Building
|
||||
|
||||
| Action | Purpose |
|
||||
|--------|---------|
|
||||
| Google Knowledge Panel | Entity recognition |
|
||||
| Wikipedia (if notable) | Authority source |
|
||||
| Consistent info across web | Entity consolidation |
|
||||
| Industry mentions | Authority signals |
|
||||
|
||||
---
|
||||
|
||||
## 7. AI Crawler Access
|
||||
|
||||
### Key AI User-Agents
|
||||
|
||||
| Crawler | Engine |
|
||||
|---------|--------|
|
||||
| GPTBot | ChatGPT/OpenAI |
|
||||
| Claude-Web | Claude |
|
||||
| PerplexityBot | Perplexity |
|
||||
| Googlebot | Gemini (shared) |
|
||||
|
||||
### Access Decision
|
||||
|
||||
| Strategy | When |
|
||||
|----------|------|
|
||||
| Allow all | Want AI citations |
|
||||
| Block GPTBot | Don't want OpenAI training |
|
||||
| Selective | Allow some, block others |
|
||||
|
||||
---
|
||||
|
||||
## 8. Measurement
|
||||
|
||||
| Metric | How to Track |
|
||||
|--------|--------------|
|
||||
| AI citations | Manual monitoring |
|
||||
| "According to [Brand]" mentions | Search in AI |
|
||||
| Competitor citations | Compare share |
|
||||
| AI-referred traffic | UTM parameters |
|
||||
|
||||
---
|
||||
|
||||
## 9. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Publish without dates | Add timestamps |
|
||||
| Vague attributions | Name sources |
|
||||
| Skip author info | Show credentials |
|
||||
| Thin content | Comprehensive coverage |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** AI cites content that's clear, authoritative, and easy to extract. Be the best answer.
|
||||
|
||||
---
|
||||
|
||||
## Script
|
||||
|
||||
| Script | Purpose | Command |
|
||||
|--------|---------|---------|
|
||||
| `scripts/geo_checker.py` | GEO audit (AI citation readiness) | `python scripts/geo_checker.py <project_path>` |
|
||||
|
||||
289
skills/geo-fundamentals/scripts/geo_checker.py
Normal file
289
skills/geo-fundamentals/scripts/geo_checker.py
Normal file
@@ -0,0 +1,289 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GEO Checker - Generative Engine Optimization Audit
|
||||
Checks PUBLIC WEB CONTENT for AI citation readiness.
|
||||
|
||||
PURPOSE:
|
||||
- Analyze pages that will be INDEXED by AI engines (ChatGPT, Perplexity, etc.)
|
||||
- Check for structured data, author info, dates, FAQ sections
|
||||
- Help content rank in AI-generated answers
|
||||
|
||||
WHAT IT CHECKS:
|
||||
- HTML files (actual web pages)
|
||||
- JSX/TSX files (React page components)
|
||||
- NOT markdown files (those are developer docs, not public content)
|
||||
|
||||
Usage:
|
||||
python geo_checker.py <project_path>
|
||||
"""
|
||||
import sys
|
||||
import re
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
# Fix Windows console encoding
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
# Directories to skip (not public content)
|
||||
SKIP_DIRS = {
|
||||
'node_modules', '.next', 'dist', 'build', '.git', '.github',
|
||||
'__pycache__', '.vscode', '.idea', 'coverage', 'test', 'tests',
|
||||
'__tests__', 'spec', 'docs', 'documentation'
|
||||
}
|
||||
|
||||
# Files to skip (not public pages)
|
||||
SKIP_FILES = {
|
||||
'jest.config', 'webpack.config', 'vite.config', 'tsconfig',
|
||||
'package.json', 'package-lock', 'yarn.lock', '.eslintrc',
|
||||
'tailwind.config', 'postcss.config', 'next.config'
|
||||
}
|
||||
|
||||
|
||||
def is_page_file(file_path: Path) -> bool:
|
||||
"""Check if this file is likely a public-facing page."""
|
||||
name = file_path.stem.lower()
|
||||
|
||||
# Skip config/utility files
|
||||
if any(skip in name for skip in SKIP_FILES):
|
||||
return False
|
||||
|
||||
# Skip test files
|
||||
if name.endswith('.test') or name.endswith('.spec'):
|
||||
return False
|
||||
if name.startswith('test_') or name.startswith('spec_'):
|
||||
return False
|
||||
|
||||
# Likely page indicators
|
||||
page_indicators = ['page', 'index', 'home', 'about', 'contact', 'blog',
|
||||
'post', 'article', 'product', 'service', 'landing']
|
||||
|
||||
# Check if it's in a pages/app directory (Next.js, etc.)
|
||||
parts = [p.lower() for p in file_path.parts]
|
||||
if 'pages' in parts or 'app' in parts or 'routes' in parts:
|
||||
return True
|
||||
|
||||
# Check filename indicators
|
||||
if any(ind in name for ind in page_indicators):
|
||||
return True
|
||||
|
||||
# HTML files are usually pages
|
||||
if file_path.suffix.lower() == '.html':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def find_web_pages(project_path: Path) -> list:
|
||||
"""Find public-facing web pages only."""
|
||||
patterns = ['**/*.html', '**/*.htm', '**/*.jsx', '**/*.tsx']
|
||||
|
||||
files = []
|
||||
for pattern in patterns:
|
||||
for f in project_path.glob(pattern):
|
||||
# Skip excluded directories
|
||||
if any(skip in f.parts for skip in SKIP_DIRS):
|
||||
continue
|
||||
|
||||
# Check if it's likely a page
|
||||
if is_page_file(f):
|
||||
files.append(f)
|
||||
|
||||
return files[:30] # Limit to 30 pages
|
||||
|
||||
|
||||
def check_page(file_path: Path) -> dict:
|
||||
"""Check a single web page for GEO elements."""
|
||||
try:
|
||||
content = file_path.read_text(encoding='utf-8', errors='ignore')
|
||||
except Exception as e:
|
||||
return {'file': str(file_path.name), 'passed': [], 'issues': [f"Error: {e}"], 'score': 0}
|
||||
|
||||
issues = []
|
||||
passed = []
|
||||
|
||||
# 1. JSON-LD Structured Data (Critical for AI)
|
||||
if 'application/ld+json' in content:
|
||||
passed.append("JSON-LD structured data found")
|
||||
if '"@type"' in content:
|
||||
if 'Article' in content:
|
||||
passed.append("Article schema present")
|
||||
if 'FAQPage' in content:
|
||||
passed.append("FAQ schema present")
|
||||
if 'Organization' in content or 'Person' in content:
|
||||
passed.append("Entity schema present")
|
||||
else:
|
||||
issues.append("No JSON-LD structured data (AI engines prefer structured content)")
|
||||
|
||||
# 2. Heading Structure
|
||||
h1_count = len(re.findall(r'<h1[^>]*>', content, re.I))
|
||||
h2_count = len(re.findall(r'<h2[^>]*>', content, re.I))
|
||||
|
||||
if h1_count == 1:
|
||||
passed.append("Single H1 heading (clear topic)")
|
||||
elif h1_count == 0:
|
||||
issues.append("No H1 heading - page topic unclear")
|
||||
else:
|
||||
issues.append(f"Multiple H1 headings ({h1_count}) - confusing for AI")
|
||||
|
||||
if h2_count >= 2:
|
||||
passed.append(f"{h2_count} H2 subheadings (good structure)")
|
||||
else:
|
||||
issues.append("Add more H2 subheadings for scannable content")
|
||||
|
||||
# 3. Author Attribution (E-E-A-T signal)
|
||||
author_patterns = ['author', 'byline', 'written-by', 'contributor', 'rel="author"']
|
||||
has_author = any(p in content.lower() for p in author_patterns)
|
||||
if has_author:
|
||||
passed.append("Author attribution found")
|
||||
else:
|
||||
issues.append("No author info (AI prefers attributed content)")
|
||||
|
||||
# 4. Publication Date (Freshness signal)
|
||||
date_patterns = ['datePublished', 'dateModified', 'datetime=', 'pubdate', 'article:published']
|
||||
has_date = any(re.search(p, content, re.I) for p in date_patterns)
|
||||
if has_date:
|
||||
passed.append("Publication date found")
|
||||
else:
|
||||
issues.append("No publication date (freshness matters for AI)")
|
||||
|
||||
# 5. FAQ Section (Highly citable)
|
||||
faq_patterns = [r'<details', r'faq', r'frequently.?asked', r'"FAQPage"']
|
||||
has_faq = any(re.search(p, content, re.I) for p in faq_patterns)
|
||||
if has_faq:
|
||||
passed.append("FAQ section detected (highly citable)")
|
||||
|
||||
# 6. Lists (Structured content)
|
||||
list_count = len(re.findall(r'<(ul|ol)[^>]*>', content, re.I))
|
||||
if list_count >= 2:
|
||||
passed.append(f"{list_count} lists (structured content)")
|
||||
|
||||
# 7. Tables (Comparison data)
|
||||
table_count = len(re.findall(r'<table[^>]*>', content, re.I))
|
||||
if table_count >= 1:
|
||||
passed.append(f"{table_count} table(s) (comparison data)")
|
||||
|
||||
# 8. Entity Recognition (E-E-A-T signal) - NEW 2025
|
||||
entity_patterns = [
|
||||
r'"@type"\s*:\s*"Organization"',
|
||||
r'"@type"\s*:\s*"LocalBusiness"',
|
||||
r'"@type"\s*:\s*"Brand"',
|
||||
r'itemtype.*schema\.org/(Organization|Person|Brand)',
|
||||
r'rel="author"'
|
||||
]
|
||||
has_entity = any(re.search(p, content, re.I) for p in entity_patterns)
|
||||
if has_entity:
|
||||
passed.append("Entity/Brand recognition (E-E-A-T)")
|
||||
|
||||
# 9. Original Statistics/Data (AI citation magnet) - NEW 2025
|
||||
stat_patterns = [
|
||||
r'\d+%', # Percentages
|
||||
r'\$[\d,]+', # Dollar amounts
|
||||
r'study\s+(shows|found)', # Research citations
|
||||
r'according to', # Source attribution
|
||||
r'data\s+(shows|reveals)', # Data-backed claims
|
||||
r'\d+x\s+(faster|better|more)', # Comparison stats
|
||||
r'(million|billion|trillion)', # Large numbers
|
||||
]
|
||||
stat_matches = sum(1 for p in stat_patterns if re.search(p, content, re.I))
|
||||
if stat_matches >= 2:
|
||||
passed.append("Original statistics/data (citation magnet)")
|
||||
|
||||
# 10. Conversational/Direct answers - NEW 2025
|
||||
direct_answer_patterns = [
|
||||
r'is defined as',
|
||||
r'refers to',
|
||||
r'means that',
|
||||
r'the answer is',
|
||||
r'in short,',
|
||||
r'simply put,',
|
||||
r'<dfn'
|
||||
]
|
||||
has_direct = any(re.search(p, content, re.I) for p in direct_answer_patterns)
|
||||
if has_direct:
|
||||
passed.append("Direct answer patterns (LLM-friendly)")
|
||||
|
||||
# Calculate score
|
||||
total = len(passed) + len(issues)
|
||||
score = (len(passed) / total * 100) if total > 0 else 0
|
||||
|
||||
return {
|
||||
'file': str(file_path.name),
|
||||
'passed': passed,
|
||||
'issues': issues,
|
||||
'score': round(score)
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
target = sys.argv[1] if len(sys.argv) > 1 else "."
|
||||
target_path = Path(target).resolve()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(" GEO CHECKER - AI Citation Readiness Audit")
|
||||
print("=" * 60)
|
||||
print(f"Project: {target_path}")
|
||||
print("-" * 60)
|
||||
|
||||
# Find web pages only
|
||||
pages = find_web_pages(target_path)
|
||||
|
||||
if not pages:
|
||||
print("\n[!] No public web pages found.")
|
||||
print(" Looking for: HTML, JSX, TSX files in pages/app directories")
|
||||
print(" Skipping: docs, tests, config files, node_modules")
|
||||
output = {"script": "geo_checker", "pages_found": 0, "passed": True}
|
||||
print("\n" + json.dumps(output, indent=2))
|
||||
sys.exit(0)
|
||||
|
||||
print(f"Found {len(pages)} public pages to analyze\n")
|
||||
|
||||
# Check each page
|
||||
results = []
|
||||
for page in pages:
|
||||
result = check_page(page)
|
||||
results.append(result)
|
||||
|
||||
# Print results
|
||||
for result in results:
|
||||
status = "[OK]" if result['score'] >= 60 else "[!]"
|
||||
print(f"{status} {result['file']}: {result['score']}%")
|
||||
if result['issues'] and result['score'] < 60:
|
||||
for issue in result['issues'][:2]: # Show max 2 issues
|
||||
print(f" - {issue}")
|
||||
|
||||
# Average score
|
||||
avg_score = sum(r['score'] for r in results) / len(results) if results else 0
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"AVERAGE GEO SCORE: {avg_score:.0f}%")
|
||||
print("=" * 60)
|
||||
|
||||
if avg_score >= 80:
|
||||
print("[OK] Excellent - Content well-optimized for AI citations")
|
||||
elif avg_score >= 60:
|
||||
print("[OK] Good - Some improvements recommended")
|
||||
elif avg_score >= 40:
|
||||
print("[!] Needs work - Add structured elements")
|
||||
else:
|
||||
print("[X] Poor - Content needs GEO optimization")
|
||||
|
||||
# JSON output
|
||||
output = {
|
||||
"script": "geo_checker",
|
||||
"project": str(target_path),
|
||||
"pages_checked": len(results),
|
||||
"average_score": round(avg_score),
|
||||
"passed": avg_score >= 60
|
||||
}
|
||||
print("\n" + json.dumps(output, indent=2))
|
||||
|
||||
sys.exit(0 if avg_score >= 60 else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
154
skills/i18n-localization/SKILL.md
Normal file
154
skills/i18n-localization/SKILL.md
Normal file
@@ -0,0 +1,154 @@
|
||||
---
|
||||
name: i18n-localization
|
||||
description: Internationalization and localization patterns. Detecting hardcoded strings, managing translations, locale files, RTL support.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# i18n & Localization
|
||||
|
||||
> Internationalization (i18n) and Localization (L10n) best practices.
|
||||
|
||||
---
|
||||
|
||||
## 1. Core Concepts
|
||||
|
||||
| Term | Meaning |
|
||||
|------|---------|
|
||||
| **i18n** | Internationalization - making app translatable |
|
||||
| **L10n** | Localization - actual translations |
|
||||
| **Locale** | Language + Region (en-US, tr-TR) |
|
||||
| **RTL** | Right-to-left languages (Arabic, Hebrew) |
|
||||
|
||||
---
|
||||
|
||||
## 2. When to Use i18n
|
||||
|
||||
| Project Type | i18n Needed? |
|
||||
|--------------|--------------|
|
||||
| Public web app | ✅ Yes |
|
||||
| SaaS product | ✅ Yes |
|
||||
| Internal tool | ⚠️ Maybe |
|
||||
| Single-region app | ⚠️ Consider future |
|
||||
| Personal project | ❌ Optional |
|
||||
|
||||
---
|
||||
|
||||
## 3. Implementation Patterns
|
||||
|
||||
### React (react-i18next)
|
||||
|
||||
```tsx
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function Welcome() {
|
||||
const { t } = useTranslation();
|
||||
return <h1>{t('welcome.title')}</h1>;
|
||||
}
|
||||
```
|
||||
|
||||
### Next.js (next-intl)
|
||||
|
||||
```tsx
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
export default function Page() {
|
||||
const t = useTranslations('Home');
|
||||
return <h1>{t('title')}</h1>;
|
||||
}
|
||||
```
|
||||
|
||||
### Python (gettext)
|
||||
|
||||
```python
|
||||
from gettext import gettext as _
|
||||
|
||||
print(_("Welcome to our app"))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. File Structure
|
||||
|
||||
```
|
||||
locales/
|
||||
├── en/
|
||||
│ ├── common.json
|
||||
│ ├── auth.json
|
||||
│ └── errors.json
|
||||
├── tr/
|
||||
│ ├── common.json
|
||||
│ ├── auth.json
|
||||
│ └── errors.json
|
||||
└── ar/ # RTL
|
||||
└── ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Best Practices
|
||||
|
||||
### DO ✅
|
||||
|
||||
- Use translation keys, not raw text
|
||||
- Namespace translations by feature
|
||||
- Support pluralization
|
||||
- Handle date/number formats per locale
|
||||
- Plan for RTL from the start
|
||||
- Use ICU message format for complex strings
|
||||
|
||||
### DON'T ❌
|
||||
|
||||
- Hardcode strings in components
|
||||
- Concatenate translated strings
|
||||
- Assume text length (German is 30% longer)
|
||||
- Forget about RTL layout
|
||||
- Mix languages in same file
|
||||
|
||||
---
|
||||
|
||||
## 6. Common Issues
|
||||
|
||||
| Issue | Solution |
|
||||
|-------|----------|
|
||||
| Missing translation | Fallback to default language |
|
||||
| Hardcoded strings | Use linter/checker script |
|
||||
| Date format | Use Intl.DateTimeFormat |
|
||||
| Number format | Use Intl.NumberFormat |
|
||||
| Pluralization | Use ICU message format |
|
||||
|
||||
---
|
||||
|
||||
## 7. RTL Support
|
||||
|
||||
```css
|
||||
/* CSS Logical Properties */
|
||||
.container {
|
||||
margin-inline-start: 1rem; /* Not margin-left */
|
||||
padding-inline-end: 1rem; /* Not padding-right */
|
||||
}
|
||||
|
||||
[dir="rtl"] .icon {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Checklist
|
||||
|
||||
Before shipping:
|
||||
|
||||
- [ ] All user-facing strings use translation keys
|
||||
- [ ] Locale files exist for all supported languages
|
||||
- [ ] Date/number formatting uses Intl API
|
||||
- [ ] RTL layout tested (if applicable)
|
||||
- [ ] Fallback language configured
|
||||
- [ ] No hardcoded strings in components
|
||||
|
||||
---
|
||||
|
||||
## Script
|
||||
|
||||
| Script | Purpose | Command |
|
||||
|--------|---------|---------|
|
||||
| `scripts/i18n_checker.py` | Detect hardcoded strings & missing translations | `python scripts/i18n_checker.py <project_path>` |
|
||||
241
skills/i18n-localization/scripts/i18n_checker.py
Normal file
241
skills/i18n-localization/scripts/i18n_checker.py
Normal file
@@ -0,0 +1,241 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
i18n Checker - Detects hardcoded strings and missing translations.
|
||||
Scans for untranslated text in React, Vue, and Python files.
|
||||
"""
|
||||
import sys
|
||||
import re
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
# Fix Windows console encoding for Unicode output
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
|
||||
except AttributeError:
|
||||
pass # Python < 3.7
|
||||
|
||||
# Patterns that indicate hardcoded strings (should be translated)
|
||||
HARDCODED_PATTERNS = {
|
||||
'jsx': [
|
||||
# Text directly in JSX: <div>Hello World</div>
|
||||
r'>\s*[A-Z][a-zA-Z\s]{3,30}\s*</',
|
||||
# JSX attribute strings: title="Welcome"
|
||||
r'(title|placeholder|label|alt|aria-label)="[A-Z][a-zA-Z\s]{2,}"',
|
||||
# Button/heading text
|
||||
r'<(button|h[1-6]|p|span|label)[^>]*>\s*[A-Z][a-zA-Z\s!?.,]{3,}\s*</',
|
||||
],
|
||||
'vue': [
|
||||
# Vue template text
|
||||
r'>\s*[A-Z][a-zA-Z\s]{3,30}\s*</',
|
||||
r'(placeholder|label|title)="[A-Z][a-zA-Z\s]{2,}"',
|
||||
],
|
||||
'python': [
|
||||
# print/raise with string literals
|
||||
r'(print|raise\s+\w+)\s*\(\s*["\'][A-Z][^"\']{5,}["\']',
|
||||
# Flask flash messages
|
||||
r'flash\s*\(\s*["\'][A-Z][^"\']{5,}["\']',
|
||||
]
|
||||
}
|
||||
|
||||
# Patterns that indicate proper i18n usage
|
||||
I18N_PATTERNS = [
|
||||
r't\(["\']', # t('key') - react-i18next
|
||||
r'useTranslation', # React hook
|
||||
r'\$t\(', # Vue i18n
|
||||
r'_\(["\']', # Python gettext
|
||||
r'gettext\(', # Python gettext
|
||||
r'useTranslations', # next-intl
|
||||
r'FormattedMessage', # react-intl
|
||||
r'i18n\.', # Generic i18n
|
||||
]
|
||||
|
||||
def find_locale_files(project_path: Path) -> list:
|
||||
"""Find translation/locale files."""
|
||||
patterns = [
|
||||
"**/locales/**/*.json",
|
||||
"**/translations/**/*.json",
|
||||
"**/lang/**/*.json",
|
||||
"**/i18n/**/*.json",
|
||||
"**/messages/*.json",
|
||||
"**/*.po", # gettext
|
||||
]
|
||||
|
||||
files = []
|
||||
for pattern in patterns:
|
||||
files.extend(project_path.glob(pattern))
|
||||
|
||||
return [f for f in files if 'node_modules' not in str(f)]
|
||||
|
||||
def check_locale_completeness(locale_files: list) -> dict:
|
||||
"""Check if all locales have the same keys."""
|
||||
issues = []
|
||||
passed = []
|
||||
|
||||
if not locale_files:
|
||||
return {'passed': [], 'issues': ["[!] No locale files found"]}
|
||||
|
||||
# Group by parent folder (language)
|
||||
locales = {}
|
||||
for f in locale_files:
|
||||
if f.suffix == '.json':
|
||||
try:
|
||||
lang = f.parent.name
|
||||
content = json.loads(f.read_text(encoding='utf-8'))
|
||||
if lang not in locales:
|
||||
locales[lang] = {}
|
||||
locales[lang][f.stem] = set(flatten_keys(content))
|
||||
except:
|
||||
continue
|
||||
|
||||
if len(locales) < 2:
|
||||
passed.append(f"[OK] Found {len(locale_files)} locale file(s)")
|
||||
return {'passed': passed, 'issues': issues}
|
||||
|
||||
passed.append(f"[OK] Found {len(locales)} language(s): {', '.join(locales.keys())}")
|
||||
|
||||
# Compare keys across locales
|
||||
all_langs = list(locales.keys())
|
||||
base_lang = all_langs[0]
|
||||
|
||||
for namespace in locales.get(base_lang, {}):
|
||||
base_keys = locales[base_lang].get(namespace, set())
|
||||
|
||||
for lang in all_langs[1:]:
|
||||
other_keys = locales.get(lang, {}).get(namespace, set())
|
||||
|
||||
missing = base_keys - other_keys
|
||||
if missing:
|
||||
issues.append(f"[X] {lang}/{namespace}: Missing {len(missing)} keys")
|
||||
|
||||
extra = other_keys - base_keys
|
||||
if extra:
|
||||
issues.append(f"[!] {lang}/{namespace}: {len(extra)} extra keys")
|
||||
|
||||
if not issues:
|
||||
passed.append("[OK] All locales have matching keys")
|
||||
|
||||
return {'passed': passed, 'issues': issues}
|
||||
|
||||
def flatten_keys(d, prefix=''):
|
||||
"""Flatten nested dict keys."""
|
||||
keys = set()
|
||||
for k, v in d.items():
|
||||
new_key = f"{prefix}.{k}" if prefix else k
|
||||
if isinstance(v, dict):
|
||||
keys.update(flatten_keys(v, new_key))
|
||||
else:
|
||||
keys.add(new_key)
|
||||
return keys
|
||||
|
||||
def check_hardcoded_strings(project_path: Path) -> dict:
|
||||
"""Check for hardcoded strings in code files."""
|
||||
issues = []
|
||||
passed = []
|
||||
|
||||
# Find code files
|
||||
extensions = {
|
||||
'.tsx': 'jsx', '.jsx': 'jsx', '.ts': 'jsx', '.js': 'jsx',
|
||||
'.vue': 'vue',
|
||||
'.py': 'python'
|
||||
}
|
||||
|
||||
code_files = []
|
||||
for ext in extensions:
|
||||
code_files.extend(project_path.rglob(f"*{ext}"))
|
||||
|
||||
code_files = [f for f in code_files if not any(x in str(f) for x in
|
||||
['node_modules', '.git', 'dist', 'build', '__pycache__', 'venv', 'test', 'spec'])]
|
||||
|
||||
if not code_files:
|
||||
return {'passed': ["[!] No code files found"], 'issues': []}
|
||||
|
||||
files_with_i18n = 0
|
||||
files_with_hardcoded = 0
|
||||
hardcoded_examples = []
|
||||
|
||||
for file_path in code_files[:50]: # Limit
|
||||
try:
|
||||
content = file_path.read_text(encoding='utf-8', errors='ignore')
|
||||
ext = file_path.suffix
|
||||
file_type = extensions.get(ext, 'jsx')
|
||||
|
||||
# Check for i18n usage
|
||||
has_i18n = any(re.search(p, content) for p in I18N_PATTERNS)
|
||||
if has_i18n:
|
||||
files_with_i18n += 1
|
||||
|
||||
# Check for hardcoded strings
|
||||
patterns = HARDCODED_PATTERNS.get(file_type, [])
|
||||
hardcoded_found = False
|
||||
|
||||
for pattern in patterns:
|
||||
matches = re.findall(pattern, content)
|
||||
if matches and not has_i18n:
|
||||
hardcoded_found = True
|
||||
if len(hardcoded_examples) < 5:
|
||||
hardcoded_examples.append(f"{file_path.name}: {str(matches[0])[:40]}...")
|
||||
|
||||
if hardcoded_found:
|
||||
files_with_hardcoded += 1
|
||||
|
||||
except:
|
||||
continue
|
||||
|
||||
passed.append(f"[OK] Analyzed {len(code_files)} code files")
|
||||
|
||||
if files_with_i18n > 0:
|
||||
passed.append(f"[OK] {files_with_i18n} files use i18n")
|
||||
|
||||
if files_with_hardcoded > 0:
|
||||
issues.append(f"[X] {files_with_hardcoded} files may have hardcoded strings")
|
||||
for ex in hardcoded_examples:
|
||||
issues.append(f" → {ex}")
|
||||
else:
|
||||
passed.append("[OK] No obvious hardcoded strings detected")
|
||||
|
||||
return {'passed': passed, 'issues': issues}
|
||||
|
||||
def main():
|
||||
target = sys.argv[1] if len(sys.argv) > 1 else "."
|
||||
project_path = Path(target)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(" i18n CHECKER - Internationalization Audit")
|
||||
print("=" * 60 + "\n")
|
||||
|
||||
# Check locale files
|
||||
locale_files = find_locale_files(project_path)
|
||||
locale_result = check_locale_completeness(locale_files)
|
||||
|
||||
# Check hardcoded strings
|
||||
code_result = check_hardcoded_strings(project_path)
|
||||
|
||||
# Print results
|
||||
print("[LOCALE FILES]")
|
||||
print("-" * 40)
|
||||
for item in locale_result['passed']:
|
||||
print(f" {item}")
|
||||
for item in locale_result['issues']:
|
||||
print(f" {item}")
|
||||
|
||||
print("\n[CODE ANALYSIS]")
|
||||
print("-" * 40)
|
||||
for item in code_result['passed']:
|
||||
print(f" {item}")
|
||||
for item in code_result['issues']:
|
||||
print(f" {item}")
|
||||
|
||||
# Summary
|
||||
critical_issues = sum(1 for i in locale_result['issues'] + code_result['issues'] if i.startswith("[X]"))
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
if critical_issues == 0:
|
||||
print("[OK] i18n CHECK: PASSED")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print(f"[X] i18n CHECK: {critical_issues} issues found")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
45
skills/lint-and-validate/SKILL.md
Normal file
45
skills/lint-and-validate/SKILL.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: lint-and-validate
|
||||
description: 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.
|
||||
allowed-tools: Read, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# Lint and Validate Skill
|
||||
|
||||
> **MANDATORY:** Run appropriate validation tools after EVERY code change. Do not finish a task until the code is error-free.
|
||||
|
||||
### Procedures by Ecosystem
|
||||
|
||||
#### Node.js / TypeScript
|
||||
1. **Lint/Fix:** `npm run lint` or `npx eslint "path" --fix`
|
||||
2. **Types:** `npx tsc --noEmit`
|
||||
3. **Security:** `npm audit --audit-level=high`
|
||||
|
||||
#### Python
|
||||
1. **Linter (Ruff):** `ruff check "path" --fix` (Fast & Modern)
|
||||
2. **Security (Bandit):** `bandit -r "path" -ll`
|
||||
3. **Types (MyPy):** `mypy "path"`
|
||||
|
||||
## The Quality Loop
|
||||
1. **Write/Edit Code**
|
||||
2. **Run Audit:** `npm run lint && npx tsc --noEmit`
|
||||
3. **Analyze Report:** Check the "FINAL AUDIT REPORT" section.
|
||||
4. **Fix & Repeat:** Submitting code with "FINAL AUDIT" failures is NOT allowed.
|
||||
|
||||
## Error Handling
|
||||
- If `lint` fails: Fix the style or syntax issues immediately.
|
||||
- If `tsc` fails: Correct type mismatches before proceeding.
|
||||
- If no tool is configured: Check the project root for `.eslintrc`, `tsconfig.json`, `pyproject.toml` and suggest creating one.
|
||||
|
||||
---
|
||||
**Strict Rule:** No code should be committed or reported as "done" without passing these checks.
|
||||
|
||||
---
|
||||
|
||||
## Scripts
|
||||
|
||||
| Script | Purpose | Command |
|
||||
|--------|---------|---------|
|
||||
| `scripts/lint_runner.py` | Unified lint check | `python scripts/lint_runner.py <project_path>` |
|
||||
| `scripts/type_coverage.py` | Type coverage analysis | `python scripts/type_coverage.py <project_path>` |
|
||||
|
||||
172
skills/lint-and-validate/scripts/lint_runner.py
Normal file
172
skills/lint-and-validate/scripts/lint_runner.py
Normal file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Lint Runner - Unified linting and type checking
|
||||
Runs appropriate linters based on project type.
|
||||
|
||||
Usage:
|
||||
python lint_runner.py <project_path>
|
||||
|
||||
Supports:
|
||||
- Node.js: npm run lint, npx tsc --noEmit
|
||||
- Python: ruff check, mypy
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import json
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Fix Windows console encoding
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def detect_project_type(project_path: Path) -> dict:
|
||||
"""Detect project type and available linters."""
|
||||
result = {
|
||||
"type": "unknown",
|
||||
"linters": []
|
||||
}
|
||||
|
||||
# Node.js project
|
||||
package_json = project_path / "package.json"
|
||||
if package_json.exists():
|
||||
result["type"] = "node"
|
||||
try:
|
||||
pkg = json.loads(package_json.read_text(encoding='utf-8'))
|
||||
scripts = pkg.get("scripts", {})
|
||||
deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}
|
||||
|
||||
# Check for lint script
|
||||
if "lint" in scripts:
|
||||
result["linters"].append({"name": "npm lint", "cmd": ["npm", "run", "lint"]})
|
||||
elif "eslint" in deps:
|
||||
result["linters"].append({"name": "eslint", "cmd": ["npx", "eslint", "."]})
|
||||
|
||||
# Check for TypeScript
|
||||
if "typescript" in deps or (project_path / "tsconfig.json").exists():
|
||||
result["linters"].append({"name": "tsc", "cmd": ["npx", "tsc", "--noEmit"]})
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
# Python project
|
||||
if (project_path / "pyproject.toml").exists() or (project_path / "requirements.txt").exists():
|
||||
result["type"] = "python"
|
||||
|
||||
# Check for ruff
|
||||
result["linters"].append({"name": "ruff", "cmd": ["ruff", "check", "."]})
|
||||
|
||||
# Check for mypy
|
||||
if (project_path / "mypy.ini").exists() or (project_path / "pyproject.toml").exists():
|
||||
result["linters"].append({"name": "mypy", "cmd": ["mypy", "."]})
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def run_linter(linter: dict, cwd: Path) -> dict:
|
||||
"""Run a single linter and return results."""
|
||||
result = {
|
||||
"name": linter["name"],
|
||||
"passed": False,
|
||||
"output": "",
|
||||
"error": ""
|
||||
}
|
||||
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
linter["cmd"],
|
||||
cwd=str(cwd),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding='utf-8',
|
||||
errors='replace',
|
||||
timeout=120
|
||||
)
|
||||
|
||||
result["output"] = proc.stdout[:2000] if proc.stdout else ""
|
||||
result["error"] = proc.stderr[:500] if proc.stderr else ""
|
||||
result["passed"] = proc.returncode == 0
|
||||
|
||||
except FileNotFoundError:
|
||||
result["error"] = f"Command not found: {linter['cmd'][0]}"
|
||||
except subprocess.TimeoutExpired:
|
||||
result["error"] = "Timeout after 120s"
|
||||
except Exception as e:
|
||||
result["error"] = str(e)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
project_path = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"[LINT RUNNER] Unified Linting")
|
||||
print(f"{'='*60}")
|
||||
print(f"Project: {project_path}")
|
||||
print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
# Detect project type
|
||||
project_info = detect_project_type(project_path)
|
||||
print(f"Type: {project_info['type']}")
|
||||
print(f"Linters: {len(project_info['linters'])}")
|
||||
print("-"*60)
|
||||
|
||||
if not project_info["linters"]:
|
||||
print("No linters found for this project type.")
|
||||
output = {
|
||||
"script": "lint_runner",
|
||||
"project": str(project_path),
|
||||
"type": project_info["type"],
|
||||
"checks": [],
|
||||
"passed": True,
|
||||
"message": "No linters configured"
|
||||
}
|
||||
print(json.dumps(output, indent=2))
|
||||
sys.exit(0)
|
||||
|
||||
# Run each linter
|
||||
results = []
|
||||
all_passed = True
|
||||
|
||||
for linter in project_info["linters"]:
|
||||
print(f"\nRunning: {linter['name']}...")
|
||||
result = run_linter(linter, project_path)
|
||||
results.append(result)
|
||||
|
||||
if result["passed"]:
|
||||
print(f" [PASS] {linter['name']}")
|
||||
else:
|
||||
print(f" [FAIL] {linter['name']}")
|
||||
if result["error"]:
|
||||
print(f" Error: {result['error'][:200]}")
|
||||
all_passed = False
|
||||
|
||||
# Summary
|
||||
print("\n" + "="*60)
|
||||
print("SUMMARY")
|
||||
print("="*60)
|
||||
|
||||
for r in results:
|
||||
icon = "[PASS]" if r["passed"] else "[FAIL]"
|
||||
print(f"{icon} {r['name']}")
|
||||
|
||||
output = {
|
||||
"script": "lint_runner",
|
||||
"project": str(project_path),
|
||||
"type": project_info["type"],
|
||||
"checks": results,
|
||||
"passed": all_passed
|
||||
}
|
||||
|
||||
print("\n" + json.dumps(output, indent=2))
|
||||
|
||||
sys.exit(0 if all_passed else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
173
skills/lint-and-validate/scripts/type_coverage.py
Normal file
173
skills/lint-and-validate/scripts/type_coverage.py
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Type Coverage Checker - Measures TypeScript/Python type coverage.
|
||||
Identifies untyped functions, any usage, and type safety issues.
|
||||
"""
|
||||
import sys
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
# Fix Windows console encoding for Unicode output
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
|
||||
except AttributeError:
|
||||
pass # Python < 3.7
|
||||
|
||||
def check_typescript_coverage(project_path: Path) -> dict:
|
||||
"""Check TypeScript type coverage."""
|
||||
issues = []
|
||||
passed = []
|
||||
stats = {'any_count': 0, 'untyped_functions': 0, 'total_functions': 0}
|
||||
|
||||
ts_files = list(project_path.rglob("*.ts")) + list(project_path.rglob("*.tsx"))
|
||||
ts_files = [f for f in ts_files if 'node_modules' not in str(f) and '.d.ts' not in str(f)]
|
||||
|
||||
if not ts_files:
|
||||
return {'type': 'typescript', 'files': 0, 'passed': [], 'issues': ["[!] No TypeScript files found"], 'stats': stats}
|
||||
|
||||
for file_path in ts_files[:30]: # Limit
|
||||
try:
|
||||
content = file_path.read_text(encoding='utf-8', errors='ignore')
|
||||
|
||||
# Count 'any' usage
|
||||
any_matches = re.findall(r':\s*any\b', content)
|
||||
stats['any_count'] += len(any_matches)
|
||||
|
||||
# Find functions without return types
|
||||
# function name(params) { - no return type
|
||||
untyped = re.findall(r'function\s+\w+\s*\([^)]*\)\s*{', content)
|
||||
# Arrow functions without types: const fn = (x) => or (x) =>
|
||||
untyped += re.findall(r'=\s*\([^:)]*\)\s*=>', content)
|
||||
stats['untyped_functions'] += len(untyped)
|
||||
|
||||
# Count typed functions
|
||||
typed = re.findall(r'function\s+\w+\s*\([^)]*\)\s*:\s*\w+', content)
|
||||
typed += re.findall(r':\s*\([^)]*\)\s*=>\s*\w+', content)
|
||||
stats['total_functions'] += len(typed) + len(untyped)
|
||||
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
# Analyze results
|
||||
if stats['any_count'] == 0:
|
||||
passed.append("[OK] No 'any' types found")
|
||||
elif stats['any_count'] <= 5:
|
||||
issues.append(f"[!] {stats['any_count']} 'any' types found (acceptable)")
|
||||
else:
|
||||
issues.append(f"[X] {stats['any_count']} 'any' types found (too many)")
|
||||
|
||||
if stats['total_functions'] > 0:
|
||||
typed_ratio = (stats['total_functions'] - stats['untyped_functions']) / stats['total_functions'] * 100
|
||||
if typed_ratio >= 80:
|
||||
passed.append(f"[OK] Type coverage: {typed_ratio:.0f}%")
|
||||
elif typed_ratio >= 50:
|
||||
issues.append(f"[!] Type coverage: {typed_ratio:.0f}% (improve)")
|
||||
else:
|
||||
issues.append(f"[X] Type coverage: {typed_ratio:.0f}% (too low)")
|
||||
|
||||
passed.append(f"[OK] Analyzed {len(ts_files)} TypeScript files")
|
||||
|
||||
return {'type': 'typescript', 'files': len(ts_files), 'passed': passed, 'issues': issues, 'stats': stats}
|
||||
|
||||
def check_python_coverage(project_path: Path) -> dict:
|
||||
"""Check Python type hints coverage."""
|
||||
issues = []
|
||||
passed = []
|
||||
stats = {'untyped_functions': 0, 'typed_functions': 0, 'any_count': 0}
|
||||
|
||||
py_files = list(project_path.rglob("*.py"))
|
||||
py_files = [f for f in py_files if not any(x in str(f) for x in ['venv', '__pycache__', '.git', 'node_modules'])]
|
||||
|
||||
if not py_files:
|
||||
return {'type': 'python', 'files': 0, 'passed': [], 'issues': ["[!] No Python files found"], 'stats': stats}
|
||||
|
||||
for file_path in py_files[:30]: # Limit
|
||||
try:
|
||||
content = file_path.read_text(encoding='utf-8', errors='ignore')
|
||||
|
||||
# Count Any usage
|
||||
any_matches = re.findall(r':\s*Any\b', content)
|
||||
stats['any_count'] += len(any_matches)
|
||||
|
||||
# Find functions with type hints
|
||||
typed_funcs = re.findall(r'def\s+\w+\s*\([^)]*:[^)]+\)', content)
|
||||
typed_funcs += re.findall(r'def\s+\w+\s*\([^)]*\)\s*->', content)
|
||||
stats['typed_functions'] += len(typed_funcs)
|
||||
|
||||
# Find functions without type hints
|
||||
all_funcs = re.findall(r'def\s+\w+\s*\(', content)
|
||||
stats['untyped_functions'] += len(all_funcs) - len(typed_funcs)
|
||||
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
total = stats['typed_functions'] + stats['untyped_functions']
|
||||
|
||||
if total > 0:
|
||||
typed_ratio = stats['typed_functions'] / total * 100
|
||||
if typed_ratio >= 70:
|
||||
passed.append(f"[OK] Type hints coverage: {typed_ratio:.0f}%")
|
||||
elif typed_ratio >= 40:
|
||||
issues.append(f"[!] Type hints coverage: {typed_ratio:.0f}%")
|
||||
else:
|
||||
issues.append(f"[X] Type hints coverage: {typed_ratio:.0f}% (add type hints)")
|
||||
|
||||
if stats['any_count'] == 0:
|
||||
passed.append("[OK] No 'Any' types found")
|
||||
elif stats['any_count'] <= 3:
|
||||
issues.append(f"[!] {stats['any_count']} 'Any' types found")
|
||||
else:
|
||||
issues.append(f"[X] {stats['any_count']} 'Any' types found")
|
||||
|
||||
passed.append(f"[OK] Analyzed {len(py_files)} Python files")
|
||||
|
||||
return {'type': 'python', 'files': len(py_files), 'passed': passed, 'issues': issues, 'stats': stats}
|
||||
|
||||
def main():
|
||||
target = sys.argv[1] if len(sys.argv) > 1 else "."
|
||||
project_path = Path(target)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(" TYPE COVERAGE CHECKER")
|
||||
print("=" * 60 + "\n")
|
||||
|
||||
results = []
|
||||
|
||||
# Check TypeScript
|
||||
ts_result = check_typescript_coverage(project_path)
|
||||
if ts_result['files'] > 0:
|
||||
results.append(ts_result)
|
||||
|
||||
# Check Python
|
||||
py_result = check_python_coverage(project_path)
|
||||
if py_result['files'] > 0:
|
||||
results.append(py_result)
|
||||
|
||||
if not results:
|
||||
print("[!] No TypeScript or Python files found.")
|
||||
sys.exit(0)
|
||||
|
||||
# Print results
|
||||
critical_issues = 0
|
||||
for result in results:
|
||||
print(f"\n[{result['type'].upper()}]")
|
||||
print("-" * 40)
|
||||
for item in result['passed']:
|
||||
print(f" {item}")
|
||||
for item in result['issues']:
|
||||
print(f" {item}")
|
||||
if item.startswith("[X]"):
|
||||
critical_issues += 1
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
if critical_issues == 0:
|
||||
print("[OK] TYPE COVERAGE: ACCEPTABLE")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print(f"[X] TYPE COVERAGE: {critical_issues} critical issues")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
394
skills/mobile-design/SKILL.md
Normal file
394
skills/mobile-design/SKILL.md
Normal file
@@ -0,0 +1,394 @@
|
||||
---
|
||||
name: mobile-design
|
||||
description: 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.
|
||||
allowed-tools: Read, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# Mobile Design System
|
||||
|
||||
> **Philosophy:** Touch-first. Battery-conscious. Platform-respectful. Offline-capable.
|
||||
> **Core Principle:** Mobile is NOT a small desktop. THINK mobile constraints, ASK platform choice.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Runtime Scripts
|
||||
|
||||
**Execute these for validation (don't read, just run):**
|
||||
|
||||
| Script | Purpose | Usage |
|
||||
|--------|---------|-------|
|
||||
| `scripts/mobile_audit.py` | Mobile UX & Touch Audit | `python scripts/mobile_audit.py <project_path>` |
|
||||
|
||||
---
|
||||
|
||||
## 🔴 MANDATORY: Read Reference Files Before Working!
|
||||
|
||||
**⛔ DO NOT start development until you read the relevant files:**
|
||||
|
||||
### Universal (Always Read)
|
||||
|
||||
| File | Content | Status |
|
||||
|------|---------|--------|
|
||||
| **[mobile-design-thinking.md](mobile-design-thinking.md)** | **⚠️ ANTI-MEMORIZATION: Forces thinking, prevents AI defaults** | **⬜ CRITICAL FIRST** |
|
||||
| **[touch-psychology.md](touch-psychology.md)** | **Fitts' Law, gestures, haptics, thumb zone** | **⬜ CRITICAL** |
|
||||
| **[mobile-performance.md](mobile-performance.md)** | **RN/Flutter performance, 60fps, memory** | **⬜ CRITICAL** |
|
||||
| **[mobile-backend.md](mobile-backend.md)** | **Push notifications, offline sync, mobile API** | **⬜ CRITICAL** |
|
||||
| **[mobile-testing.md](mobile-testing.md)** | **Testing pyramid, E2E, platform-specific** | **⬜ CRITICAL** |
|
||||
| **[mobile-debugging.md](mobile-debugging.md)** | **Native vs JS debugging, Flipper, Logcat** | **⬜ CRITICAL** |
|
||||
| [mobile-navigation.md](mobile-navigation.md) | Tab/Stack/Drawer, deep linking | ⬜ Read |
|
||||
| [mobile-typography.md](mobile-typography.md) | System fonts, Dynamic Type, a11y | ⬜ Read |
|
||||
| [mobile-color-system.md](mobile-color-system.md) | OLED, dark mode, battery-aware | ⬜ Read |
|
||||
| [decision-trees.md](decision-trees.md) | Framework/state/storage selection | ⬜ Read |
|
||||
|
||||
> 🧠 **mobile-design-thinking.md is PRIORITY!** This file ensures AI thinks instead of using memorized patterns.
|
||||
|
||||
### Platform-Specific (Read Based on Target)
|
||||
|
||||
| Platform | File | Content | When to Read |
|
||||
|----------|------|---------|--------------|
|
||||
| **iOS** | [platform-ios.md](platform-ios.md) | Human Interface Guidelines, SF Pro, SwiftUI patterns | Building for iPhone/iPad |
|
||||
| **Android** | [platform-android.md](platform-android.md) | Material Design 3, Roboto, Compose patterns | Building for Android |
|
||||
| **Cross-Platform** | Both above | Platform divergence points | React Native / Flutter |
|
||||
|
||||
> 🔴 **If building for iOS → Read platform-ios.md FIRST!**
|
||||
> 🔴 **If building for Android → Read platform-android.md FIRST!**
|
||||
> 🔴 **If cross-platform → Read BOTH and apply conditional platform logic!**
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ CRITICAL: ASK BEFORE ASSUMING (MANDATORY)
|
||||
|
||||
> **STOP! If the user's request is open-ended, DO NOT default to your favorites.**
|
||||
|
||||
### You MUST Ask If Not Specified:
|
||||
|
||||
| Aspect | Ask | Why |
|
||||
|--------|-----|-----|
|
||||
| **Platform** | "iOS, Android, or both?" | Affects EVERY design decision |
|
||||
| **Framework** | "React Native, Flutter, or native?" | Determines patterns and tools |
|
||||
| **Navigation** | "Tab bar, drawer, or stack-based?" | Core UX decision |
|
||||
| **State** | "What state management? (Zustand/Redux/Riverpod/BLoC?)" | Architecture foundation |
|
||||
| **Offline** | "Does this need to work offline?" | Affects data strategy |
|
||||
| **Target devices** | "Phone only, or tablet support?" | Layout complexity |
|
||||
|
||||
### ⛔ AI MOBILE ANTI-PATTERNS (YASAK LİSTESİ)
|
||||
|
||||
> 🚫 **These are AI default tendencies that MUST be avoided!**
|
||||
|
||||
#### Performance Sins
|
||||
|
||||
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|
||||
|-------------|----------------|--------------|
|
||||
| **ScrollView for long lists** | Renders ALL items, memory explodes | Use `FlatList` / `FlashList` / `ListView.builder` |
|
||||
| **Inline renderItem function** | New function every render, all items re-render | `useCallback` + `React.memo` |
|
||||
| **Missing keyExtractor** | Index-based keys cause bugs on reorder | Unique, stable ID from data |
|
||||
| **Skip getItemLayout** | Async layout = janky scroll | Provide when items have fixed height |
|
||||
| **setState() everywhere** | Unnecessary widget rebuilds | Targeted state, `const` constructors |
|
||||
| **Native driver: false** | Animations blocked by JS thread | `useNativeDriver: true` always |
|
||||
| **console.log in production** | Blocks JS thread severely | Remove before release build |
|
||||
| **Skip React.memo/const** | Every item re-renders on any change | Memoize list items ALWAYS |
|
||||
|
||||
#### Touch/UX Sins
|
||||
|
||||
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|
||||
|-------------|----------------|--------------|
|
||||
| **Touch target < 44px** | Impossible to tap accurately, frustrating | Minimum 44pt (iOS) / 48dp (Android) |
|
||||
| **Spacing < 8px between targets** | Accidental taps on neighbors | Minimum 8-12px gap |
|
||||
| **Gesture-only interactions** | Motor impaired users excluded | Always provide button alternative |
|
||||
| **No loading state** | User thinks app crashed | ALWAYS show loading feedback |
|
||||
| **No error state** | User stuck, no recovery path | Show error with retry option |
|
||||
| **No offline handling** | Crash/block when network lost | Graceful degradation, cached data |
|
||||
| **Ignore platform conventions** | Users confused, muscle memory broken | iOS feels iOS, Android feels Android |
|
||||
|
||||
#### Security Sins
|
||||
|
||||
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|
||||
|-------------|----------------|--------------|
|
||||
| **Token in AsyncStorage** | Easily accessible, stolen on rooted device | `SecureStore` / `Keychain` / `EncryptedSharedPreferences` |
|
||||
| **Hardcode API keys** | Reverse engineered from APK/IPA | Environment variables, secure storage |
|
||||
| **Skip SSL pinning** | MITM attacks possible | Pin certificates in production |
|
||||
| **Log sensitive data** | Logs can be extracted | Never log tokens, passwords, PII |
|
||||
|
||||
#### Architecture Sins
|
||||
|
||||
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|
||||
|-------------|----------------|--------------|
|
||||
| **Business logic in UI** | Untestable, unmaintainable | Service layer separation |
|
||||
| **Global state for everything** | Unnecessary re-renders, complexity | Local state default, lift when needed |
|
||||
| **Deep linking as afterthought** | Notifications, shares broken | Plan deep links from day one |
|
||||
| **Skip dispose/cleanup** | Memory leaks, zombie listeners | Clean up subscriptions, timers |
|
||||
|
||||
---
|
||||
|
||||
## 📱 Platform Decision Matrix
|
||||
|
||||
### When to Unify vs Diverge
|
||||
|
||||
```
|
||||
UNIFY (same on both) DIVERGE (platform-specific)
|
||||
─────────────────── ──────────────────────────
|
||||
Business Logic ✅ Always -
|
||||
Data Layer ✅ Always -
|
||||
Core Features ✅ Always -
|
||||
|
||||
Navigation - ✅ iOS: edge swipe, Android: back button
|
||||
Gestures - ✅ Platform-native feel
|
||||
Icons - ✅ SF Symbols vs Material Icons
|
||||
Date Pickers - ✅ Native pickers feel right
|
||||
Modals/Sheets - ✅ iOS: bottom sheet vs Android: dialog
|
||||
Typography - ✅ SF Pro vs Roboto (or custom)
|
||||
Error Dialogs - ✅ Platform conventions for alerts
|
||||
```
|
||||
|
||||
### Quick Reference: Platform Defaults
|
||||
|
||||
| Element | iOS | Android |
|
||||
|---------|-----|---------|
|
||||
| **Primary Font** | SF Pro / SF Compact | Roboto |
|
||||
| **Min Touch Target** | 44pt × 44pt | 48dp × 48dp |
|
||||
| **Back Navigation** | Edge swipe left | System back button/gesture |
|
||||
| **Bottom Tab Icons** | SF Symbols | Material Symbols |
|
||||
| **Action Sheet** | UIActionSheet from bottom | Bottom Sheet / Dialog |
|
||||
| **Progress** | Spinner | Linear progress (Material) |
|
||||
| **Pull to Refresh** | Native UIRefreshControl | SwipeRefreshLayout |
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Mobile UX Psychology (Quick Reference)
|
||||
|
||||
### Fitts' Law for Touch
|
||||
|
||||
```
|
||||
Desktop: Cursor is precise (1px)
|
||||
Mobile: Finger is imprecise (~7mm contact area)
|
||||
|
||||
→ Touch targets MUST be 44-48px minimum
|
||||
→ Important actions in THUMB ZONE (bottom of screen)
|
||||
→ Destructive actions AWAY from easy reach
|
||||
```
|
||||
|
||||
### Thumb Zone (One-Handed Usage)
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ HARD TO REACH │ ← Navigation, menu, back
|
||||
│ (stretch) │
|
||||
├─────────────────────────────┤
|
||||
│ OK TO REACH │ ← Secondary actions
|
||||
│ (natural) │
|
||||
├─────────────────────────────┤
|
||||
│ EASY TO REACH │ ← PRIMARY CTAs, tab bar
|
||||
│ (thumb's natural arc) │ ← Main content interaction
|
||||
└─────────────────────────────┘
|
||||
[ HOME ]
|
||||
```
|
||||
|
||||
### Mobile-Specific Cognitive Load
|
||||
|
||||
| Desktop | Mobile Difference |
|
||||
|---------|-------------------|
|
||||
| Multiple windows | ONE task at a time |
|
||||
| Keyboard shortcuts | Touch gestures |
|
||||
| Hover states | NO hover (tap or nothing) |
|
||||
| Large viewport | Limited space, scroll vertical |
|
||||
| Stable attention | Interrupted constantly |
|
||||
|
||||
For deep dive: [touch-psychology.md](touch-psychology.md)
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Performance Principles (Quick Reference)
|
||||
|
||||
### React Native Critical Rules
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT: Memoized renderItem + React.memo wrapper
|
||||
const ListItem = React.memo(({ item }: { item: Item }) => (
|
||||
<View style={styles.item}>
|
||||
<Text>{item.title}</Text>
|
||||
</View>
|
||||
));
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ item }: { item: Item }) => <ListItem item={item} />,
|
||||
[]
|
||||
);
|
||||
|
||||
// ✅ CORRECT: FlatList with all optimizations
|
||||
<FlatList
|
||||
data={items}
|
||||
renderItem={renderItem}
|
||||
keyExtractor={(item) => item.id} // Stable ID, NOT index
|
||||
getItemLayout={(data, index) => ({
|
||||
length: ITEM_HEIGHT,
|
||||
offset: ITEM_HEIGHT * index,
|
||||
index,
|
||||
})}
|
||||
removeClippedSubviews={true}
|
||||
maxToRenderPerBatch={10}
|
||||
windowSize={5}
|
||||
/>
|
||||
```
|
||||
|
||||
### Flutter Critical Rules
|
||||
|
||||
```dart
|
||||
// ✅ CORRECT: const constructors prevent rebuilds
|
||||
class MyWidget extends StatelessWidget {
|
||||
const MyWidget({super.key}); // CONST!
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Column( // CONST!
|
||||
children: [
|
||||
Text('Static content'),
|
||||
MyConstantWidget(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Targeted state with ValueListenableBuilder
|
||||
ValueListenableBuilder<int>(
|
||||
valueListenable: counter,
|
||||
builder: (context, value, child) => Text('$value'),
|
||||
child: const ExpensiveWidget(), // Won't rebuild!
|
||||
)
|
||||
```
|
||||
|
||||
### Animation Performance
|
||||
|
||||
```
|
||||
GPU-accelerated (FAST): CPU-bound (SLOW):
|
||||
├── transform ├── width, height
|
||||
├── opacity ├── top, left, right, bottom
|
||||
└── (use these ONLY) ├── margin, padding
|
||||
└── (AVOID animating these)
|
||||
```
|
||||
|
||||
For complete guide: [mobile-performance.md](mobile-performance.md)
|
||||
|
||||
---
|
||||
|
||||
## 📝 CHECKPOINT (MANDATORY Before Any Mobile Work)
|
||||
|
||||
> **Before writing ANY mobile code, you MUST complete this checkpoint:**
|
||||
|
||||
```
|
||||
🧠 CHECKPOINT:
|
||||
|
||||
Platform: [ iOS / Android / Both ]
|
||||
Framework: [ React Native / Flutter / SwiftUI / Kotlin ]
|
||||
Files Read: [ List the skill files you've read ]
|
||||
|
||||
3 Principles I Will Apply:
|
||||
1. _______________
|
||||
2. _______________
|
||||
3. _______________
|
||||
|
||||
Anti-Patterns I Will Avoid:
|
||||
1. _______________
|
||||
2. _______________
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```
|
||||
🧠 CHECKPOINT:
|
||||
|
||||
Platform: iOS + Android (Cross-platform)
|
||||
Framework: React Native + Expo
|
||||
Files Read: touch-psychology.md, mobile-performance.md, platform-ios.md, platform-android.md
|
||||
|
||||
3 Principles I Will Apply:
|
||||
1. FlatList with React.memo + useCallback for all lists
|
||||
2. 48px touch targets, thumb zone for primary CTAs
|
||||
3. Platform-specific navigation (edge swipe iOS, back button Android)
|
||||
|
||||
Anti-Patterns I Will Avoid:
|
||||
1. ScrollView for lists → FlatList
|
||||
2. Inline renderItem → Memoized
|
||||
3. AsyncStorage for tokens → SecureStore
|
||||
```
|
||||
|
||||
> 🔴 **Can't fill the checkpoint? → GO BACK AND READ THE SKILL FILES.**
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Framework Decision Tree
|
||||
|
||||
```
|
||||
WHAT ARE YOU BUILDING?
|
||||
│
|
||||
├── Need OTA updates + rapid iteration + web team
|
||||
│ └── ✅ React Native + Expo
|
||||
│
|
||||
├── Need pixel-perfect custom UI + performance critical
|
||||
│ └── ✅ Flutter
|
||||
│
|
||||
├── Deep native features + single platform focus
|
||||
│ ├── iOS only → SwiftUI
|
||||
│ └── Android only → Kotlin + Jetpack Compose
|
||||
│
|
||||
├── Existing RN codebase + new features
|
||||
│ └── ✅ React Native (bare workflow)
|
||||
│
|
||||
└── Enterprise + existing Flutter codebase
|
||||
└── ✅ Flutter
|
||||
```
|
||||
|
||||
For complete decision trees: [decision-trees.md](decision-trees.md)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Pre-Development Checklist
|
||||
|
||||
### Before Starting ANY Mobile Project
|
||||
|
||||
- [ ] **Platform confirmed?** (iOS / Android / Both)
|
||||
- [ ] **Framework chosen?** (RN / Flutter / Native)
|
||||
- [ ] **Navigation pattern decided?** (Tabs / Stack / Drawer)
|
||||
- [ ] **State management selected?** (Zustand / Redux / Riverpod / BLoC)
|
||||
- [ ] **Offline requirements known?**
|
||||
- [ ] **Deep linking planned from day one?**
|
||||
- [ ] **Target devices defined?** (Phone / Tablet / Both)
|
||||
|
||||
### Before Every Screen
|
||||
|
||||
- [ ] **Touch targets ≥ 44-48px?**
|
||||
- [ ] **Primary CTA in thumb zone?**
|
||||
- [ ] **Loading state exists?**
|
||||
- [ ] **Error state with retry exists?**
|
||||
- [ ] **Offline handling considered?**
|
||||
- [ ] **Platform conventions followed?**
|
||||
|
||||
### Before Release
|
||||
|
||||
- [ ] **console.log removed?**
|
||||
- [ ] **SecureStore for sensitive data?**
|
||||
- [ ] **SSL pinning enabled?**
|
||||
- [ ] **Lists optimized (memo, keyExtractor)?**
|
||||
- [ ] **Memory cleanup on unmount?**
|
||||
- [ ] **Tested on low-end devices?**
|
||||
- [ ] **Accessibility labels on all interactive elements?**
|
||||
|
||||
---
|
||||
|
||||
## 📚 Reference Files
|
||||
|
||||
For deeper guidance on specific areas:
|
||||
|
||||
| File | When to Use |
|
||||
|------|-------------|
|
||||
| [mobile-design-thinking.md](mobile-design-thinking.md) | **FIRST! Anti-memorization, forces context-based thinking** |
|
||||
| [touch-psychology.md](touch-psychology.md) | Understanding touch interaction, Fitts' Law, gesture design |
|
||||
| [mobile-performance.md](mobile-performance.md) | Optimizing RN/Flutter, 60fps, memory/battery |
|
||||
| [platform-ios.md](platform-ios.md) | iOS-specific design, HIG compliance |
|
||||
| [platform-android.md](platform-android.md) | Android-specific design, Material Design 3 |
|
||||
| [mobile-navigation.md](mobile-navigation.md) | Navigation patterns, deep linking |
|
||||
| [mobile-typography.md](mobile-typography.md) | Type scale, system fonts, accessibility |
|
||||
| [mobile-color-system.md](mobile-color-system.md) | OLED optimization, dark mode, battery |
|
||||
| [decision-trees.md](decision-trees.md) | Framework, state, storage decisions |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Mobile users are impatient, interrupted, and using imprecise fingers on small screens. Design for the WORST conditions: bad network, one hand, bright sun, low battery. If it works there, it works everywhere.
|
||||
516
skills/mobile-design/decision-trees.md
Normal file
516
skills/mobile-design/decision-trees.md
Normal file
@@ -0,0 +1,516 @@
|
||||
# Mobile Decision Trees
|
||||
|
||||
> Framework selection, state management, storage strategy, and context-based decisions.
|
||||
> **These are THINKING guides, not copy-paste answers.**
|
||||
|
||||
---
|
||||
|
||||
## 1. Framework Selection
|
||||
|
||||
### Master Decision Tree
|
||||
|
||||
```
|
||||
WHAT ARE YOU BUILDING?
|
||||
│
|
||||
├── Need OTA updates without app store review?
|
||||
│ │
|
||||
│ ├── Yes → React Native + Expo
|
||||
│ │ ├── Expo Go for development
|
||||
│ │ ├── EAS Update for production OTA
|
||||
│ │ └── Best for: rapid iteration, web teams
|
||||
│ │
|
||||
│ └── No → Continue ▼
|
||||
│
|
||||
├── Need pixel-perfect custom UI across platforms?
|
||||
│ │
|
||||
│ ├── Yes → Flutter
|
||||
│ │ ├── Custom rendering engine
|
||||
│ │ ├── Single UI for iOS + Android
|
||||
│ │ └── Best for: branded, visual apps
|
||||
│ │
|
||||
│ └── No → Continue ▼
|
||||
│
|
||||
├── Heavy native features (ARKit, HealthKit, specific sensors)?
|
||||
│ │
|
||||
│ ├── iOS only → SwiftUI / UIKit
|
||||
│ │ └── Maximum native capability
|
||||
│ │
|
||||
│ ├── Android only → Kotlin + Jetpack Compose
|
||||
│ │ └── Maximum native capability
|
||||
│ │
|
||||
│ └── Both → Consider native with shared logic
|
||||
│ └── Kotlin Multiplatform for shared
|
||||
│
|
||||
├── Existing web team + TypeScript codebase?
|
||||
│ │
|
||||
│ └── Yes → React Native
|
||||
│ ├── Familiar paradigm for React devs
|
||||
│ ├── Share code with web (limited)
|
||||
│ └── Large ecosystem
|
||||
│
|
||||
└── Enterprise with existing Flutter team?
|
||||
│
|
||||
└── Yes → Flutter
|
||||
└── Leverage existing expertise
|
||||
```
|
||||
|
||||
### Framework Comparison
|
||||
|
||||
| Factor | React Native | Flutter | Native (Swift/Kotlin) |
|
||||
|--------|-------------|---------|----------------------|
|
||||
| **OTA Updates** | ✅ Expo | ❌ No | ❌ No |
|
||||
| **Learning Curve** | Low (React devs) | Medium | Higher |
|
||||
| **Performance** | Good | Excellent | Best |
|
||||
| **UI Consistency** | Platform-native | Identical | Platform-native |
|
||||
| **Bundle Size** | Medium | Larger | Smallest |
|
||||
| **Native Access** | Via bridges | Via channels | Direct |
|
||||
| **Hot Reload** | ✅ | ✅ | ✅ (Xcode 15+) |
|
||||
|
||||
### When to Choose Native
|
||||
|
||||
```
|
||||
CHOOSE NATIVE WHEN:
|
||||
├── Maximum performance required (games, 3D)
|
||||
├── Deep OS integration needed
|
||||
├── Platform-specific features are core
|
||||
├── Team has native expertise
|
||||
├── App store presence is primary
|
||||
└── Long-term maintenance priority
|
||||
|
||||
AVOID NATIVE WHEN:
|
||||
├── Limited budget/time
|
||||
├── Need rapid iteration
|
||||
├── Identical UI on both platforms
|
||||
├── Team is web-focused
|
||||
└── Cross-platform is priority
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. State Management Selection
|
||||
|
||||
### React Native State Decision
|
||||
|
||||
```
|
||||
WHAT'S YOUR STATE COMPLEXITY?
|
||||
│
|
||||
├── Simple app, few screens, minimal shared state
|
||||
│ │
|
||||
│ └── Zustand (or just useState/Context)
|
||||
│ ├── Minimal boilerplate
|
||||
│ ├── Easy to understand
|
||||
│ └── Scales OK to medium
|
||||
│
|
||||
├── Primarily server data (API-driven)
|
||||
│ │
|
||||
│ └── TanStack Query (React Query) + Zustand
|
||||
│ ├── Query for server state
|
||||
│ ├── Zustand for UI state
|
||||
│ └── Excellent caching, refetching
|
||||
│
|
||||
├── Complex app with many features
|
||||
│ │
|
||||
│ └── Redux Toolkit + RTK Query
|
||||
│ ├── Predicable, debuggable
|
||||
│ ├── RTK Query for API
|
||||
│ └── Good for large teams
|
||||
│
|
||||
└── Atomic, granular state needs
|
||||
│
|
||||
└── Jotai
|
||||
├── Atom-based (like Recoil)
|
||||
├── Minimizes re-renders
|
||||
└── Good for derived state
|
||||
```
|
||||
|
||||
### Flutter State Decision
|
||||
|
||||
```
|
||||
WHAT'S YOUR STATE COMPLEXITY?
|
||||
│
|
||||
├── Simple app, learning Flutter
|
||||
│ │
|
||||
│ └── Provider (or setState)
|
||||
│ ├── Official, simple
|
||||
│ ├── Built into Flutter
|
||||
│ └── Good for small apps
|
||||
│
|
||||
├── Modern, type-safe, testable
|
||||
│ │
|
||||
│ └── Riverpod 2.0
|
||||
│ ├── Compile-time safety
|
||||
│ ├── Code generation
|
||||
│ ├── Excellent for medium-large apps
|
||||
│ └── Recommended for new projects
|
||||
│
|
||||
├── Enterprise, strict patterns needed
|
||||
│ │
|
||||
│ └── BLoC
|
||||
│ ├── Event → State pattern
|
||||
│ ├── Very testable
|
||||
│ ├── More boilerplate
|
||||
│ └── Good for large teams
|
||||
│
|
||||
└── Quick prototyping
|
||||
│
|
||||
└── GetX (with caution)
|
||||
├── Fast to implement
|
||||
├── Less strict patterns
|
||||
└── Can become messy at scale
|
||||
```
|
||||
|
||||
### State Management Anti-Patterns
|
||||
|
||||
```
|
||||
❌ DON'T:
|
||||
├── Use global state for everything
|
||||
├── Mix state management approaches
|
||||
├── Store server state in local state
|
||||
├── Skip state normalization
|
||||
├── Overuse Context (re-render heavy)
|
||||
└── Put navigation state in app state
|
||||
|
||||
✅ DO:
|
||||
├── Server state → Query library
|
||||
├── UI state → Minimal, local first
|
||||
├── Lift state only when needed
|
||||
├── Choose ONE approach per project
|
||||
└── Keep state close to where it's used
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Navigation Pattern Selection
|
||||
|
||||
```
|
||||
HOW MANY TOP-LEVEL DESTINATIONS?
|
||||
│
|
||||
├── 2 destinations
|
||||
│ └── Consider: Top tabs or simple stack
|
||||
│
|
||||
├── 3-5 destinations (equal importance)
|
||||
│ └── ✅ Tab Bar / Bottom Navigation
|
||||
│ ├── Most common pattern
|
||||
│ └── Easy discovery
|
||||
│
|
||||
├── 5+ destinations
|
||||
│ │
|
||||
│ ├── All important → Drawer Navigation
|
||||
│ │ └── Hidden but many options
|
||||
│ │
|
||||
│ └── Some less important → Tab bar + drawer hybrid
|
||||
│
|
||||
└── Single linear flow?
|
||||
└── Stack Navigation only
|
||||
└── Onboarding, checkout, etc.
|
||||
```
|
||||
|
||||
### Navigation by App Type
|
||||
|
||||
| App Type | Pattern | Reason |
|
||||
|----------|---------|--------|
|
||||
| Social (Instagram) | Tab bar | Frequent switching |
|
||||
| E-commerce | Tab bar + stack | Categories as tabs |
|
||||
| Email (Gmail) | Drawer + list-detail | Many folders |
|
||||
| Settings | Stack only | Deep drill-down |
|
||||
| Onboarding | Stack wizard | Linear flow |
|
||||
| Messaging | Tab (chats) + stack | Threads |
|
||||
|
||||
---
|
||||
|
||||
## 4. Storage Strategy Selection
|
||||
|
||||
```
|
||||
WHAT TYPE OF DATA?
|
||||
│
|
||||
├── Sensitive (tokens, passwords, keys)
|
||||
│ │
|
||||
│ └── ✅ Secure Storage
|
||||
│ ├── iOS: Keychain
|
||||
│ ├── Android: EncryptedSharedPreferences
|
||||
│ └── RN: expo-secure-store / react-native-keychain
|
||||
│
|
||||
├── User preferences (settings, theme)
|
||||
│ │
|
||||
│ └── ✅ Key-Value Storage
|
||||
│ ├── iOS: UserDefaults
|
||||
│ ├── Android: SharedPreferences
|
||||
│ └── RN: AsyncStorage / MMKV
|
||||
│
|
||||
├── Structured data (entities, relationships)
|
||||
│ │
|
||||
│ └── ✅ Database
|
||||
│ ├── SQLite (expo-sqlite, sqflite)
|
||||
│ ├── Realm (NoSQL, reactive)
|
||||
│ └── WatermelonDB (large datasets)
|
||||
│
|
||||
├── Large files (images, documents)
|
||||
│ │
|
||||
│ └── ✅ File System
|
||||
│ ├── iOS: Documents / Caches directory
|
||||
│ ├── Android: Internal/External storage
|
||||
│ └── RN: react-native-fs / expo-file-system
|
||||
│
|
||||
└── Cached API data
|
||||
│
|
||||
└── ✅ Query Library Cache
|
||||
├── TanStack Query (RN)
|
||||
├── Riverpod async (Flutter)
|
||||
└── Automatic invalidation
|
||||
```
|
||||
|
||||
### Storage Comparison
|
||||
|
||||
| Storage | Speed | Security | Capacity | Use Case |
|
||||
|---------|-------|----------|----------|----------|
|
||||
| Secure Storage | Medium | 🔒 High | Small | Tokens, secrets |
|
||||
| Key-Value | Fast | Low | Medium | Settings |
|
||||
| SQLite | Fast | Low | Large | Structured data |
|
||||
| File System | Medium | Low | Very Large | Media, documents |
|
||||
| Query Cache | Fast | Low | Medium | API responses |
|
||||
|
||||
---
|
||||
|
||||
## 5. Offline Strategy Selection
|
||||
|
||||
```
|
||||
HOW CRITICAL IS OFFLINE?
|
||||
│
|
||||
├── Nice to have (works when possible)
|
||||
│ │
|
||||
│ └── Cache last data + show stale
|
||||
│ ├── Simple implementation
|
||||
│ ├── TanStack Query with staleTime
|
||||
│ └── Show "last updated" timestamp
|
||||
│
|
||||
├── Essential (core functionality offline)
|
||||
│ │
|
||||
│ └── Offline-first architecture
|
||||
│ ├── Local database as source of truth
|
||||
│ ├── Sync to server when online
|
||||
│ ├── Conflict resolution strategy
|
||||
│ └── Queue actions for later sync
|
||||
│
|
||||
└── Real-time critical (collaboration, chat)
|
||||
│
|
||||
└── WebSocket + local queue
|
||||
├── Optimistic updates
|
||||
├── Eventual consistency
|
||||
└── Complex conflict handling
|
||||
```
|
||||
|
||||
### Offline Implementation Patterns
|
||||
|
||||
```
|
||||
1. CACHE-FIRST (Simple)
|
||||
Request → Check cache → If stale, fetch → Update cache
|
||||
|
||||
2. STALE-WHILE-REVALIDATE
|
||||
Request → Return cached → Fetch update → Update UI
|
||||
|
||||
3. OFFLINE-FIRST (Complex)
|
||||
Action → Write to local DB → Queue sync → Sync when online
|
||||
|
||||
4. SYNC ENGINE
|
||||
Use: Firebase, Realm Sync, Supabase realtime
|
||||
Handles conflict resolution automatically
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Authentication Pattern Selection
|
||||
|
||||
```
|
||||
WHAT AUTH TYPE NEEDED?
|
||||
│
|
||||
├── Simple email/password
|
||||
│ │
|
||||
│ └── Token-based (JWT)
|
||||
│ ├── Store refresh token securely
|
||||
│ ├── Access token in memory
|
||||
│ └── Silent refresh flow
|
||||
│
|
||||
├── Social login (Google, Apple, etc.)
|
||||
│ │
|
||||
│ └── OAuth 2.0 + PKCE
|
||||
│ ├── Use platform SDKs
|
||||
│ ├── Deep link callback
|
||||
│ └── Apple Sign-In required for iOS
|
||||
│
|
||||
├── Enterprise/SSO
|
||||
│ │
|
||||
│ └── OIDC / SAML
|
||||
│ ├── Web view or system browser
|
||||
│ └── Handle redirect properly
|
||||
│
|
||||
└── Biometric (FaceID, fingerprint)
|
||||
│
|
||||
└── Local auth + secure token
|
||||
├── Biometrics unlock stored token
|
||||
├── Not a replacement for server auth
|
||||
└── Fallback to PIN/password
|
||||
```
|
||||
|
||||
### Auth Token Storage
|
||||
|
||||
```
|
||||
❌ NEVER store tokens in:
|
||||
├── AsyncStorage (plain text)
|
||||
├── Redux/state (not persisted correctly)
|
||||
├── Local storage equivalent
|
||||
└── Logs or debug output
|
||||
|
||||
✅ ALWAYS store tokens in:
|
||||
├── iOS: Keychain
|
||||
├── Android: EncryptedSharedPreferences
|
||||
├── Expo: SecureStore
|
||||
├── Biometric-protected if available
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Project Type Templates
|
||||
|
||||
### E-Commerce App
|
||||
|
||||
```
|
||||
RECOMMENDED STACK:
|
||||
├── Framework: React Native + Expo (OTA for pricing)
|
||||
├── Navigation: Tab bar (Home, Search, Cart, Account)
|
||||
├── State: TanStack Query (products) + Zustand (cart)
|
||||
├── Storage: SecureStore (auth) + SQLite (cart cache)
|
||||
├── Offline: Cache products, queue cart actions
|
||||
└── Auth: Email/password + Social + Apple Pay
|
||||
|
||||
KEY DECISIONS:
|
||||
├── Product images: Lazy load, cache aggressively
|
||||
├── Cart: Sync across devices via API
|
||||
├── Checkout: Secure, minimal steps
|
||||
└── Deep links: Product shares, marketing
|
||||
```
|
||||
|
||||
### Social/Content App
|
||||
|
||||
```
|
||||
RECOMMENDED STACK:
|
||||
├── Framework: React Native or Flutter
|
||||
├── Navigation: Tab bar (Feed, Search, Create, Notifications, Profile)
|
||||
├── State: TanStack Query (feed) + Zustand (UI)
|
||||
├── Storage: SQLite (feed cache, drafts)
|
||||
├── Offline: Cache feed, queue posts
|
||||
└── Auth: Social login primary, Apple required
|
||||
|
||||
KEY DECISIONS:
|
||||
├── Feed: Infinite scroll, memoized items
|
||||
├── Media: Upload queuing, background upload
|
||||
├── Push: Deep link to content
|
||||
└── Real-time: WebSocket for notifications
|
||||
```
|
||||
|
||||
### Productivity/SaaS App
|
||||
|
||||
```
|
||||
RECOMMENDED STACK:
|
||||
├── Framework: Flutter (consistent UI) or RN
|
||||
├── Navigation: Drawer or Tab bar
|
||||
├── State: Riverpod/BLoC or Redux Toolkit
|
||||
├── Storage: SQLite (offline), SecureStore (auth)
|
||||
├── Offline: Full offline editing, sync
|
||||
└── Auth: SSO/OIDC for enterprise
|
||||
|
||||
KEY DECISIONS:
|
||||
├── Data sync: Conflict resolution strategy
|
||||
├── Collaborative: Real-time or eventual?
|
||||
├── Files: Large file handling
|
||||
└── Enterprise: MDM, compliance
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Decision Checklist
|
||||
|
||||
### Before Starting ANY Project
|
||||
|
||||
- [ ] Target platforms defined (iOS/Android/both)?
|
||||
- [ ] Framework selected based on criteria?
|
||||
- [ ] State management approach chosen?
|
||||
- [ ] Navigation pattern selected?
|
||||
- [ ] Storage strategy for each data type?
|
||||
- [ ] Offline requirements defined?
|
||||
- [ ] Auth flow designed?
|
||||
- [ ] Deep linking planned from start?
|
||||
|
||||
### Questions to Ask User
|
||||
|
||||
```
|
||||
If project details are vague, ASK:
|
||||
|
||||
1. "Will this need OTA updates without app store review?"
|
||||
→ Affects framework choice (Expo = yes)
|
||||
|
||||
2. "Do iOS and Android need identical UI?"
|
||||
→ Affects framework (Flutter = identical)
|
||||
|
||||
3. "What's the offline requirement?"
|
||||
→ Affects architecture complexity
|
||||
|
||||
4. "Is there an existing backend/auth system?"
|
||||
→ Affects auth and API approach
|
||||
|
||||
5. "What devices? Phone only, or tablet?"
|
||||
→ Affects navigation and layout
|
||||
|
||||
6. "Enterprise or consumer?"
|
||||
→ Affects auth (SSO), security, compliance
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Anti-Pattern Decisions
|
||||
|
||||
### ❌ Decision Anti-Patterns
|
||||
|
||||
| Anti-Pattern | Why It's Bad | Better Approach |
|
||||
|--------------|--------------|-----------------|
|
||||
| **Redux for simple app** | Massive overkill | Zustand or context |
|
||||
| **Native for MVP** | Slow development | Cross-platform MVP |
|
||||
| **Drawer for 3 sections** | Hidden navigation | Tab bar |
|
||||
| **AsyncStorage for tokens** | Insecure | SecureStore |
|
||||
| **No offline consideration** | Broken on subway | Plan from start |
|
||||
| **Same stack for all projects** | Doesn't fit context | Evaluate per project |
|
||||
|
||||
---
|
||||
|
||||
## 10. Quick Reference
|
||||
|
||||
### Framework Quick Pick
|
||||
|
||||
```
|
||||
OTA needed? → React Native + Expo
|
||||
Identical UI? → Flutter
|
||||
Maximum performance? → Native
|
||||
Web team? → React Native
|
||||
Quick prototype? → Expo
|
||||
```
|
||||
|
||||
### State Quick Pick
|
||||
|
||||
```
|
||||
Simple app? → Zustand / Provider
|
||||
Server-heavy? → TanStack Query / Riverpod
|
||||
Enterprise? → Redux / BLoC
|
||||
Atomic state? → Jotai
|
||||
```
|
||||
|
||||
### Storage Quick Pick
|
||||
|
||||
```
|
||||
Secrets? → SecureStore / Keychain
|
||||
Settings? → AsyncStorage / UserDefaults
|
||||
Structured data? → SQLite
|
||||
API cache? → Query library
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** These trees are guides for THINKING, not rules to follow blindly. Every project has unique constraints. ASK clarifying questions when requirements are vague, and choose based on actual needs, not defaults.
|
||||
491
skills/mobile-design/mobile-backend.md
Normal file
491
skills/mobile-design/mobile-backend.md
Normal file
@@ -0,0 +1,491 @@
|
||||
# Mobile Backend Patterns
|
||||
|
||||
> **This file covers backend/API patterns SPECIFIC to mobile clients.**
|
||||
> Generic backend patterns are in `nodejs-best-practices` and `api-patterns`.
|
||||
> **Mobile backend is NOT the same as web backend. Different constraints, different patterns.**
|
||||
|
||||
---
|
||||
|
||||
## 🧠 MOBILE BACKEND MINDSET
|
||||
|
||||
```
|
||||
Mobile clients are DIFFERENT from web clients:
|
||||
├── Unreliable network (2G, subway, elevator)
|
||||
├── Battery constraints (minimize wake-ups)
|
||||
├── Limited storage (can't cache everything)
|
||||
├── Interrupted sessions (calls, notifications)
|
||||
├── Diverse devices (old phones to flagships)
|
||||
└── Binary updates are slow (App Store review)
|
||||
```
|
||||
|
||||
**Your backend must compensate for ALL of these.**
|
||||
|
||||
---
|
||||
|
||||
## 🚫 AI MOBILE BACKEND ANTI-PATTERNS
|
||||
|
||||
### These are common AI mistakes when building mobile backends:
|
||||
|
||||
| ❌ AI Default | Why It's Wrong | ✅ Mobile-Correct |
|
||||
|---------------|----------------|-------------------|
|
||||
| Same API for web and mobile | Mobile needs compact responses | Separate mobile endpoints OR field selection |
|
||||
| Full object responses | Wastes bandwidth, battery | Partial responses, pagination |
|
||||
| No offline consideration | App crashes without network | Offline-first design, sync queues |
|
||||
| WebSocket for everything | Battery drain | Push notifications + polling fallback |
|
||||
| No app versioning | Can't force updates, breaking changes | Version headers, minimum version check |
|
||||
| Generic error messages | Users can't fix issues | Mobile-specific error codes + recovery actions |
|
||||
| Session-based auth | Mobile apps restart | Token-based with refresh |
|
||||
| Ignore device info | Can't debug issues | Device ID, app version in headers |
|
||||
|
||||
---
|
||||
|
||||
## 1. Push Notifications
|
||||
|
||||
### Platform Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ YOUR BACKEND │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │ │
|
||||
│ ┌──────────┴──────────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ FCM (Google) │ │ APNs (Apple) │ │
|
||||
│ │ Firebase │ │ Direct or FCM │ │
|
||||
│ └────────┬────────┘ └────────┬────────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ Android Device │ │ iOS Device │ │
|
||||
│ └─────────────────┘ └─────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Push Types
|
||||
|
||||
| Type | Use Case | User Sees |
|
||||
|------|----------|-----------|
|
||||
| **Display** | New message, order update | Notification banner |
|
||||
| **Silent** | Background sync, content update | Nothing (background) |
|
||||
| **Data** | Custom handling by app | Depends on app logic |
|
||||
|
||||
### Anti-Patterns
|
||||
|
||||
| ❌ NEVER | ✅ ALWAYS |
|
||||
|----------|----------|
|
||||
| Send sensitive data in push | Push says "New message", app fetches content |
|
||||
| Overload with pushes | Batch, dedupe, respect quiet hours |
|
||||
| Same message to all | Segment by user preference, timezone |
|
||||
| Ignore failed tokens | Clean up invalid tokens regularly |
|
||||
| Skip APNs for iOS | FCM alone doesn't guarantee iOS delivery |
|
||||
|
||||
### Token Management
|
||||
|
||||
```
|
||||
TOKEN LIFECYCLE:
|
||||
├── App registers → Get token → Send to backend
|
||||
├── Token can change → App must re-register on start
|
||||
├── Token expires → Clean from database
|
||||
├── User uninstalls → Token becomes invalid (detect via error)
|
||||
└── Multiple devices → Store multiple tokens per user
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Offline Sync & Conflict Resolution
|
||||
|
||||
### Sync Strategy Selection
|
||||
|
||||
```
|
||||
WHAT TYPE OF DATA?
|
||||
│
|
||||
├── Read-only (news, catalog)
|
||||
│ └── Simple cache + TTL
|
||||
│ └── ETag/Last-Modified for invalidation
|
||||
│
|
||||
├── User-owned (notes, todos)
|
||||
│ └── Last-write-wins (simple)
|
||||
│ └── Or timestamp-based merge
|
||||
│
|
||||
├── Collaborative (shared docs)
|
||||
│ └── CRDT or OT required
|
||||
│ └── Consider Firebase/Supabase
|
||||
│
|
||||
└── Critical (payments, inventory)
|
||||
└── Server is source of truth
|
||||
└── Optimistic UI + server confirmation
|
||||
```
|
||||
|
||||
### Conflict Resolution Strategies
|
||||
|
||||
| Strategy | How It Works | Best For |
|
||||
|----------|--------------|----------|
|
||||
| **Last-write-wins** | Latest timestamp overwrites | Simple data, single user |
|
||||
| **Server-wins** | Server always authoritative | Critical transactions |
|
||||
| **Client-wins** | Offline changes prioritized | Offline-heavy apps |
|
||||
| **Merge** | Combine changes field-by-field | Documents, rich content |
|
||||
| **CRDT** | Mathematically conflict-free | Real-time collaboration |
|
||||
|
||||
### Sync Queue Pattern
|
||||
|
||||
```
|
||||
CLIENT SIDE:
|
||||
├── User makes change → Write to local DB
|
||||
├── Add to sync queue → { action, data, timestamp, retries }
|
||||
├── Network available → Process queue FIFO
|
||||
├── Success → Remove from queue
|
||||
├── Failure → Retry with backoff (max 5 retries)
|
||||
└── Conflict → Apply resolution strategy
|
||||
|
||||
SERVER SIDE:
|
||||
├── Accept change with client timestamp
|
||||
├── Compare with server version
|
||||
├── Apply conflict resolution
|
||||
├── Return merged state
|
||||
└── Client updates local with server response
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Mobile API Optimization
|
||||
|
||||
### Response Size Reduction
|
||||
|
||||
| Technique | Savings | Implementation |
|
||||
|-----------|---------|----------------|
|
||||
| **Field selection** | 30-70% | `?fields=id,name,thumbnail` |
|
||||
| **Compression** | 60-80% | gzip/brotli (automatic) |
|
||||
| **Pagination** | Varies | Cursor-based for mobile |
|
||||
| **Image variants** | 50-90% | `/image?w=200&q=80` |
|
||||
| **Delta sync** | 80-95% | Only changed records since timestamp |
|
||||
|
||||
### Pagination: Cursor vs Offset
|
||||
|
||||
```
|
||||
OFFSET (Bad for mobile):
|
||||
├── Page 1: OFFSET 0 LIMIT 20
|
||||
├── Page 2: OFFSET 20 LIMIT 20
|
||||
├── Problem: New item added → duplicates!
|
||||
└── Problem: Large offset = slow query
|
||||
|
||||
CURSOR (Good for mobile):
|
||||
├── First: ?limit=20
|
||||
├── Next: ?limit=20&after=cursor_abc123
|
||||
├── Cursor = encoded (id + sort values)
|
||||
├── No duplicates on data changes
|
||||
└── Consistent performance
|
||||
```
|
||||
|
||||
### Batch Requests
|
||||
|
||||
```
|
||||
Instead of:
|
||||
GET /users/1
|
||||
GET /users/2
|
||||
GET /users/3
|
||||
(3 round trips, 3x latency)
|
||||
|
||||
Use:
|
||||
POST /batch
|
||||
{ requests: [
|
||||
{ method: "GET", path: "/users/1" },
|
||||
{ method: "GET", path: "/users/2" },
|
||||
{ method: "GET", path: "/users/3" }
|
||||
]}
|
||||
(1 round trip)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. App Versioning
|
||||
|
||||
### Version Check Endpoint
|
||||
|
||||
```
|
||||
GET /api/app-config
|
||||
Headers:
|
||||
X-App-Version: 2.1.0
|
||||
X-Platform: ios
|
||||
X-Device-ID: abc123
|
||||
|
||||
Response:
|
||||
{
|
||||
"minimum_version": "2.0.0",
|
||||
"latest_version": "2.3.0",
|
||||
"force_update": false,
|
||||
"update_url": "https://apps.apple.com/...",
|
||||
"feature_flags": {
|
||||
"new_player": true,
|
||||
"dark_mode": true
|
||||
},
|
||||
"maintenance": false,
|
||||
"maintenance_message": null
|
||||
}
|
||||
```
|
||||
|
||||
### Version Comparison Logic
|
||||
|
||||
```
|
||||
CLIENT VERSION vs MINIMUM VERSION:
|
||||
├── client >= minimum → Continue normally
|
||||
├── client < minimum → Show force update screen
|
||||
│ └── Block app usage until updated
|
||||
└── client < latest → Show optional update prompt
|
||||
|
||||
FEATURE FLAGS:
|
||||
├── Enable/disable features without app update
|
||||
├── A/B testing by version/device
|
||||
└── Gradual rollout (10% → 50% → 100%)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Authentication for Mobile
|
||||
|
||||
### Token Strategy
|
||||
|
||||
```
|
||||
ACCESS TOKEN:
|
||||
├── Short-lived (15 min - 1 hour)
|
||||
├── Stored in memory (not persistent)
|
||||
├── Used for API requests
|
||||
└── Refresh when expired
|
||||
|
||||
REFRESH TOKEN:
|
||||
├── Long-lived (30-90 days)
|
||||
├── Stored in SecureStore/Keychain
|
||||
├── Used only to get new access token
|
||||
└── Rotate on each use (security)
|
||||
|
||||
DEVICE TOKEN:
|
||||
├── Identifies this device
|
||||
├── Allows "log out all devices"
|
||||
├── Stored alongside refresh token
|
||||
└── Server tracks active devices
|
||||
```
|
||||
|
||||
### Silent Re-authentication
|
||||
|
||||
```
|
||||
REQUEST FLOW:
|
||||
├── Make request with access token
|
||||
├── 401 Unauthorized?
|
||||
│ ├── Have refresh token?
|
||||
│ │ ├── Yes → Call /auth/refresh
|
||||
│ │ │ ├── Success → Retry original request
|
||||
│ │ │ └── Failure → Force logout
|
||||
│ │ └── No → Force logout
|
||||
│ └── Token just expired (not invalid)
|
||||
│ └── Auto-refresh, user doesn't notice
|
||||
└── Success → Continue
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Error Handling for Mobile
|
||||
|
||||
### Mobile-Specific Error Format
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "PAYMENT_DECLINED",
|
||||
"message": "Your payment was declined",
|
||||
"user_message": "Please check your card details or try another payment method",
|
||||
"action": {
|
||||
"type": "navigate",
|
||||
"destination": "payment_methods"
|
||||
},
|
||||
"retry": {
|
||||
"allowed": true,
|
||||
"after_seconds": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Categories
|
||||
|
||||
| Code Range | Category | Mobile Handling |
|
||||
|------------|----------|-----------------|
|
||||
| 400-499 | Client error | Show message, user action needed |
|
||||
| 401 | Auth expired | Silent refresh or re-login |
|
||||
| 403 | Forbidden | Show upgrade/permission screen |
|
||||
| 404 | Not found | Remove from local cache |
|
||||
| 409 | Conflict | Show sync conflict UI |
|
||||
| 429 | Rate limit | Retry after header, backoff |
|
||||
| 500-599 | Server error | Retry with backoff, show "try later" |
|
||||
| Network | No connection | Use cached data, queue for sync |
|
||||
|
||||
---
|
||||
|
||||
## 7. Media & Binary Handling
|
||||
|
||||
### Image Optimization
|
||||
|
||||
```
|
||||
CLIENT REQUEST:
|
||||
GET /images/{id}?w=400&h=300&q=80&format=webp
|
||||
|
||||
SERVER RESPONSE:
|
||||
├── Resize on-the-fly OR use CDN
|
||||
├── WebP for Android (smaller)
|
||||
├── HEIC for iOS 14+ (if supported)
|
||||
├── JPEG fallback
|
||||
└── Cache-Control: max-age=31536000
|
||||
```
|
||||
|
||||
### Chunked Upload (Large Files)
|
||||
|
||||
```
|
||||
UPLOAD FLOW:
|
||||
1. POST /uploads/init
|
||||
{ filename, size, mime_type }
|
||||
→ { upload_id, chunk_size }
|
||||
|
||||
2. PUT /uploads/{upload_id}/chunks/{n}
|
||||
→ Upload each chunk (1-5 MB)
|
||||
→ Can resume if interrupted
|
||||
|
||||
3. POST /uploads/{upload_id}/complete
|
||||
→ Server assembles chunks
|
||||
→ Return final file URL
|
||||
```
|
||||
|
||||
### Streaming Audio/Video
|
||||
|
||||
```
|
||||
REQUIREMENTS:
|
||||
├── HLS (HTTP Live Streaming) for iOS
|
||||
├── DASH or HLS for Android
|
||||
├── Multiple quality levels (adaptive bitrate)
|
||||
├── Range request support (seeking)
|
||||
└── Offline download chunks
|
||||
|
||||
ENDPOINTS:
|
||||
GET /media/{id}/manifest.m3u8 → HLS manifest
|
||||
GET /media/{id}/segment_{n}.ts → Video segment
|
||||
GET /media/{id}/download → Full file for offline
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Security for Mobile
|
||||
|
||||
### Device Attestation
|
||||
|
||||
```
|
||||
VERIFY REAL DEVICE (not emulator/bot):
|
||||
├── iOS: DeviceCheck API
|
||||
│ └── Server verifies with Apple
|
||||
├── Android: Play Integrity API (replaces SafetyNet)
|
||||
│ └── Server verifies with Google
|
||||
└── Fail closed: Reject if attestation fails
|
||||
```
|
||||
|
||||
### Request Signing
|
||||
|
||||
```
|
||||
CLIENT:
|
||||
├── Create signature = HMAC(timestamp + path + body, secret)
|
||||
├── Send: X-Signature: {signature}
|
||||
├── Send: X-Timestamp: {timestamp}
|
||||
└── Send: X-Device-ID: {device_id}
|
||||
|
||||
SERVER:
|
||||
├── Validate timestamp (within 5 minutes)
|
||||
├── Recreate signature with same inputs
|
||||
├── Compare signatures
|
||||
└── Reject if mismatch (tampering detected)
|
||||
```
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
```
|
||||
MOBILE-SPECIFIC LIMITS:
|
||||
├── Per device (X-Device-ID)
|
||||
├── Per user (after auth)
|
||||
├── Per endpoint (stricter for sensitive)
|
||||
└── Sliding window preferred
|
||||
|
||||
HEADERS:
|
||||
X-RateLimit-Limit: 100
|
||||
X-RateLimit-Remaining: 95
|
||||
X-RateLimit-Reset: 1609459200
|
||||
Retry-After: 60 (when 429)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Monitoring & Analytics
|
||||
|
||||
### Required Headers from Mobile
|
||||
|
||||
```
|
||||
Every mobile request should include:
|
||||
├── X-App-Version: 2.1.0
|
||||
├── X-Platform: ios | android
|
||||
├── X-OS-Version: 17.0
|
||||
├── X-Device-Model: iPhone15,2
|
||||
├── X-Device-ID: uuid (persistent)
|
||||
├── X-Request-ID: uuid (per request, for tracing)
|
||||
├── Accept-Language: tr-TR
|
||||
└── X-Timezone: Europe/Istanbul
|
||||
```
|
||||
|
||||
### What to Log
|
||||
|
||||
```
|
||||
FOR EACH REQUEST:
|
||||
├── All headers above
|
||||
├── Endpoint, method, status
|
||||
├── Response time
|
||||
├── Error details (if any)
|
||||
└── User ID (if authenticated)
|
||||
|
||||
ALERTS:
|
||||
├── Error rate > 5% per version
|
||||
├── P95 latency > 2 seconds
|
||||
├── Specific version crash spike
|
||||
├── Auth failure spike (attack?)
|
||||
└── Push delivery failure spike
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 MOBILE BACKEND CHECKLIST
|
||||
|
||||
### Before API Design
|
||||
- [ ] Identified mobile-specific requirements?
|
||||
- [ ] Planned offline behavior?
|
||||
- [ ] Designed sync strategy?
|
||||
- [ ] Considered bandwidth constraints?
|
||||
|
||||
### For Every Endpoint
|
||||
- [ ] Response as small as possible?
|
||||
- [ ] Pagination cursor-based?
|
||||
- [ ] Proper caching headers?
|
||||
- [ ] Mobile error format with actions?
|
||||
|
||||
### Authentication
|
||||
- [ ] Token refresh implemented?
|
||||
- [ ] Silent re-auth flow?
|
||||
- [ ] Multi-device logout?
|
||||
- [ ] Secure token storage guidance?
|
||||
|
||||
### Push Notifications
|
||||
- [ ] FCM + APNs configured?
|
||||
- [ ] Token lifecycle managed?
|
||||
- [ ] Silent vs display push defined?
|
||||
- [ ] Sensitive data NOT in push payload?
|
||||
|
||||
### Release
|
||||
- [ ] Version check endpoint ready?
|
||||
- [ ] Feature flags configured?
|
||||
- [ ] Force update mechanism?
|
||||
- [ ] Monitoring headers required?
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Mobile backend must be resilient to bad networks, respect battery life, and handle interrupted sessions gracefully. The client cannot be trusted, but it also cannot be hung up—provide offline capabilities and clear error recovery paths.
|
||||
420
skills/mobile-design/mobile-color-system.md
Normal file
420
skills/mobile-design/mobile-color-system.md
Normal file
@@ -0,0 +1,420 @@
|
||||
# Mobile Color System Reference
|
||||
|
||||
> OLED optimization, dark mode, battery-aware colors, and outdoor visibility.
|
||||
> **Color on mobile isn't just aesthetics—it's battery life and usability.**
|
||||
|
||||
---
|
||||
|
||||
## 1. Mobile Color Fundamentals
|
||||
|
||||
### Why Mobile Color is Different
|
||||
|
||||
```
|
||||
DESKTOP: MOBILE:
|
||||
├── LCD screens (backlit) ├── OLED common (self-emissive)
|
||||
├── Controlled lighting ├── Outdoor, bright sun
|
||||
├── Stable power ├── Battery matters
|
||||
├── Personal preference ├── System-wide dark mode
|
||||
└── Static viewing └── Variable angles, motion
|
||||
```
|
||||
|
||||
### Mobile Color Priorities
|
||||
|
||||
| Priority | Why |
|
||||
|----------|-----|
|
||||
| **1. Readability** | Outdoor, variable lighting |
|
||||
| **2. Battery efficiency** | OLED = dark mode saves power |
|
||||
| **3. System integration** | Dark/light mode support |
|
||||
| **4. Semantics** | Error, success, warning colors |
|
||||
| **5. Brand** | After functional requirements |
|
||||
|
||||
---
|
||||
|
||||
## 2. OLED Considerations
|
||||
|
||||
### How OLED Differs
|
||||
|
||||
```
|
||||
LCD (Liquid Crystal Display):
|
||||
├── Backlight always on
|
||||
├── Black = backlight through dark filter
|
||||
├── Energy use = constant
|
||||
└── Dark mode = no battery savings
|
||||
|
||||
OLED (Organic LED):
|
||||
├── Each pixel emits own light
|
||||
├── Black = pixel OFF (zero power)
|
||||
├── Energy use = brighter pixels use more
|
||||
└── Dark mode = significant battery savings
|
||||
```
|
||||
|
||||
### Battery Savings with OLED
|
||||
|
||||
```
|
||||
Color energy consumption (relative):
|
||||
|
||||
#000000 (True Black) ████░░░░░░ 0%
|
||||
#1A1A1A (Near Black) █████░░░░░ ~15%
|
||||
#333333 (Dark Gray) ██████░░░░ ~30%
|
||||
#666666 (Medium Gray) ███████░░░ ~50%
|
||||
#FFFFFF (White) ██████████ 100%
|
||||
|
||||
Saturated colors also use significant power:
|
||||
├── Blue pixels: Most efficient
|
||||
├── Green pixels: Medium
|
||||
├── Red pixels: Least efficient
|
||||
└── Desaturated colors save more
|
||||
```
|
||||
|
||||
### True Black vs Near Black
|
||||
|
||||
```
|
||||
#000000 (True Black):
|
||||
├── Maximum battery savings
|
||||
├── Can cause "black smear" on scroll
|
||||
├── Sharp contrast (may be harsh)
|
||||
└── Used by Apple in pure dark mode
|
||||
|
||||
#121212 or #1A1A1A (Near Black):
|
||||
├── Still good battery savings
|
||||
├── Smoother scrolling (no smear)
|
||||
├── Slightly softer on eyes
|
||||
└── Material Design recommendation
|
||||
|
||||
RECOMMENDATION: #000000 for backgrounds, #0D0D0D-#1A1A1A for surfaces
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Dark Mode Design
|
||||
|
||||
### Dark Mode Benefits
|
||||
|
||||
```
|
||||
Users enable dark mode for:
|
||||
├── Battery savings (OLED)
|
||||
├── Reduced eye strain (low light)
|
||||
├── Personal preference
|
||||
├── AMOLED aesthetic
|
||||
└── Accessibility (light sensitivity)
|
||||
```
|
||||
|
||||
### Dark Mode Color Strategy
|
||||
|
||||
```
|
||||
LIGHT MODE DARK MODE
|
||||
────────── ─────────
|
||||
Background: #FFFFFF → #000000 or #121212
|
||||
Surface: #F5F5F5 → #1E1E1E
|
||||
Surface 2: #EEEEEE → #2C2C2C
|
||||
|
||||
Primary: #1976D2 → #90CAF9 (lighter)
|
||||
Text: #212121 → #E0E0E0 (not pure white)
|
||||
Secondary: #757575 → #9E9E9E
|
||||
|
||||
Elevation in dark mode:
|
||||
├── Higher = slightly lighter surface
|
||||
├── 0dp → 0% overlay
|
||||
├── 4dp → 9% overlay
|
||||
├── 8dp → 12% overlay
|
||||
└── Creates depth without shadows
|
||||
```
|
||||
|
||||
### Text Colors in Dark Mode
|
||||
|
||||
| Role | Light Mode | Dark Mode |
|
||||
|------|------------|-----------|
|
||||
| Primary | #000000 (Black) | #E8E8E8 (Not pure white) |
|
||||
| Secondary | #666666 | #B0B0B0 |
|
||||
| Disabled | #9E9E9E | #6E6E6E |
|
||||
| Links | #1976D2 | #8AB4F8 |
|
||||
|
||||
### Color Inversion Rules
|
||||
|
||||
```
|
||||
DON'T just invert colors:
|
||||
├── Saturated colors become eye-burning
|
||||
├── Semantic colors lose meaning
|
||||
├── Brand colors may break
|
||||
└── Contrast ratios change unpredictably
|
||||
|
||||
DO create intentional dark palette:
|
||||
├── Desaturate primary colors
|
||||
├── Use lighter tints for emphasis
|
||||
├── Maintain semantic color meanings
|
||||
├── Check contrast ratios independently
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Outdoor Visibility
|
||||
|
||||
### The Sunlight Problem
|
||||
|
||||
```
|
||||
Screen visibility outdoors:
|
||||
├── Bright sun washes out low contrast
|
||||
├── Glare reduces readability
|
||||
├── Polarized sunglasses affect
|
||||
└── Users shield screen with hand
|
||||
|
||||
Affected elements:
|
||||
├── Light gray text on white
|
||||
├── Subtle color differences
|
||||
├── Low opacity overlays
|
||||
└── Pastel colors
|
||||
```
|
||||
|
||||
### High Contrast Strategies
|
||||
|
||||
```
|
||||
For outdoor visibility:
|
||||
|
||||
MINIMUM CONTRAST RATIOS:
|
||||
├── Normal text: 4.5:1 (WCAG AA)
|
||||
├── Large text: 3:1 (WCAG AA)
|
||||
├── Recommended: 7:1+ (AAA)
|
||||
|
||||
AVOID:
|
||||
├── #999 on #FFF (fails AA)
|
||||
├── #BBB on #FFF (fails)
|
||||
├── Pale colors on light backgrounds
|
||||
└── Subtle gradients for critical info
|
||||
|
||||
DO:
|
||||
├── Use system semantic colors
|
||||
├── Test in bright environment
|
||||
├── Provide high contrast mode
|
||||
└── Use solid colors for critical UI
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Semantic Colors
|
||||
|
||||
### Consistent Meaning
|
||||
|
||||
| Semantic | Meaning | iOS Default | Android Default |
|
||||
|----------|---------|-------------|-----------------|
|
||||
| Error | Problems, destruction | #FF3B30 | #B3261E |
|
||||
| Success | Completion, positive | #34C759 | #4CAF50 |
|
||||
| Warning | Attention, caution | #FF9500 | #FFC107 |
|
||||
| Info | Information | #007AFF | #2196F3 |
|
||||
|
||||
### Semantic Color Rules
|
||||
|
||||
```
|
||||
NEVER use semantic colors for:
|
||||
├── Branding (confuses meaning)
|
||||
├── Decoration (reduces impact)
|
||||
├── Arbitrary styling
|
||||
└── Status indicators (use icons too)
|
||||
|
||||
ALWAYS:
|
||||
├── Pair with icons (colorblind users)
|
||||
├── Maintain across light/dark modes
|
||||
├── Keep consistent throughout app
|
||||
└── Follow platform conventions
|
||||
```
|
||||
|
||||
### Error State Colors
|
||||
|
||||
```
|
||||
Error states need:
|
||||
├── Red-ish color (semantic)
|
||||
├── High contrast against background
|
||||
├── Icon reinforcement
|
||||
├── Clear text explanation
|
||||
|
||||
iOS:
|
||||
├── Light: #FF3B30
|
||||
├── Dark: #FF453A
|
||||
|
||||
Android:
|
||||
├── Light: #B3261E
|
||||
├── Dark: #F2B8B5 (on error container)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Dynamic Color (Android)
|
||||
|
||||
### Material You
|
||||
|
||||
```
|
||||
Android 12+ Dynamic Color:
|
||||
|
||||
User's wallpaper → Color extraction → App theme
|
||||
|
||||
Your app automatically gets:
|
||||
├── Primary (from wallpaper dominant)
|
||||
├── Secondary (complementary)
|
||||
├── Tertiary (accent)
|
||||
├── Surface colors (neutral, derived)
|
||||
├── On-colors (text on each)
|
||||
```
|
||||
|
||||
### Supporting Dynamic Color
|
||||
|
||||
```kotlin
|
||||
// Jetpack Compose
|
||||
MaterialTheme(
|
||||
colorScheme = dynamicColorScheme()
|
||||
?: staticColorScheme() // Fallback for older Android
|
||||
)
|
||||
|
||||
// React Native
|
||||
// Limited support - consider react-native-material-you
|
||||
```
|
||||
|
||||
### Fallback Colors
|
||||
|
||||
```
|
||||
When dynamic color unavailable:
|
||||
├── Android < 12
|
||||
├── User disabled
|
||||
├── Non-supporting launchers
|
||||
|
||||
Provide static color scheme:
|
||||
├── Define your brand colors
|
||||
├── Test in both modes
|
||||
├── Match dynamic color roles
|
||||
└── Support light + dark
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Color Accessibility
|
||||
|
||||
### Colorblind Considerations
|
||||
|
||||
```
|
||||
~8% of men, ~0.5% of women are colorblind
|
||||
|
||||
Types:
|
||||
├── Protanopia (red weakness)
|
||||
├── Deuteranopia (green weakness)
|
||||
├── Tritanopia (blue weakness)
|
||||
├── Monochromacy (rare, no color)
|
||||
|
||||
Design rules:
|
||||
├── Never rely on color alone
|
||||
├── Use patterns, icons, text
|
||||
├── Test with simulation tools
|
||||
├── Avoid red/green distinctions only
|
||||
```
|
||||
|
||||
### Contrast Testing Tools
|
||||
|
||||
```
|
||||
Use these to verify:
|
||||
├── Built-in accessibility inspector (Xcode)
|
||||
├── Accessibility Scanner (Android)
|
||||
├── Contrast ratio calculators
|
||||
├── Colorblind simulation
|
||||
└── Test on actual devices in sunlight
|
||||
```
|
||||
|
||||
### Sufficient Contrast
|
||||
|
||||
```
|
||||
WCAG Guidelines:
|
||||
|
||||
AA (Minimum)
|
||||
├── Normal text: 4.5:1
|
||||
├── Large text (18pt+): 3:1
|
||||
├── UI components: 3:1
|
||||
|
||||
AAA (Enhanced)
|
||||
├── Normal text: 7:1
|
||||
├── Large text: 4.5:1
|
||||
|
||||
Mobile recommendation: Meet AA, aim for AAA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Color Anti-Patterns
|
||||
|
||||
### ❌ Common Mistakes
|
||||
|
||||
| Mistake | Problem | Fix |
|
||||
|---------|---------|-----|
|
||||
| **Light gray on white** | Invisible outdoors | Min 4.5:1 contrast |
|
||||
| **Pure white in dark mode** | Eye strain | Use #E0E0E0-#F0F0F0 |
|
||||
| **Same saturation dark mode** | Garish, glowing | Desaturate colors |
|
||||
| **Red/green only indicator** | Colorblind users can't see | Add icons |
|
||||
| **Semantic colors for brand** | Confusing meaning | Use neutral for brand |
|
||||
| **Ignoring system dark mode** | Jarring experience | Support both modes |
|
||||
|
||||
### ❌ AI Color Mistakes
|
||||
|
||||
```
|
||||
AI tends to:
|
||||
├── Use same colors for light/dark
|
||||
├── Ignore OLED battery implications
|
||||
├── Skip contrast calculations
|
||||
├── Default to purple/violet (BANNED)
|
||||
├── Use low contrast "aesthetic" grays
|
||||
├── Not test in outdoor conditions
|
||||
└── Forget colorblind users
|
||||
|
||||
RULE: Design for the worst case.
|
||||
Test in bright sunlight, with colorblindness simulation.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Color System Checklist
|
||||
|
||||
### Before Choosing Colors
|
||||
|
||||
- [ ] Light and dark mode variants defined?
|
||||
- [ ] Contrast ratios checked (4.5:1+)?
|
||||
- [ ] OLED battery considered (dark mode)?
|
||||
- [ ] Semantic colors follow conventions?
|
||||
- [ ] Colorblind-safe (not color-only indicators)?
|
||||
|
||||
### Before Release
|
||||
|
||||
- [ ] Tested in bright sunlight?
|
||||
- [ ] Tested dark mode on OLED device?
|
||||
- [ ] System dark mode respected?
|
||||
- [ ] Dynamic color supported (Android)?
|
||||
- [ ] Error/success/warning consistent?
|
||||
- [ ] All text meets contrast requirements?
|
||||
|
||||
---
|
||||
|
||||
## 10. Quick Reference
|
||||
|
||||
### Dark Mode Backgrounds
|
||||
|
||||
```
|
||||
True black (OLED max savings): #000000
|
||||
Near black (Material): #121212
|
||||
Surface 1: #1E1E1E
|
||||
Surface 2: #2C2C2C
|
||||
Surface 3: #3C3C3C
|
||||
```
|
||||
|
||||
### Text on Dark
|
||||
|
||||
```
|
||||
Primary: #E0E0E0 to #ECECEC
|
||||
Secondary: #A0A0A0 to #B0B0B0
|
||||
Disabled: #606060 to #707070
|
||||
```
|
||||
|
||||
### Contrast Ratios
|
||||
|
||||
```
|
||||
Small text: 4.5:1 (minimum)
|
||||
Large text: 3:1 (minimum)
|
||||
UI elements: 3:1 (minimum)
|
||||
Ideal: 7:1 (AAA)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Color on mobile must work in the worst conditions—bright sun, tired eyes, colorblindness, low battery. Pretty colors that fail these tests are useless colors.
|
||||
122
skills/mobile-design/mobile-debugging.md
Normal file
122
skills/mobile-design/mobile-debugging.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Mobile Debugging Guide
|
||||
|
||||
> **Stop console.log() debugging!**
|
||||
> Mobile apps have complex native layers. Text logs are not enough.
|
||||
> **This file teaches effective mobile debugging strategies.**
|
||||
|
||||
---
|
||||
|
||||
## 🧠 MOBILE DEBUGGING MINDSET
|
||||
|
||||
```
|
||||
Web Debugging: Mobile Debugging:
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ Browser │ │ JS Bridge │
|
||||
│ DevTools │ │ Native UI │
|
||||
│ Network Tab │ │ GPU/Memory │
|
||||
└──────────────┘ │ Threads │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
**Key Differences:**
|
||||
1. **Native Layer:** JS code works, but app crashes? It's likely native (Java/Obj-C).
|
||||
2. **Deployment:** You can't just "refresh". State gets lost or stuck.
|
||||
3. **Network:** SSL Pinning, proxy settings are harder.
|
||||
4. **Device Logs:** `adb logcat` and `Console.app` are your truth.
|
||||
|
||||
---
|
||||
|
||||
## 🚫 AI DEBUGGING ANTI-PATTERNS
|
||||
|
||||
| ❌ Default | ✅ Mobile-Correct |
|
||||
|------------|-------------------|
|
||||
| "Add console.logs" | Use Flipper / Reactotron |
|
||||
| "Check network tab" | Use Charles Proxy / Proxyman |
|
||||
| "It works on simulator" | **Test on Real Device** (HW specific bugs) |
|
||||
| "Reinstall node_modules" | **Clean Native Build** (Gradle/Pod cache) |
|
||||
| Ignored native logs | Read `logcat` / Xcode logs |
|
||||
|
||||
---
|
||||
|
||||
## 1. The Toolset
|
||||
|
||||
### ⚡ React Native & Expo
|
||||
|
||||
| Tool | Purpose | Best For |
|
||||
|------|---------|----------|
|
||||
| **Reactotron** | State/API/Redux | JS side debugging |
|
||||
| **Flipper** | Layout/Network/db | Native + JS bridge |
|
||||
| **Expo Tools** | Element inspector | Quick UI checks |
|
||||
|
||||
### 🛠️ Native Layer (The Deep Dive)
|
||||
|
||||
| Tool | Platform | Command | Why Use? |
|
||||
|------|----------|---------|----------|
|
||||
| **Logcat** | Android | `adb logcat` | Native crashes, ANRs |
|
||||
| **Console** | iOS | via Xcode | Native exceptions, memory |
|
||||
| **Layout Insp.** | Android | Android Studio | UI hierarchy bugs |
|
||||
| **View Insp.** | iOS | Xcode | UI hierarchy bugs |
|
||||
|
||||
---
|
||||
|
||||
## 2. Common Debugging Workflows
|
||||
|
||||
### 🕵️ "The App Just Crashed" (Red Screen vs Crash to Home)
|
||||
|
||||
**Scenario A: Red Screen (JS Error)**
|
||||
- **Cause:** Undefined is not an object, import error.
|
||||
- **Fix:** Read the stack trace on screen. It's usually clear.
|
||||
|
||||
**Scenario B: Crash to Home Screen (Native Crash)**
|
||||
- **Cause:** Native module failure, memory OOM, permission usage without declaration.
|
||||
- **Tools:**
|
||||
- **Android:** `adb logcat *:E` (Filter for Errors)
|
||||
- **iOS:** Open Xcode → Window → Devices → View Device Logs
|
||||
|
||||
> **💡 Pro Tip:** If app crashes immediately on launch, it's almost 100% a native configuration issue (Info.plist, AndroidManifest.xml).
|
||||
|
||||
### 🌐 "API Request Failed" (Network)
|
||||
|
||||
**Web:** Open Chrome DevTools → Network.
|
||||
**Mobile:** *You usually can't see this easily.*
|
||||
|
||||
**Solution 1: Reactotron/Flipper**
|
||||
- View network requests in the monitoring app.
|
||||
|
||||
**Solution 2: Proxy (Charles/Proxyman)**
|
||||
- **Hard but powerful.** See ALL traffic even from native SDKs.
|
||||
- Requires installing SSL cert on device.
|
||||
|
||||
### 🐢 "The UI is Laggy" (Performance)
|
||||
|
||||
**Don't guess.** measure.
|
||||
- **React Native:** Performance Monitor (Shake menu).
|
||||
- **Android:** "Profile GPU Rendering" in Developer Options.
|
||||
- **Issues:**
|
||||
- **JS FPS drop:** Heavy calculation in JS thread.
|
||||
- **UI FPS drop:** Too many views, intricate hierarchy, heavy images.
|
||||
|
||||
---
|
||||
|
||||
## 3. Platform-Specific Nightmares
|
||||
|
||||
### Android
|
||||
- **Gradle Sync Fail:** Usually Java version mismatch or duplicate classes.
|
||||
- **Emulator Network:** Emulator `localhost` is `10.0.2.2`, NOT `127.0.0.1`.
|
||||
- **Cached Builds:** `./gradlew clean` is your best friend.
|
||||
|
||||
### iOS
|
||||
- **Pod Issues:** `pod deintegrate && pod install`.
|
||||
- **Signing Errors:** Check Team ID and Bundle Identifier.
|
||||
- **Cache:** Xcode → Product → Clean Build Folder.
|
||||
|
||||
---
|
||||
|
||||
## 📝 DEBUGGING CHECKLIST
|
||||
|
||||
- [ ] **Is it a JS or Native crash?** (Red screen or home screen?)
|
||||
- [ ] **Did you clean build?** (Native caches are aggressive)
|
||||
- [ ] **Are you on a real device?** (Simulators hide concurrency bugs)
|
||||
- [ ] **Did you check the native logs?** (Not just terminal output)
|
||||
|
||||
> **Remember:** If JavaScript looks perfect but the app fails, look closer at the Native side.
|
||||
357
skills/mobile-design/mobile-design-thinking.md
Normal file
357
skills/mobile-design/mobile-design-thinking.md
Normal file
@@ -0,0 +1,357 @@
|
||||
# Mobile Design Thinking
|
||||
|
||||
> **This file prevents AI from using memorized patterns and forces genuine thinking.**
|
||||
> Mechanisms to prevent standard AI training defaults in mobile development.
|
||||
> **The mobile equivalent of frontend's layout decomposition approach.**
|
||||
|
||||
---
|
||||
|
||||
## 🧠 DEEP MOBILE THINKING PROTOCOL
|
||||
|
||||
### This Process is Mandatory Before Every Mobile Project
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DEEP MOBILE THINKING │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1️⃣ CONTEXT SCAN │
|
||||
│ └── What are my assumptions for this project? │
|
||||
│ └── QUESTION these assumptions │
|
||||
│ │
|
||||
│ 2️⃣ ANTI-DEFAULT ANALYSIS │
|
||||
│ └── Am I applying a memorized pattern? │
|
||||
│ └── Is this pattern REALLY the best for THIS project? │
|
||||
│ │
|
||||
│ 3️⃣ PLATFORM DECOMPOSITION │
|
||||
│ └── Did I think about iOS and Android separately? │
|
||||
│ └── What are the platform-specific patterns? │
|
||||
│ │
|
||||
│ 4️⃣ TOUCH INTERACTION BREAKDOWN │
|
||||
│ └── Did I analyze each interaction individually? │
|
||||
│ └── Did I apply Fitts' Law, Thumb Zone? │
|
||||
│ │
|
||||
│ 5️⃣ PERFORMANCE IMPACT ANALYSIS │
|
||||
│ └── Did I consider performance impact of each component? │
|
||||
│ └── Is the default solution performant? │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚫 AI MOBILE DEFAULTS (FORBIDDEN LIST)
|
||||
|
||||
### Using These Patterns Automatically is FORBIDDEN!
|
||||
|
||||
The following patterns are "defaults" that AIs learned from training data.
|
||||
Before using any of these, **QUESTION them and CONSIDER ALTERNATIVES!**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 🚫 AI MOBILE SAFE HARBOR │
|
||||
│ (Default Patterns - Never Use Without Questioning) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ NAVIGATION DEFAULTS: │
|
||||
│ ├── Tab bar for every project (Would drawer be better?) │
|
||||
│ ├── Fixed 5 tabs (Are 3 enough? For 6+, drawer?) │
|
||||
│ ├── "Home" tab on left (What does user behavior say?) │
|
||||
│ └── Hamburger menu (Is it outdated now?) │
|
||||
│ │
|
||||
│ STATE MANAGEMENT DEFAULTS: │
|
||||
│ ├── Redux everywhere (Is Zustand/Jotai sufficient?) │
|
||||
│ ├── Global state for everything (Isn't local state enough?) │
|
||||
│ ├── Context Provider hell (Is atom-based better?) │
|
||||
│ └── BLoC for every Flutter project (Is Riverpod more modern?) │
|
||||
│ │
|
||||
│ LIST IMPLEMENTATION DEFAULTS: │
|
||||
│ ├── FlatList as default (Is FlashList more performant?) │
|
||||
│ ├── windowSize=21 (Is it really needed?) │
|
||||
│ ├── removeClippedSubviews (Always?) │
|
||||
│ └── ListView.builder (Is ListView.separated better?) │
|
||||
│ │
|
||||
│ UI PATTERN DEFAULTS: │
|
||||
│ ├── FAB bottom-right (Is bottom-left more accessible?) │
|
||||
│ ├── Pull-to-refresh on every list (Is it needed everywhere?) │
|
||||
│ ├── Swipe-to-delete from left (Is right better?) │
|
||||
│ └── Bottom sheet for every modal (Is full screen better?) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 COMPONENT DECOMPOSITION (MANDATORY)
|
||||
|
||||
### Decomposition Analysis for Every Screen
|
||||
|
||||
Before designing any screen, perform this analysis:
|
||||
|
||||
```
|
||||
SCREEN: [Screen Name]
|
||||
├── PRIMARY ACTION: [What is the main action?]
|
||||
│ └── Is it in thumb zone? [Yes/No → Why?]
|
||||
│
|
||||
├── TOUCH TARGETS: [All tappable elements]
|
||||
│ ├── [Element 1]: [Size]pt → Sufficient?
|
||||
│ ├── [Element 2]: [Size]pt → Sufficient?
|
||||
│ └── Spacing: [Gap]pt → Accidental tap risk?
|
||||
│
|
||||
├── SCROLLABLE CONTENT:
|
||||
│ ├── Is it a list? → FlatList/FlashList [Why this choice?]
|
||||
│ ├── Item count: ~[N] → Performance consideration?
|
||||
│ └── Fixed height? → Is getItemLayout needed?
|
||||
│
|
||||
├── STATE REQUIREMENTS:
|
||||
│ ├── Is local state sufficient?
|
||||
│ ├── Do I need to lift state?
|
||||
│ └── Is global required? [Why?]
|
||||
│
|
||||
├── PLATFORM DIFFERENCES:
|
||||
│ ├── iOS: [Anything different needed?]
|
||||
│ └── Android: [Anything different needed?]
|
||||
│
|
||||
├── OFFLINE CONSIDERATION:
|
||||
│ ├── Should this screen work offline?
|
||||
│ └── Cache strategy: [Yes/No/Which one?]
|
||||
│
|
||||
└── PERFORMANCE IMPACT:
|
||||
├── Any heavy components?
|
||||
├── Is memoization needed?
|
||||
└── Animation performance?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 PATTERN QUESTIONING MATRIX
|
||||
|
||||
Ask these questions for every default pattern:
|
||||
|
||||
### Navigation Pattern Questioning
|
||||
|
||||
| Assumption | Question | Alternative |
|
||||
|------------|----------|-------------|
|
||||
| "I'll use tab bar" | How many destinations? | 3 → minimal tabs, 6+ → drawer |
|
||||
| "5 tabs" | Are all equally important? | "More" tab? Drawer hybrid? |
|
||||
| "Bottom nav" | iPad/tablet support? | Navigation rail alternative |
|
||||
| "Stack navigation" | Did I consider deep links? | URL structure = navigation structure |
|
||||
|
||||
### State Pattern Questioning
|
||||
|
||||
| Assumption | Question | Alternative |
|
||||
|------------|----------|-------------|
|
||||
| "I'll use Redux" | How complex is the app? | Simple: Zustand, Server: TanStack |
|
||||
| "Global state" | Is this state really global? | Local lift, Context selector |
|
||||
| "Context Provider" | Will re-render be an issue? | Zustand, Jotai (atom-based) |
|
||||
| "BLoC pattern" | Is the boilerplate worth it? | Riverpod (less code) |
|
||||
|
||||
### List Pattern Questioning
|
||||
|
||||
| Assumption | Question | Alternative |
|
||||
|------------|----------|-------------|
|
||||
| "FlatList" | Is performance critical? | FlashList (faster) |
|
||||
| "Standard renderItem" | Is it memoized? | useCallback + React.memo |
|
||||
| "Index key" | Does data order change? | Use item.id |
|
||||
| "ListView" | Are there separators? | ListView.separated |
|
||||
|
||||
### UI Pattern Questioning
|
||||
|
||||
| Assumption | Question | Alternative |
|
||||
|------------|----------|-------------|
|
||||
| "FAB bottom-right" | User handedness? | Accessibility settings |
|
||||
| "Pull-to-refresh" | Does this list need refresh? | Only when necessary |
|
||||
| "Modal bottom sheet" | How much content? | Full screen modal might be better |
|
||||
| "Swipe actions" | Discoverability? | Visible button alternative |
|
||||
|
||||
---
|
||||
|
||||
## 🧪 ANTI-MEMORIZATION TEST
|
||||
|
||||
### Ask Yourself Before Every Solution
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ANTI-MEMORIZATION CHECKLIST │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ □ Did I pick this solution "because I always do it this way"? │
|
||||
│ → If YES: STOP. Consider alternatives. │
|
||||
│ │
|
||||
│ □ Is this a pattern I've seen frequently in training data? │
|
||||
│ → If YES: Is it REALLY suitable for THIS project? │
|
||||
│ │
|
||||
│ □ Did I write this solution automatically without thinking? │
|
||||
│ → If YES: Step back, do decomposition. │
|
||||
│ │
|
||||
│ □ Did I consider an alternative approach? │
|
||||
│ → If NO: Think of at least 2 alternatives, then decide. │
|
||||
│ │
|
||||
│ □ Did I think platform-specifically? │
|
||||
│ → If NO: Analyze iOS and Android separately. │
|
||||
│ │
|
||||
│ □ Did I consider performance impact of this solution? │
|
||||
│ → If NO: What is the memory, CPU, battery impact? │
|
||||
│ │
|
||||
│ □ Is this solution suitable for THIS project's CONTEXT? │
|
||||
│ → If NO: Customize based on context. │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 CONTEXT-BASED DECISION PROTOCOL
|
||||
|
||||
### Think Differently Based on Project Type
|
||||
|
||||
```
|
||||
DETERMINE PROJECT TYPE:
|
||||
│
|
||||
├── E-Commerce App
|
||||
│ ├── Navigation: Tab (Home, Search, Cart, Account)
|
||||
│ ├── Lists: Product grids (memoized, image optimized)
|
||||
│ ├── Performance: Image caching CRITICAL
|
||||
│ ├── Offline: Cart persistence, product cache
|
||||
│ └── Special: Checkout flow, payment security
|
||||
│
|
||||
├── Social/Content App
|
||||
│ ├── Navigation: Tab (Feed, Search, Create, Notify, Profile)
|
||||
│ ├── Lists: Infinite scroll, complex items
|
||||
│ ├── Performance: Feed rendering CRITICAL
|
||||
│ ├── Offline: Feed cache, draft posts
|
||||
│ └── Special: Real-time updates, media handling
|
||||
│
|
||||
├── Productivity/SaaS App
|
||||
│ ├── Navigation: Drawer or adaptive (mobile tab, tablet rail)
|
||||
│ ├── Lists: Data tables, forms
|
||||
│ ├── Performance: Data sync
|
||||
│ ├── Offline: Full offline editing
|
||||
│ └── Special: Conflict resolution, background sync
|
||||
│
|
||||
├── Utility App
|
||||
│ ├── Navigation: Minimal (stack-only possible)
|
||||
│ ├── Lists: Probably minimal
|
||||
│ ├── Performance: Fast startup
|
||||
│ ├── Offline: Core feature offline
|
||||
│ └── Special: Widget, shortcuts
|
||||
│
|
||||
└── Media/Streaming App
|
||||
├── Navigation: Tab (Home, Search, Library, Profile)
|
||||
├── Lists: Horizontal carousels, vertical feeds
|
||||
├── Performance: Preloading, buffering
|
||||
├── Offline: Download management
|
||||
└── Special: Background playback, casting
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 INTERACTION BREAKDOWN
|
||||
|
||||
### Analysis for Every Gesture
|
||||
|
||||
Before adding any gesture:
|
||||
|
||||
```
|
||||
GESTURE: [Gesture Type]
|
||||
├── DISCOVERABILITY:
|
||||
│ └── How will users discover this gesture?
|
||||
│ ├── Is there a visual hint?
|
||||
│ ├── Will it be shown in onboarding?
|
||||
│ └── Is there a button alternative? (MANDATORY)
|
||||
│
|
||||
├── PLATFORM CONVENTION:
|
||||
│ ├── What does this gesture mean on iOS?
|
||||
│ ├── What does this gesture mean on Android?
|
||||
│ └── Am I deviating from platform convention?
|
||||
│
|
||||
├── ACCESSIBILITY:
|
||||
│ ├── Can motor-impaired users perform this gesture?
|
||||
│ ├── Is there a VoiceOver/TalkBack alternative?
|
||||
│ └── Does it work with switch control?
|
||||
│
|
||||
├── CONFLICT CHECK:
|
||||
│ ├── Does it conflict with system gestures?
|
||||
│ │ ├── iOS: Edge swipe back
|
||||
│ │ ├── Android: Back gesture
|
||||
│ │ └── Home indicator swipe
|
||||
│ └── Is it consistent with other app gestures?
|
||||
│
|
||||
└── FEEDBACK:
|
||||
├── Is haptic feedback defined?
|
||||
├── Is visual feedback sufficient?
|
||||
└── Is audio feedback needed?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎭 SPIRIT OVER CHECKLIST (Mobile Edition)
|
||||
|
||||
### Passing the Checklist is Not Enough!
|
||||
|
||||
| ❌ Self-Deception | ✅ Honest Assessment |
|
||||
|-------------------|----------------------|
|
||||
| "Touch target is 44px" (but on edge, unreachable) | "Can user reach it one-handed?" |
|
||||
| "I used FlatList" (but didn't memoize) | "Is scroll smooth?" |
|
||||
| "Platform-specific nav" (but only icons differ) | "Does iOS feel like iOS, Android like Android?" |
|
||||
| "Offline support exists" (but error message is generic) | "What can user actually do offline?" |
|
||||
| "Loading state exists" (but just a spinner) | "Does user know how long to wait?" |
|
||||
|
||||
> 🔴 **Passing the checklist is NOT the goal. Creating great mobile UX IS the goal.**
|
||||
|
||||
---
|
||||
|
||||
## 📝 MOBILE DESIGN COMMITMENT
|
||||
|
||||
### Fill This at the Start of Every Mobile Project
|
||||
|
||||
```
|
||||
📱 MOBILE DESIGN COMMITMENT
|
||||
|
||||
Project: _______________
|
||||
Platform: iOS / Android / Both
|
||||
|
||||
1. Default pattern I will NOT use in this project:
|
||||
└── _______________
|
||||
|
||||
2. Context-specific focus for this project:
|
||||
└── _______________
|
||||
|
||||
3. Platform-specific differences I will implement:
|
||||
└── iOS: _______________
|
||||
└── Android: _______________
|
||||
|
||||
4. Area I will specifically optimize for performance:
|
||||
└── _______________
|
||||
|
||||
5. Unique challenge of this project:
|
||||
└── _______________
|
||||
|
||||
🧠 If I can't fill this commitment → I don't understand the project well enough.
|
||||
→ Go back, understand context better, ask the user.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚨 MANDATORY: Before Every Mobile Work
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PRE-WORK VALIDATION │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ □ Did I complete Component Decomposition? │
|
||||
│ □ Did I fill the Pattern Questioning Matrix? │
|
||||
│ □ Did I pass the Anti-Memorization Test? │
|
||||
│ □ Did I make context-based decisions? │
|
||||
│ □ Did I analyze Interaction Breakdown? │
|
||||
│ □ Did I fill the Mobile Design Commitment? │
|
||||
│ │
|
||||
│ ⚠️ Do not write code without completing these! │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** If you chose a solution "because that's how it's always done," you chose WITHOUT THINKING. Every project is unique. Every context is different. Every user behavior is specific. **THINK, then code.**
|
||||
458
skills/mobile-design/mobile-navigation.md
Normal file
458
skills/mobile-design/mobile-navigation.md
Normal file
@@ -0,0 +1,458 @@
|
||||
# Mobile Navigation Reference
|
||||
|
||||
> Navigation patterns, deep linking, back handling, and tab/stack/drawer decisions.
|
||||
> **Navigation is the skeleton of your app—get it wrong and everything feels broken.**
|
||||
|
||||
---
|
||||
|
||||
## 1. Navigation Selection Decision Tree
|
||||
|
||||
```
|
||||
WHAT TYPE OF APP?
|
||||
│
|
||||
├── 3-5 top-level sections (equal importance)
|
||||
│ └── ✅ Tab Bar / Bottom Navigation
|
||||
│ Examples: Social, E-commerce, Utility
|
||||
│
|
||||
├── Deep hierarchical content (drill down)
|
||||
│ └── ✅ Stack Navigation
|
||||
│ Examples: Settings, Email folders
|
||||
│
|
||||
├── Many destinations (>5 top-level)
|
||||
│ └── ✅ Drawer Navigation
|
||||
│ Examples: Gmail, complex enterprise
|
||||
│
|
||||
├── Single linear flow
|
||||
│ └── ✅ Stack only (wizard/onboarding)
|
||||
│ Examples: Checkout, Setup flow
|
||||
│
|
||||
└── Tablet/Foldable
|
||||
└── ✅ Navigation Rail + List-Detail
|
||||
Examples: Mail, Notes on iPad
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Tab Bar Navigation
|
||||
|
||||
### When to Use
|
||||
|
||||
```
|
||||
✅ USE Tab Bar when:
|
||||
├── 3-5 top-level destinations
|
||||
├── Destinations are of equal importance
|
||||
├── User frequently switches between them
|
||||
├── Each tab has independent navigation stack
|
||||
└── App is used in short sessions
|
||||
|
||||
❌ AVOID Tab Bar when:
|
||||
├── More than 5 destinations
|
||||
├── Destinations have clear hierarchy
|
||||
├── Tabs would be used very unequally
|
||||
└── Content flows in a sequence
|
||||
```
|
||||
|
||||
### Tab Bar Best Practices
|
||||
|
||||
```
|
||||
iOS Tab Bar:
|
||||
├── Height: 49pt (83pt with home indicator)
|
||||
├── Max items: 5
|
||||
├── Icons: SF Symbols, 25×25pt
|
||||
├── Labels: Always show (accessibility)
|
||||
├── Active indicator: Tint color
|
||||
|
||||
Android Bottom Navigation:
|
||||
├── Height: 80dp
|
||||
├── Max items: 5 (3-5 ideal)
|
||||
├── Icons: Material Symbols, 24dp
|
||||
├── Labels: Always show
|
||||
├── Active indicator: Pill shape + filled icon
|
||||
```
|
||||
|
||||
### Tab State Preservation
|
||||
|
||||
```
|
||||
RULE: Each tab maintains its own navigation stack.
|
||||
|
||||
User journey:
|
||||
1. Home tab → Drill into item → Add to cart
|
||||
2. Switch to Profile tab
|
||||
3. Switch back to Home tab
|
||||
→ Should return to "Add to cart" screen, NOT home root
|
||||
|
||||
Implementation:
|
||||
├── React Navigation: Each tab has own navigator
|
||||
├── Flutter: IndexedStack for state preservation
|
||||
└── Never reset tab stack on switch
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Stack Navigation
|
||||
|
||||
### Core Concepts
|
||||
|
||||
```
|
||||
Stack metaphor: Cards stacked on top of each other
|
||||
|
||||
Push: Add screen on top
|
||||
Pop: Remove top screen (back)
|
||||
Replace: Swap current screen
|
||||
Reset: Clear stack, set new root
|
||||
|
||||
Visual: New screen slides in from right (LTR)
|
||||
Back: Screen slides out to right
|
||||
```
|
||||
|
||||
### Stack Navigation Patterns
|
||||
|
||||
| Pattern | Use Case | Implementation |
|
||||
|---------|----------|----------------|
|
||||
| **Simple Stack** | Linear flow | Push each step |
|
||||
| **Nested Stack** | Sections with sub-navigation | Stack inside tab |
|
||||
| **Modal Stack** | Focused tasks | Present modally |
|
||||
| **Auth Stack** | Login vs Main | Conditional root |
|
||||
|
||||
### Back Button Handling
|
||||
|
||||
```
|
||||
iOS:
|
||||
├── Edge swipe from left (system)
|
||||
├── Back button in nav bar (optional)
|
||||
├── Interactive pop gesture
|
||||
└── Never override swipe back without good reason
|
||||
|
||||
Android:
|
||||
├── System back button/gesture
|
||||
├── Up button in toolbar (optional, for drill-down)
|
||||
├── Predictive back animation (Android 14+)
|
||||
└── Must handle back correctly (Activity/Fragment)
|
||||
|
||||
Cross-Platform Rule:
|
||||
├── Back ALWAYS navigates up the stack
|
||||
├── Never hijack back for other purposes
|
||||
├── Confirm before discarding unsaved data
|
||||
└── Deep links should allow full back traversal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Drawer Navigation
|
||||
|
||||
### When to Use
|
||||
|
||||
```
|
||||
✅ USE Drawer when:
|
||||
├── More than 5 top-level destinations
|
||||
├── Less frequently accessed destinations
|
||||
├── Complex app with many features
|
||||
├── Need for branding/user info in nav
|
||||
└── Tablet/large screen with persistent drawer
|
||||
|
||||
❌ AVOID Drawer when:
|
||||
├── 5 or fewer destinations (use tabs)
|
||||
├── All destinations equally important
|
||||
├── Mobile-first simple app
|
||||
└── Discoverability is critical (drawer is hidden)
|
||||
```
|
||||
|
||||
### Drawer Patterns
|
||||
|
||||
```
|
||||
Modal Drawer:
|
||||
├── Opens over content (scrim behind)
|
||||
├── Swipe to open from edge
|
||||
├── Hamburger icon ( ☰ ) triggers
|
||||
└── Most common on mobile
|
||||
|
||||
Permanent Drawer:
|
||||
├── Always visible (large screens)
|
||||
├── Content shifts over
|
||||
├── Good for productivity apps
|
||||
└── Tablets, desktops
|
||||
|
||||
Navigation Rail (Android):
|
||||
├── Narrow vertical strip
|
||||
├── Icons + optional labels
|
||||
├── For tablets in portrait
|
||||
└── 80dp width
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Modal Navigation
|
||||
|
||||
### Modal vs Push
|
||||
|
||||
```
|
||||
PUSH (Stack): MODAL:
|
||||
├── Horizontal slide ├── Vertical slide up (sheet)
|
||||
├── Part of hierarchy ├── Separate task
|
||||
├── Back returns ├── Dismiss (X) returns
|
||||
├── Same navigation context ├── Own navigation context
|
||||
└── "Drill in" └── "Focus on task"
|
||||
|
||||
USE MODAL for:
|
||||
├── Creating new content
|
||||
├── Settings/preferences
|
||||
├── Completing a transaction
|
||||
├── Self-contained workflows
|
||||
├── Quick actions
|
||||
```
|
||||
|
||||
### Modal Types
|
||||
|
||||
| Type | iOS | Android | Use Case |
|
||||
|------|-----|---------|----------|
|
||||
| **Sheet** | `.sheet` | Bottom Sheet | Quick tasks |
|
||||
| **Full Screen** | `.fullScreenCover` | Full Activity | Complex forms |
|
||||
| **Alert** | Alert | Dialog | Confirmations |
|
||||
| **Action Sheet** | Action Sheet | Menu/Bottom Sheet | Choose from options |
|
||||
|
||||
### Modal Dismissal
|
||||
|
||||
```
|
||||
Users expect to dismiss modals by:
|
||||
├── Tapping X / Close button
|
||||
├── Swiping down (sheet)
|
||||
├── Tapping scrim (non-critical)
|
||||
├── System back (Android)
|
||||
├── Hardware back (old Android)
|
||||
|
||||
RULE: Only block dismissal for unsaved data.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Deep Linking
|
||||
|
||||
### Why Deep Links from Day One
|
||||
|
||||
```
|
||||
Deep links enable:
|
||||
├── Push notification navigation
|
||||
├── Sharing content
|
||||
├── Marketing campaigns
|
||||
├── Spotlight/Search integration
|
||||
├── Widget navigation
|
||||
├── External app integration
|
||||
|
||||
Building later is HARD:
|
||||
├── Requires navigation refactor
|
||||
├── Screen dependencies unclear
|
||||
├── Parameter passing complex
|
||||
└── Always plan deep links at start
|
||||
```
|
||||
|
||||
### URL Structure
|
||||
|
||||
```
|
||||
Scheme://host/path?params
|
||||
|
||||
Examples:
|
||||
├── myapp://product/123
|
||||
├── https://myapp.com/product/123 (Universal/App Link)
|
||||
├── myapp://checkout?promo=SAVE20
|
||||
├── myapp://tab/profile/settings
|
||||
|
||||
Hierarchy should match navigation:
|
||||
├── myapp://home
|
||||
├── myapp://home/product/123
|
||||
├── myapp://home/product/123/reviews
|
||||
└── URL path = navigation path
|
||||
```
|
||||
|
||||
### Deep Link Navigation Rules
|
||||
|
||||
```
|
||||
1. FULL STACK CONSTRUCTION
|
||||
Deep link to myapp://product/123 should:
|
||||
├── Put Home at root of stack
|
||||
├── Push Product screen on top
|
||||
└── Back button returns to Home
|
||||
|
||||
2. AUTHENTICATION AWARENESS
|
||||
If deep link requires auth:
|
||||
├── Save intended destination
|
||||
├── Redirect to login
|
||||
├── After login, navigate to destination
|
||||
|
||||
3. INVALID LINKS
|
||||
If deep link target doesn't exist:
|
||||
├── Navigate to fallback (home)
|
||||
├── Show error message
|
||||
└── Never crash or blank screen
|
||||
|
||||
4. STATEFUL NAVIGATION
|
||||
Deep link during active session:
|
||||
├── Don't blow away current stack
|
||||
├── Push on top OR
|
||||
├── Ask user if should navigate away
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Navigation State Persistence
|
||||
|
||||
### What to Persist
|
||||
|
||||
```
|
||||
SHOULD persist:
|
||||
├── Current tab selection
|
||||
├── Scroll position in lists
|
||||
├── Form draft data
|
||||
├── Recent navigation stack
|
||||
└── User preferences
|
||||
|
||||
SHOULD NOT persist:
|
||||
├── Modal states (dialogs)
|
||||
├── Temporary UI states
|
||||
├── Stale data (refresh on return)
|
||||
├── Authentication state (use secure storage)
|
||||
```
|
||||
|
||||
### Implementation
|
||||
|
||||
```javascript
|
||||
// React Navigation - State Persistence
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
const [initialState, setInitialState] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
const loadState = async () => {
|
||||
const savedState = await AsyncStorage.getItem('NAV_STATE');
|
||||
if (savedState) setInitialState(JSON.parse(savedState));
|
||||
setIsReady(true);
|
||||
};
|
||||
loadState();
|
||||
}, []);
|
||||
|
||||
const handleStateChange = (state) => {
|
||||
AsyncStorage.setItem('NAV_STATE', JSON.stringify(state));
|
||||
};
|
||||
|
||||
<NavigationContainer
|
||||
initialState={initialState}
|
||||
onStateChange={handleStateChange}
|
||||
>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Transition Animations
|
||||
|
||||
### Platform Defaults
|
||||
|
||||
```
|
||||
iOS Transitions:
|
||||
├── Push: Slide from right
|
||||
├── Modal: Slide from bottom (sheet) or fade
|
||||
├── Tab switch: Cross-fade
|
||||
├── Interactive: Swipe to go back
|
||||
|
||||
Android Transitions:
|
||||
├── Push: Fade + slide from right
|
||||
├── Modal: Slide from bottom
|
||||
├── Tab switch: Cross-fade or none
|
||||
├── Shared element: Hero animations
|
||||
```
|
||||
|
||||
### Custom Transitions
|
||||
|
||||
```
|
||||
When to custom:
|
||||
├── Brand identity requires it
|
||||
├── Shared element connections
|
||||
├── Special reveal effects
|
||||
└── Keep it subtle, <300ms
|
||||
|
||||
When to use default:
|
||||
├── Most of the time
|
||||
├── Standard drill-down
|
||||
├── Platform consistency
|
||||
└── Performance critical paths
|
||||
```
|
||||
|
||||
### Shared Element Transitions
|
||||
|
||||
```
|
||||
Connect elements between screens:
|
||||
|
||||
Screen A: Product card with image
|
||||
↓ (tap)
|
||||
Screen B: Product detail with same image (expanded)
|
||||
|
||||
Image animates from card position to detail position.
|
||||
|
||||
Implementation:
|
||||
├── React Navigation: shared element library
|
||||
├── Flutter: Hero widget
|
||||
├── SwiftUI: matchedGeometryEffect
|
||||
└── Compose: Shared element transitions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Navigation Anti-Patterns
|
||||
|
||||
### ❌ Navigation Sins
|
||||
|
||||
| Anti-Pattern | Problem | Solution |
|
||||
|--------------|---------|----------|
|
||||
| **Inconsistent back** | User confused, can't predict | Always pop stack |
|
||||
| **Hidden navigation** | Features undiscoverable | Visible tabs/drawer trigger |
|
||||
| **Deep nesting** | User gets lost | Max 3-4 levels, breadcrumbs |
|
||||
| **Breaking swipe back** | iOS users frustrated | Never override gesture |
|
||||
| **No deep links** | Can't share, bad notifications | Plan from start |
|
||||
| **Tab stack reset** | Work lost on switch | Preserve tab states |
|
||||
| **Modal for primary flow** | Can't back track | Use stack navigation |
|
||||
|
||||
### ❌ AI Navigation Mistakes
|
||||
|
||||
```
|
||||
AI tends to:
|
||||
├── Use modals for everything (wrong)
|
||||
├── Forget tab state preservation (wrong)
|
||||
├── Skip deep linking (wrong)
|
||||
├── Override platform back behavior (wrong)
|
||||
├── Reset stack on tab switch (wrong)
|
||||
└── Ignore predictive back (Android 14+)
|
||||
|
||||
RULE: Use platform navigation patterns.
|
||||
Don't reinvent navigation.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Navigation Checklist
|
||||
|
||||
### Before Navigation Architecture
|
||||
|
||||
- [ ] App type determined (tabs/drawer/stack)
|
||||
- [ ] Number of top-level destinations counted
|
||||
- [ ] Deep link URL scheme planned
|
||||
- [ ] Auth flow integrated with navigation
|
||||
- [ ] Tablet/large screen considered
|
||||
|
||||
### Before Every Screen
|
||||
|
||||
- [ ] Can user navigate back? (not dead end)
|
||||
- [ ] Deep link to this screen planned
|
||||
- [ ] State preserved on navigate away/back
|
||||
- [ ] Transition appropriate for relationship
|
||||
- [ ] Auth required? Handled?
|
||||
|
||||
### Before Release
|
||||
|
||||
- [ ] All deep links tested
|
||||
- [ ] Back button works everywhere
|
||||
- [ ] Tab states preserved correctly
|
||||
- [ ] Edge swipe back works (iOS)
|
||||
- [ ] Predictive back works (Android 14+)
|
||||
- [ ] Universal/App links configured
|
||||
- [ ] Push notification deep links work
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Navigation is invisible when done right. Users shouldn't think about HOW to get somewhere—they just get there. If they notice navigation, something is wrong.
|
||||
767
skills/mobile-design/mobile-performance.md
Normal file
767
skills/mobile-design/mobile-performance.md
Normal file
@@ -0,0 +1,767 @@
|
||||
# Mobile Performance Reference
|
||||
|
||||
> Deep dive into React Native and Flutter performance optimization, 60fps animations, memory management, and battery considerations.
|
||||
> **This file covers the #1 area where AI-generated code FAILS.**
|
||||
|
||||
---
|
||||
|
||||
## 1. The Mobile Performance Mindset
|
||||
|
||||
### Why Mobile Performance is Different
|
||||
|
||||
```
|
||||
DESKTOP: MOBILE:
|
||||
├── Unlimited power ├── Battery matters
|
||||
├── Abundant RAM ├── RAM is shared, limited
|
||||
├── Stable network ├── Network is unreliable
|
||||
├── CPU always available ├── CPU throttles when hot
|
||||
└── User expects fast anyway └── User expects INSTANT
|
||||
```
|
||||
|
||||
### Performance Budget Concept
|
||||
|
||||
```
|
||||
Every frame must complete in:
|
||||
├── 60fps → 16.67ms per frame
|
||||
├── 120fps (ProMotion) → 8.33ms per frame
|
||||
|
||||
If your code takes longer:
|
||||
├── Frame drops → Janky scroll/animation
|
||||
├── User perceives as "slow" or "broken"
|
||||
└── They WILL uninstall your app
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. React Native Performance
|
||||
|
||||
### 🚫 The #1 AI Mistake: ScrollView for Lists
|
||||
|
||||
```javascript
|
||||
// ❌ NEVER DO THIS - AI's favorite mistake
|
||||
<ScrollView>
|
||||
{items.map(item => (
|
||||
<ItemComponent key={item.id} item={item} />
|
||||
))}
|
||||
</ScrollView>
|
||||
|
||||
// Why it's catastrophic:
|
||||
// ├── Renders ALL items immediately (1000 items = 1000 renders)
|
||||
// ├── Memory explodes
|
||||
// ├── Initial render takes seconds
|
||||
// └── Scroll becomes janky
|
||||
|
||||
// ✅ ALWAYS USE FlatList
|
||||
<FlatList
|
||||
data={items}
|
||||
renderItem={renderItem}
|
||||
keyExtractor={item => item.id}
|
||||
/>
|
||||
```
|
||||
|
||||
### FlatList Optimization Checklist
|
||||
|
||||
```javascript
|
||||
// ✅ CORRECT: All optimizations applied
|
||||
|
||||
// 1. Memoize the item component
|
||||
const ListItem = React.memo(({ item }: { item: Item }) => {
|
||||
return (
|
||||
<Pressable style={styles.item}>
|
||||
<Text>{item.title}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
});
|
||||
|
||||
// 2. Memoize renderItem with useCallback
|
||||
const renderItem = useCallback(
|
||||
({ item }: { item: Item }) => <ListItem item={item} />,
|
||||
[] // Empty deps = never recreated
|
||||
);
|
||||
|
||||
// 3. Stable keyExtractor (NEVER use index!)
|
||||
const keyExtractor = useCallback((item: Item) => item.id, []);
|
||||
|
||||
// 4. Provide getItemLayout for fixed-height items
|
||||
const getItemLayout = useCallback(
|
||||
(data: Item[] | null, index: number) => ({
|
||||
length: ITEM_HEIGHT, // Fixed height
|
||||
offset: ITEM_HEIGHT * index,
|
||||
index,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
// 5. Apply to FlatList
|
||||
<FlatList
|
||||
data={items}
|
||||
renderItem={renderItem}
|
||||
keyExtractor={keyExtractor}
|
||||
getItemLayout={getItemLayout}
|
||||
// Performance props
|
||||
removeClippedSubviews={true} // Android: detach off-screen
|
||||
maxToRenderPerBatch={10} // Items per batch
|
||||
windowSize={5} // Render window (5 = 2 screens each side)
|
||||
initialNumToRender={10} // Initial items
|
||||
updateCellsBatchingPeriod={50} // Batching delay
|
||||
/>
|
||||
```
|
||||
|
||||
### Why Each Optimization Matters
|
||||
|
||||
| Optimization | What It Prevents | Impact |
|
||||
|--------------|------------------|--------|
|
||||
| `React.memo` | Re-render on parent change | 🔴 Critical |
|
||||
| `useCallback renderItem` | New function every render | 🔴 Critical |
|
||||
| Stable `keyExtractor` | Wrong item recycling | 🔴 Critical |
|
||||
| `getItemLayout` | Async layout calculation | 🟡 High |
|
||||
| `removeClippedSubviews` | Memory from off-screen | 🟡 High |
|
||||
| `maxToRenderPerBatch` | Blocking main thread | 🟢 Medium |
|
||||
| `windowSize` | Memory usage | 🟢 Medium |
|
||||
|
||||
### FlashList: The Better Option
|
||||
|
||||
```javascript
|
||||
// Consider FlashList for better performance
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
|
||||
<FlashList
|
||||
data={items}
|
||||
renderItem={renderItem}
|
||||
estimatedItemSize={ITEM_HEIGHT}
|
||||
keyExtractor={keyExtractor}
|
||||
/>
|
||||
|
||||
// Benefits over FlatList:
|
||||
// ├── Faster recycling
|
||||
// ├── Better memory management
|
||||
// ├── Simpler API
|
||||
// └── Fewer optimization props needed
|
||||
```
|
||||
|
||||
### Animation Performance
|
||||
|
||||
```javascript
|
||||
// ❌ JS-driven animation (blocks JS thread)
|
||||
Animated.timing(value, {
|
||||
toValue: 1,
|
||||
duration: 300,
|
||||
useNativeDriver: false, // BAD!
|
||||
}).start();
|
||||
|
||||
// ✅ Native-driver animation (runs on UI thread)
|
||||
Animated.timing(value, {
|
||||
toValue: 1,
|
||||
duration: 300,
|
||||
useNativeDriver: true, // GOOD!
|
||||
}).start();
|
||||
|
||||
// Native driver supports ONLY:
|
||||
// ├── transform (translate, scale, rotate)
|
||||
// └── opacity
|
||||
//
|
||||
// Does NOT support:
|
||||
// ├── width, height
|
||||
// ├── backgroundColor
|
||||
// ├── borderRadius changes
|
||||
// └── margin, padding
|
||||
```
|
||||
|
||||
### Reanimated for Complex Animations
|
||||
|
||||
```javascript
|
||||
// For animations native driver can't handle, use Reanimated 3
|
||||
|
||||
import Animated, {
|
||||
useSharedValue,
|
||||
useAnimatedStyle,
|
||||
withSpring,
|
||||
} from 'react-native-reanimated';
|
||||
|
||||
const Component = () => {
|
||||
const offset = useSharedValue(0);
|
||||
|
||||
const animatedStyles = useAnimatedStyle(() => ({
|
||||
transform: [{ translateX: withSpring(offset.value) }],
|
||||
}));
|
||||
|
||||
return <Animated.View style={animatedStyles} />;
|
||||
};
|
||||
|
||||
// Benefits:
|
||||
// ├── Runs on UI thread (60fps guaranteed)
|
||||
// ├── Can animate any property
|
||||
// ├── Gesture-driven animations
|
||||
// └── Worklets for complex logic
|
||||
```
|
||||
|
||||
### Memory Leak Prevention
|
||||
|
||||
```javascript
|
||||
// ❌ Memory leak: uncleared interval
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
fetchData();
|
||||
}, 5000);
|
||||
// Missing cleanup!
|
||||
}, []);
|
||||
|
||||
// ✅ Proper cleanup
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
fetchData();
|
||||
}, 5000);
|
||||
|
||||
return () => clearInterval(interval); // CLEANUP!
|
||||
}, []);
|
||||
|
||||
// Common memory leak sources:
|
||||
// ├── Timers (setInterval, setTimeout)
|
||||
// ├── Event listeners
|
||||
// ├── Subscriptions (WebSocket, PubSub)
|
||||
// ├── Async operations that update state after unmount
|
||||
// └── Image caching without limits
|
||||
```
|
||||
|
||||
### React Native Performance Checklist
|
||||
|
||||
```markdown
|
||||
## Before Every List
|
||||
- [ ] Using FlatList or FlashList (NOT ScrollView)
|
||||
- [ ] renderItem is useCallback memoized
|
||||
- [ ] List items are React.memo wrapped
|
||||
- [ ] keyExtractor uses stable ID (NOT index)
|
||||
- [ ] getItemLayout provided (if fixed height)
|
||||
|
||||
## Before Every Animation
|
||||
- [ ] useNativeDriver: true (if possible)
|
||||
- [ ] Using Reanimated for complex animations
|
||||
- [ ] Only animating transform/opacity
|
||||
- [ ] Tested on low-end Android device
|
||||
|
||||
## Before Any Release
|
||||
- [ ] console.log statements removed
|
||||
- [ ] Cleanup functions in all useEffects
|
||||
- [ ] No memory leaks (test with profiler)
|
||||
- [ ] Tested in release build (not dev)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Flutter Performance
|
||||
|
||||
### 🚫 The #1 AI Mistake: setState Overuse
|
||||
|
||||
```dart
|
||||
// ❌ WRONG: setState rebuilds ENTIRE widget tree
|
||||
class BadCounter extends StatefulWidget {
|
||||
@override
|
||||
State<BadCounter> createState() => _BadCounterState();
|
||||
}
|
||||
|
||||
class _BadCounterState extends State<BadCounter> {
|
||||
int _counter = 0;
|
||||
|
||||
void _increment() {
|
||||
setState(() {
|
||||
_counter++; // This rebuilds EVERYTHING below!
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Text('Counter: $_counter'),
|
||||
ExpensiveWidget(), // Rebuilds unnecessarily!
|
||||
AnotherExpensiveWidget(), // Rebuilds unnecessarily!
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### The `const` Constructor Revolution
|
||||
|
||||
```dart
|
||||
// ✅ CORRECT: const prevents rebuilds
|
||||
|
||||
class GoodCounter extends StatefulWidget {
|
||||
const GoodCounter({super.key}); // CONST constructor!
|
||||
|
||||
@override
|
||||
State<GoodCounter> createState() => _GoodCounterState();
|
||||
}
|
||||
|
||||
class _GoodCounterState extends State<GoodCounter> {
|
||||
int _counter = 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Text('Counter: $_counter'),
|
||||
const ExpensiveWidget(), // Won't rebuild!
|
||||
const AnotherExpensiveWidget(), // Won't rebuild!
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// RULE: Add `const` to EVERY widget that doesn't depend on state
|
||||
```
|
||||
|
||||
### Targeted State Management
|
||||
|
||||
```dart
|
||||
// ❌ setState rebuilds whole tree
|
||||
setState(() => _value = newValue);
|
||||
|
||||
// ✅ ValueListenableBuilder: surgical rebuilds
|
||||
class TargetedState extends StatelessWidget {
|
||||
final ValueNotifier<int> counter = ValueNotifier(0);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// Only this rebuilds when counter changes
|
||||
ValueListenableBuilder<int>(
|
||||
valueListenable: counter,
|
||||
builder: (context, value, child) => Text('$value'),
|
||||
child: const Icon(Icons.star), // Won't rebuild!
|
||||
),
|
||||
const ExpensiveWidget(), // Never rebuilds
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Riverpod/Provider Best Practices
|
||||
|
||||
```dart
|
||||
// ❌ WRONG: Reading entire provider in build
|
||||
Widget build(BuildContext context) {
|
||||
final state = ref.watch(myProvider); // Rebuilds on ANY change
|
||||
return Text(state.name);
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Select only what you need
|
||||
Widget build(BuildContext context) {
|
||||
final name = ref.watch(myProvider.select((s) => s.name));
|
||||
return Text(name); // Only rebuilds when name changes
|
||||
}
|
||||
```
|
||||
|
||||
### ListView Optimization
|
||||
|
||||
```dart
|
||||
// ❌ WRONG: ListView without builder (renders all)
|
||||
ListView(
|
||||
children: items.map((item) => ItemWidget(item)).toList(),
|
||||
)
|
||||
|
||||
// ✅ CORRECT: ListView.builder (lazy rendering)
|
||||
ListView.builder(
|
||||
itemCount: items.length,
|
||||
itemBuilder: (context, index) => ItemWidget(items[index]),
|
||||
// Additional optimizations:
|
||||
itemExtent: 56, // Fixed height = faster layout
|
||||
cacheExtent: 100, // Pre-render distance
|
||||
)
|
||||
|
||||
// ✅ EVEN BETTER: ListView.separated for dividers
|
||||
ListView.separated(
|
||||
itemCount: items.length,
|
||||
itemBuilder: (context, index) => ItemWidget(items[index]),
|
||||
separatorBuilder: (context, index) => const Divider(),
|
||||
)
|
||||
```
|
||||
|
||||
### Image Optimization
|
||||
|
||||
```dart
|
||||
// ❌ WRONG: No caching, full resolution
|
||||
Image.network(url)
|
||||
|
||||
// ✅ CORRECT: Cached with proper sizing
|
||||
CachedNetworkImage(
|
||||
imageUrl: url,
|
||||
width: 100,
|
||||
height: 100,
|
||||
fit: BoxFit.cover,
|
||||
memCacheWidth: 200, // Cache at 2x for retina
|
||||
memCacheHeight: 200,
|
||||
placeholder: (context, url) => const Skeleton(),
|
||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||
)
|
||||
```
|
||||
|
||||
### Dispose Pattern
|
||||
|
||||
```dart
|
||||
class MyWidget extends StatefulWidget {
|
||||
@override
|
||||
State<MyWidget> createState() => _MyWidgetState();
|
||||
}
|
||||
|
||||
class _MyWidgetState extends State<MyWidget> {
|
||||
late final StreamSubscription _subscription;
|
||||
late final AnimationController _controller;
|
||||
late final TextEditingController _textController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_subscription = stream.listen((_) {});
|
||||
_controller = AnimationController(vsync: this);
|
||||
_textController = TextEditingController();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// ALWAYS dispose in reverse order of creation
|
||||
_textController.dispose();
|
||||
_controller.dispose();
|
||||
_subscription.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Container();
|
||||
}
|
||||
```
|
||||
|
||||
### Flutter Performance Checklist
|
||||
|
||||
```markdown
|
||||
## Before Every Widget
|
||||
- [ ] const constructor added (if no runtime args)
|
||||
- [ ] const keywords on static children
|
||||
- [ ] Minimal setState scope
|
||||
- [ ] Using selectors for provider watches
|
||||
|
||||
## Before Every List
|
||||
- [ ] Using ListView.builder (NOT ListView with children)
|
||||
- [ ] itemExtent provided (if fixed height)
|
||||
- [ ] Image caching with size limits
|
||||
|
||||
## Before Any Animation
|
||||
- [ ] Using Impeller (Flutter 3.16+)
|
||||
- [ ] Avoiding Opacity widget (use FadeTransition)
|
||||
- [ ] TickerProviderStateMixin for AnimationController
|
||||
|
||||
## Before Any Release
|
||||
- [ ] All dispose() methods implemented
|
||||
- [ ] No print() in production
|
||||
- [ ] Tested in profile/release mode
|
||||
- [ ] DevTools performance overlay checked
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Animation Performance (Both Platforms)
|
||||
|
||||
### The 60fps Imperative
|
||||
|
||||
```
|
||||
Human eye detects:
|
||||
├── < 24 fps → "Slideshow" (broken)
|
||||
├── 24-30 fps → "Choppy" (uncomfortable)
|
||||
├── 30-45 fps → "Noticeably not smooth"
|
||||
├── 45-60 fps → "Smooth" (acceptable)
|
||||
├── 60 fps → "Buttery" (target)
|
||||
└── 120 fps → "Premium" (ProMotion devices)
|
||||
|
||||
NEVER ship < 60fps animations.
|
||||
```
|
||||
|
||||
### GPU vs CPU Animation
|
||||
|
||||
```
|
||||
GPU-ACCELERATED (FAST): CPU-BOUND (SLOW):
|
||||
├── transform: translate ├── width, height
|
||||
├── transform: scale ├── top, left, right, bottom
|
||||
├── transform: rotate ├── margin, padding
|
||||
├── opacity ├── border-radius (animated)
|
||||
└── (Composited, off main) └── box-shadow (animated)
|
||||
|
||||
RULE: Only animate transform and opacity.
|
||||
Everything else causes layout recalculation.
|
||||
```
|
||||
|
||||
### Animation Timing Guide
|
||||
|
||||
| Animation Type | Duration | Easing |
|
||||
|----------------|----------|--------|
|
||||
| Micro-interaction | 100-200ms | ease-out |
|
||||
| Standard transition | 200-300ms | ease-out |
|
||||
| Page transition | 300-400ms | ease-in-out |
|
||||
| Complex/dramatic | 400-600ms | ease-in-out |
|
||||
| Loading skeletons | 1000-1500ms | linear (loop) |
|
||||
|
||||
### Spring Physics
|
||||
|
||||
```javascript
|
||||
// React Native Reanimated
|
||||
withSpring(targetValue, {
|
||||
damping: 15, // How quickly it settles (higher = faster stop)
|
||||
stiffness: 150, // How "tight" the spring (higher = faster)
|
||||
mass: 1, // Weight of the object
|
||||
})
|
||||
|
||||
// Flutter
|
||||
SpringSimulation(
|
||||
SpringDescription(
|
||||
mass: 1,
|
||||
stiffness: 150,
|
||||
damping: 15,
|
||||
),
|
||||
start,
|
||||
end,
|
||||
velocity,
|
||||
)
|
||||
|
||||
// Natural feel ranges:
|
||||
// Damping: 10-20 (bouncy to settled)
|
||||
// Stiffness: 100-200 (loose to tight)
|
||||
// Mass: 0.5-2 (light to heavy)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Memory Management
|
||||
|
||||
### Common Memory Leaks
|
||||
|
||||
| Source | Platform | Solution |
|
||||
|--------|----------|----------|
|
||||
| Timers | Both | Clear in cleanup/dispose |
|
||||
| Event listeners | Both | Remove in cleanup/dispose |
|
||||
| Subscriptions | Both | Cancel in cleanup/dispose |
|
||||
| Large images | Both | Limit cache, resize |
|
||||
| Async after unmount | RN | isMounted check or AbortController |
|
||||
| Animation controllers | Flutter | Dispose controllers |
|
||||
|
||||
### Image Memory
|
||||
|
||||
```
|
||||
Image memory = width × height × 4 bytes (RGBA)
|
||||
|
||||
1080p image = 1920 × 1080 × 4 = 8.3 MB
|
||||
4K image = 3840 × 2160 × 4 = 33.2 MB
|
||||
|
||||
10 4K images = 332 MB → App crash!
|
||||
|
||||
RULE: Always resize images to display size (or 2-3x for retina).
|
||||
```
|
||||
|
||||
### Memory Profiling
|
||||
|
||||
```
|
||||
React Native:
|
||||
├── Flipper → Memory tab
|
||||
├── Xcode Instruments (iOS)
|
||||
└── Android Studio Profiler
|
||||
|
||||
Flutter:
|
||||
├── DevTools → Memory tab
|
||||
├── Observatory
|
||||
└── flutter run --profile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Battery Optimization
|
||||
|
||||
### Battery Drain Sources
|
||||
|
||||
| Source | Impact | Mitigation |
|
||||
|--------|--------|------------|
|
||||
| **Screen on** | 🔴 Highest | Dark mode on OLED |
|
||||
| **GPS continuous** | 🔴 Very high | Use significant change |
|
||||
| **Network requests** | 🟡 High | Batch, cache aggressively |
|
||||
| **Animations** | 🟡 Medium | Reduce when low battery |
|
||||
| **Background work** | 🟡 Medium | Defer non-critical |
|
||||
| **CPU computation** | 🟢 Lower | Offload to backend |
|
||||
|
||||
### OLED Battery Saving
|
||||
|
||||
```
|
||||
OLED screens: Black pixels = OFF = 0 power
|
||||
|
||||
Dark mode savings:
|
||||
├── True black (#000000) → Maximum savings
|
||||
├── Dark gray (#1a1a1a) → Slight savings
|
||||
├── Any color → Some power
|
||||
└── White (#FFFFFF) → Maximum power
|
||||
|
||||
RULE: On dark mode, use true black for backgrounds.
|
||||
```
|
||||
|
||||
### Background Task Guidelines
|
||||
|
||||
```
|
||||
iOS:
|
||||
├── Background refresh: Limited, system-scheduled
|
||||
├── Push notifications: Use for important updates
|
||||
├── Background modes: Location, audio, VoIP only
|
||||
└── Background tasks: Max ~30 seconds
|
||||
|
||||
Android:
|
||||
├── WorkManager: System-scheduled, battery-aware
|
||||
├── Foreground service: Visible to user, continuous
|
||||
├── JobScheduler: Batch network operations
|
||||
└── Doze mode: Respect it, batch operations
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Network Performance
|
||||
|
||||
### Offline-First Architecture
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ UI │
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌──────▼───────┐
|
||||
│ Cache │ ← Read from cache FIRST
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌──────▼───────┐
|
||||
│ Network │ ← Update cache from network
|
||||
└──────────────┘
|
||||
|
||||
Benefits:
|
||||
├── Instant UI (no loading spinner for cached data)
|
||||
├── Works offline
|
||||
├── Reduces data usage
|
||||
└── Better UX on slow networks
|
||||
```
|
||||
|
||||
### Request Optimization
|
||||
|
||||
```
|
||||
BATCH: Combine multiple requests into one
|
||||
├── 10 small requests → 1 batch request
|
||||
├── Reduces connection overhead
|
||||
└── Better for battery (radio on once)
|
||||
|
||||
CACHE: Don't re-fetch unchanged data
|
||||
├── ETag/If-None-Match headers
|
||||
├── Cache-Control headers
|
||||
└── Stale-while-revalidate pattern
|
||||
|
||||
COMPRESS: Reduce payload size
|
||||
├── gzip/brotli compression
|
||||
├── Request only needed fields (GraphQL)
|
||||
└── Paginate large lists
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Performance Testing
|
||||
|
||||
### What to Test
|
||||
|
||||
| Metric | Target | Tool |
|
||||
|--------|--------|------|
|
||||
| **Frame rate** | ≥ 60fps | Performance overlay |
|
||||
| **Memory** | Stable, no growth | Profiler |
|
||||
| **Cold start** | < 2s | Manual timing |
|
||||
| **TTI (Time to Interactive)** | < 3s | Lighthouse |
|
||||
| **List scroll** | No jank | Manual feel |
|
||||
| **Animation smoothness** | No drops | Performance monitor |
|
||||
|
||||
### Test on Real Devices
|
||||
|
||||
```
|
||||
⚠️ NEVER trust only:
|
||||
├── Simulator/emulator (faster than real)
|
||||
├── Dev mode (slower than release)
|
||||
├── High-end devices only
|
||||
|
||||
✅ ALWAYS test on:
|
||||
├── Low-end Android (< $200 phone)
|
||||
├── Older iOS device (iPhone 8 or SE)
|
||||
├── Release/profile build
|
||||
└── With real data (not 10 items)
|
||||
```
|
||||
|
||||
### Performance Monitoring Checklist
|
||||
|
||||
```markdown
|
||||
## During Development
|
||||
- [ ] Performance overlay enabled
|
||||
- [ ] Watching for dropped frames
|
||||
- [ ] Memory usage stable
|
||||
- [ ] No console warnings about performance
|
||||
|
||||
## Before Release
|
||||
- [ ] Tested on low-end device
|
||||
- [ ] Profiled memory over extended use
|
||||
- [ ] Cold start time measured
|
||||
- [ ] List scroll tested with 1000+ items
|
||||
- [ ] Animations tested at 60fps
|
||||
- [ ] Network tested on slow 3G
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Quick Reference Card
|
||||
|
||||
### React Native Essentials
|
||||
|
||||
```javascript
|
||||
// List: Always use
|
||||
<FlatList
|
||||
data={data}
|
||||
renderItem={useCallback(({item}) => <MemoItem item={item} />, [])}
|
||||
keyExtractor={useCallback(item => item.id, [])}
|
||||
getItemLayout={useCallback((_, i) => ({length: H, offset: H*i, index: i}), [])}
|
||||
/>
|
||||
|
||||
// Animation: Always native
|
||||
useNativeDriver: true
|
||||
|
||||
// Cleanup: Always present
|
||||
useEffect(() => {
|
||||
return () => cleanup();
|
||||
}, []);
|
||||
```
|
||||
|
||||
### Flutter Essentials
|
||||
|
||||
```dart
|
||||
// Widgets: Always const
|
||||
const MyWidget()
|
||||
|
||||
// Lists: Always builder
|
||||
ListView.builder(itemBuilder: ...)
|
||||
|
||||
// State: Always targeted
|
||||
ValueListenableBuilder() or ref.watch(provider.select(...))
|
||||
|
||||
// Dispose: Always cleanup
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
```
|
||||
|
||||
### Animation Targets
|
||||
|
||||
```
|
||||
Transform/Opacity only ← What to animate
|
||||
16.67ms per frame ← Time budget
|
||||
60fps minimum ← Target
|
||||
Low-end Android ← Test device
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Performance is not optimization—it's baseline quality. A slow app is a broken app. Test on the worst device your users have, not the best device you have.
|
||||
356
skills/mobile-design/mobile-testing.md
Normal file
356
skills/mobile-design/mobile-testing.md
Normal file
@@ -0,0 +1,356 @@
|
||||
# Mobile Testing Patterns
|
||||
|
||||
> **Mobile testing is NOT web testing. Different constraints, different strategies.**
|
||||
> This file teaches WHEN to use each testing approach and WHY.
|
||||
> **Code examples are minimal - focus on decision-making.**
|
||||
|
||||
---
|
||||
|
||||
## 🧠 MOBILE TESTING MINDSET
|
||||
|
||||
```
|
||||
Mobile testing differs from web:
|
||||
├── Real devices matter (emulators hide bugs)
|
||||
├── Platform differences (iOS vs Android behavior)
|
||||
├── Network conditions vary wildly
|
||||
├── Battery/performance under test
|
||||
├── App lifecycle (background, killed, restored)
|
||||
├── Permissions and system dialogs
|
||||
└── Touch interactions vs clicks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚫 AI MOBILE TESTING ANTI-PATTERNS
|
||||
|
||||
| ❌ AI Default | Why It's Wrong | ✅ Mobile-Correct |
|
||||
|---------------|----------------|-------------------|
|
||||
| Jest-only testing | Misses native layer | Jest + E2E on device |
|
||||
| Enzyme patterns | Deprecated, web-focused | React Native Testing Library |
|
||||
| Browser-based E2E (Cypress) | Can't test native features | Detox / Maestro |
|
||||
| Mock everything | Misses integration bugs | Real device testing |
|
||||
| Ignore platform tests | iOS/Android differ | Platform-specific cases |
|
||||
| Skip performance tests | Mobile perf is critical | Profile on low-end device |
|
||||
| Test only happy path | Mobile has more edge cases | Offline, permissions, interrupts |
|
||||
| 100% unit test coverage | False security | Pyramid balance |
|
||||
| Copy web testing patterns | Different environment | Mobile-specific tools |
|
||||
|
||||
---
|
||||
|
||||
## 1. Testing Tool Selection
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
WHAT ARE YOU TESTING?
|
||||
│
|
||||
├── Pure functions, utilities, helpers
|
||||
│ └── Jest (unit tests)
|
||||
│ └── No special mobile setup needed
|
||||
│
|
||||
├── Individual components (isolated)
|
||||
│ ├── React Native → React Native Testing Library
|
||||
│ └── Flutter → flutter_test (widget tests)
|
||||
│
|
||||
├── Components with hooks, context, navigation
|
||||
│ ├── React Native → RNTL + mocked providers
|
||||
│ └── Flutter → integration_test package
|
||||
│
|
||||
├── Full user flows (login, checkout, etc.)
|
||||
│ ├── Detox (React Native, fast, reliable)
|
||||
│ ├── Maestro (Cross-platform, YAML-based)
|
||||
│ └── Appium (Legacy, slow, last resort)
|
||||
│
|
||||
└── Performance, memory, battery
|
||||
├── Flashlight (RN performance)
|
||||
├── Flutter DevTools
|
||||
└── Real device profiling (Xcode/Android Studio)
|
||||
```
|
||||
|
||||
### Tool Comparison
|
||||
|
||||
| Tool | Platform | Speed | Reliability | Use When |
|
||||
|------|----------|-------|-------------|----------|
|
||||
| **Jest** | RN | ⚡⚡⚡ | ⚡⚡⚡ | Unit tests, logic |
|
||||
| **RNTL** | RN | ⚡⚡⚡ | ⚡⚡ | Component tests |
|
||||
| **flutter_test** | Flutter | ⚡⚡⚡ | ⚡⚡⚡ | Widget tests |
|
||||
| **Detox** | RN | ⚡⚡ | ⚡⚡⚡ | E2E, critical flows |
|
||||
| **Maestro** | Both | ⚡⚡ | ⚡⚡ | E2E, cross-platform |
|
||||
| **Appium** | Both | ⚡ | ⚡ | Legacy, last resort |
|
||||
|
||||
---
|
||||
|
||||
## 2. Testing Pyramid for Mobile
|
||||
|
||||
```
|
||||
┌───────────────┐
|
||||
│ E2E Tests │ 10%
|
||||
│ (Real device) │ Slow, expensive, essential
|
||||
├───────────────┤
|
||||
│ Integration │ 20%
|
||||
│ Tests │ Component + context
|
||||
├───────────────┤
|
||||
│ Component │ 30%
|
||||
│ Tests │ Isolated UI
|
||||
├───────────────┤
|
||||
│ Unit Tests │ 40%
|
||||
│ (Jest) │ Pure logic
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
### Why This Distribution?
|
||||
|
||||
| Level | Why This % |
|
||||
|-------|------------|
|
||||
| **E2E 10%** | Slow, flaky, but catches integration bugs |
|
||||
| **Integration 20%** | Tests real user flows without full app |
|
||||
| **Component 30%** | Fast feedback on UI changes |
|
||||
| **Unit 40%** | Fastest, most stable, logic coverage |
|
||||
|
||||
> 🔴 **If you have 90% unit tests and 0% E2E, you're testing the wrong things.**
|
||||
|
||||
---
|
||||
|
||||
## 3. What to Test at Each Level
|
||||
|
||||
### Unit Tests (Jest)
|
||||
|
||||
```
|
||||
✅ TEST:
|
||||
├── Utility functions (formatDate, calculatePrice)
|
||||
├── State reducers (Redux, Zustand stores)
|
||||
├── API response transformers
|
||||
├── Validation logic
|
||||
└── Business rules
|
||||
|
||||
❌ DON'T TEST:
|
||||
├── Component rendering (use component tests)
|
||||
├── Navigation (use integration tests)
|
||||
├── Native modules (mock them)
|
||||
└── Third-party libraries
|
||||
```
|
||||
|
||||
### Component Tests (RNTL / flutter_test)
|
||||
|
||||
```
|
||||
✅ TEST:
|
||||
├── Component renders correctly
|
||||
├── User interactions (tap, type, swipe)
|
||||
├── Loading/error/empty states
|
||||
├── Accessibility labels exist
|
||||
└── Props change behavior
|
||||
|
||||
❌ DON'T TEST:
|
||||
├── Internal implementation details
|
||||
├── Snapshot everything (only key components)
|
||||
├── Styling specifics (brittle)
|
||||
└── Third-party component internals
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
```
|
||||
✅ TEST:
|
||||
├── Form submission flows
|
||||
├── Navigation between screens
|
||||
├── State persistence across screens
|
||||
├── API integration (with mocked server)
|
||||
└── Context/provider interactions
|
||||
|
||||
❌ DON'T TEST:
|
||||
├── Every possible path (use unit tests)
|
||||
├── Third-party services (mock them)
|
||||
└── Backend logic (backend tests)
|
||||
```
|
||||
|
||||
### E2E Tests
|
||||
|
||||
```
|
||||
✅ TEST:
|
||||
├── Critical user journeys (login, purchase, signup)
|
||||
├── Offline → online transitions
|
||||
├── Deep link handling
|
||||
├── Push notification navigation
|
||||
├── Permission flows
|
||||
└── Payment flows
|
||||
|
||||
❌ DON'T TEST:
|
||||
├── Every edge case (too slow)
|
||||
├── Visual regression (use snapshot tests)
|
||||
├── Non-critical features
|
||||
└── Backend-only logic
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Platform-Specific Testing
|
||||
|
||||
### What Differs Between iOS and Android?
|
||||
|
||||
| Area | iOS Behavior | Android Behavior | Test Both? |
|
||||
|------|--------------|------------------|------------|
|
||||
| **Back navigation** | Edge swipe | System back button | ✅ YES |
|
||||
| **Permissions** | Ask once, settings | Ask each time, rationale | ✅ YES |
|
||||
| **Keyboard** | Different appearance | Different behavior | ✅ YES |
|
||||
| **Date picker** | Wheel/modal | Material dialog | ⚠️ If custom UI |
|
||||
| **Push format** | APNs payload | FCM payload | ✅ YES |
|
||||
| **Deep links** | Universal Links | App Links | ✅ YES |
|
||||
| **Gestures** | Some unique | Material gestures | ⚠️ If custom |
|
||||
|
||||
### Platform Testing Strategy
|
||||
|
||||
```
|
||||
FOR EACH PLATFORM:
|
||||
├── Run unit tests (same on both)
|
||||
├── Run component tests (same on both)
|
||||
├── Run E2E on REAL DEVICE
|
||||
│ ├── iOS: iPhone (not just simulator)
|
||||
│ └── Android: Mid-range device (not flagship)
|
||||
└── Test platform-specific features separately
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Offline & Network Testing
|
||||
|
||||
### Offline Scenarios to Test
|
||||
|
||||
| Scenario | What to Verify |
|
||||
|----------|----------------|
|
||||
| Start app offline | Shows cached data or offline message |
|
||||
| Go offline mid-action | Action queued, not lost |
|
||||
| Come back online | Queue synced, no duplicates |
|
||||
| Slow network (2G) | Loading states, timeouts work |
|
||||
| Flaky network | Retry logic, error recovery |
|
||||
|
||||
### How to Test Network Conditions
|
||||
|
||||
```
|
||||
APPROACH:
|
||||
├── Unit tests: Mock NetInfo, test logic
|
||||
├── Integration: Mock API responses, test UI
|
||||
├── E2E (Detox): Use device.setURLBlacklist()
|
||||
├── E2E (Maestro): Use network conditions
|
||||
└── Manual: Use Charles Proxy / Network Link Conditioner
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Performance Testing
|
||||
|
||||
### What to Measure
|
||||
|
||||
| Metric | Target | How to Measure |
|
||||
|--------|--------|----------------|
|
||||
| **App startup** | < 2 seconds | Profiler, Flashlight |
|
||||
| **Screen transition** | < 300ms | React DevTools |
|
||||
| **List scroll** | 60 FPS | Profiler, feel |
|
||||
| **Memory** | Stable, no leaks | Instruments / Android Profiler |
|
||||
| **Bundle size** | Minimize | Metro bundler analysis |
|
||||
|
||||
### When to Performance Test
|
||||
|
||||
```
|
||||
PERFORMANCE TEST:
|
||||
├── Before release (required)
|
||||
├── After adding heavy features
|
||||
├── After upgrading dependencies
|
||||
├── When users report slowness
|
||||
└── On CI (optional, automated benchmarks)
|
||||
|
||||
WHERE TO TEST:
|
||||
├── Real device (REQUIRED)
|
||||
├── Low-end device (Galaxy A series, old iPhone)
|
||||
├── NOT on emulator (lies about performance)
|
||||
└── With production-like data (not 3 items)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Accessibility Testing
|
||||
|
||||
### What to Verify
|
||||
|
||||
| Element | Check |
|
||||
|---------|-------|
|
||||
| Interactive elements | Have accessibilityLabel |
|
||||
| Images | Have alt text or decorative flag |
|
||||
| Forms | Labels linked to inputs |
|
||||
| Buttons | Role = button |
|
||||
| Touch targets | ≥ 44x44 (iOS) / 48x48 (Android) |
|
||||
| Color contrast | WCAG AA minimum |
|
||||
|
||||
### How to Test
|
||||
|
||||
```
|
||||
AUTOMATED:
|
||||
├── React Native: jest-axe
|
||||
├── Flutter: Accessibility checker in tests
|
||||
└── Lint rules for missing labels
|
||||
|
||||
MANUAL:
|
||||
├── Enable VoiceOver (iOS) / TalkBack (Android)
|
||||
├── Navigate entire app with screen reader
|
||||
├── Test with increased text size
|
||||
└── Test with reduced motion
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. CI/CD Integration
|
||||
|
||||
### What to Run Where
|
||||
|
||||
| Stage | Tests | Devices |
|
||||
|-------|-------|---------|
|
||||
| **PR** | Unit + Component | None (fast) |
|
||||
| **Merge to main** | + Integration | Simulator/Emulator |
|
||||
| **Pre-release** | + E2E | Real devices (farm) |
|
||||
| **Nightly** | Full suite | Device farm |
|
||||
|
||||
### Device Farm Options
|
||||
|
||||
| Service | Pros | Cons |
|
||||
|---------|------|------|
|
||||
| **Firebase Test Lab** | Free tier, Google devices | Android focus |
|
||||
| **AWS Device Farm** | Wide selection | Expensive |
|
||||
| **BrowserStack** | Good UX | Expensive |
|
||||
| **Local devices** | Free, reliable | Limited variety |
|
||||
|
||||
---
|
||||
|
||||
## 📝 MOBILE TESTING CHECKLIST
|
||||
|
||||
### Before PR
|
||||
- [ ] Unit tests for new logic
|
||||
- [ ] Component tests for new UI
|
||||
- [ ] No console.logs in tests
|
||||
- [ ] Tests pass on CI
|
||||
|
||||
### Before Release
|
||||
- [ ] E2E on real iOS device
|
||||
- [ ] E2E on real Android device
|
||||
- [ ] Tested on low-end device
|
||||
- [ ] Offline scenarios verified
|
||||
- [ ] Performance acceptable
|
||||
- [ ] Accessibility verified
|
||||
|
||||
### What to Skip (Consciously)
|
||||
- [ ] 100% coverage (aim for meaningful coverage)
|
||||
- [ ] Every visual permutation (use snapshots sparingly)
|
||||
- [ ] Third-party library internals
|
||||
- [ ] Backend logic (separate tests)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Testing Questions to Ask
|
||||
|
||||
Before writing tests, answer:
|
||||
|
||||
1. **What could break?** → Test that
|
||||
2. **What's critical for users?** → E2E test that
|
||||
3. **What's complex logic?** → Unit test that
|
||||
4. **What's platform-specific?** → Test on both platforms
|
||||
5. **What happens offline?** → Test that scenario
|
||||
|
||||
> **Remember:** Good mobile testing is about testing the RIGHT things, not EVERYTHING. A flaky E2E test is worse than no test. A failing unit test that catches a bug is worth 100 passing trivial tests.
|
||||
433
skills/mobile-design/mobile-typography.md
Normal file
433
skills/mobile-design/mobile-typography.md
Normal file
@@ -0,0 +1,433 @@
|
||||
# Mobile Typography Reference
|
||||
|
||||
> Type scale, system fonts, Dynamic Type, accessibility, and dark mode typography.
|
||||
> **Typography failures are the #1 cause of unreadable mobile apps.**
|
||||
|
||||
---
|
||||
|
||||
## 1. Mobile Typography Fundamentals
|
||||
|
||||
### Why Mobile Type is Different
|
||||
|
||||
```
|
||||
DESKTOP: MOBILE:
|
||||
├── 20-30" viewing distance ├── 12-15" viewing distance
|
||||
├── Large viewport ├── Small viewport, narrow
|
||||
├── Hover for details ├── Tap/scroll for details
|
||||
├── Controlled lighting ├── Variable (outdoor, etc.)
|
||||
├── Fixed font size ├── User-controlled sizing
|
||||
└── Long reading sessions └── Quick scanning
|
||||
```
|
||||
|
||||
### Mobile Type Rules
|
||||
|
||||
| Rule | Desktop | Mobile |
|
||||
|------|---------|--------|
|
||||
| **Minimum body size** | 14px | 16px (14pt/14sp) |
|
||||
| **Maximum line length** | 75 characters | 40-60 characters |
|
||||
| **Line height** | 1.4-1.5 | 1.4-1.6 (more generous) |
|
||||
| **Font weight** | Varies | Regular dominant, bold sparingly |
|
||||
| **Contrast** | AA (4.5:1) | AA minimum, AAA preferred |
|
||||
|
||||
---
|
||||
|
||||
## 2. System Fonts
|
||||
|
||||
### iOS: SF Pro Family
|
||||
|
||||
```
|
||||
San Francisco (SF) Family:
|
||||
├── SF Pro Display: Large text (≥ 20pt)
|
||||
├── SF Pro Text: Body text (< 20pt)
|
||||
├── SF Pro Rounded: Friendly contexts
|
||||
├── SF Mono: Monospace
|
||||
└── SF Compact: Apple Watch, compact UI
|
||||
|
||||
Features:
|
||||
├── Optical sizing (auto-adjusts)
|
||||
├── Dynamic tracking (spacing)
|
||||
├── Tabular/proportional figures
|
||||
├── Excellent legibility
|
||||
```
|
||||
|
||||
### Android: Roboto Family
|
||||
|
||||
```
|
||||
Roboto Family:
|
||||
├── Roboto: Default sans-serif
|
||||
├── Roboto Flex: Variable font
|
||||
├── Roboto Serif: Serif option
|
||||
├── Roboto Mono: Monospace
|
||||
├── Roboto Condensed: Narrow spaces
|
||||
|
||||
Features:
|
||||
├── Optimized for screens
|
||||
├── Wide language support
|
||||
├── Multiple weights
|
||||
├── Good at small sizes
|
||||
```
|
||||
|
||||
### When to Use System Fonts
|
||||
|
||||
```
|
||||
✅ USE system fonts when:
|
||||
├── Brand doesn't mandate custom font
|
||||
├── Reading efficiency is priority
|
||||
├── App feels native/integrated important
|
||||
├── Performance is critical
|
||||
├── Wide language support needed
|
||||
|
||||
❌ AVOID system fonts when:
|
||||
├── Brand identity requires custom
|
||||
├── Design differentiation needed
|
||||
├── Editorial/magazine style
|
||||
└── (But still support accessibility)
|
||||
```
|
||||
|
||||
### Custom Font Considerations
|
||||
|
||||
```
|
||||
If using custom fonts:
|
||||
├── Include all weights needed
|
||||
├── Subset for file size
|
||||
├── Test at all Dynamic Type sizes
|
||||
├── Provide fallback to system
|
||||
├── Test rendering quality
|
||||
└── Check language support
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Type Scale
|
||||
|
||||
### iOS Type Scale (Built-in)
|
||||
|
||||
| Style | Size | Weight | Line Height |
|
||||
|-------|------|--------|-------------|
|
||||
| Large Title | 34pt | Bold | 41pt |
|
||||
| Title 1 | 28pt | Bold | 34pt |
|
||||
| Title 2 | 22pt | Bold | 28pt |
|
||||
| Title 3 | 20pt | Semibold | 25pt |
|
||||
| Headline | 17pt | Semibold | 22pt |
|
||||
| Body | 17pt | Regular | 22pt |
|
||||
| Callout | 16pt | Regular | 21pt |
|
||||
| Subhead | 15pt | Regular | 20pt |
|
||||
| Footnote | 13pt | Regular | 18pt |
|
||||
| Caption 1 | 12pt | Regular | 16pt |
|
||||
| Caption 2 | 11pt | Regular | 13pt |
|
||||
|
||||
### Android Type Scale (Material 3)
|
||||
|
||||
| Role | Size | Weight | Line Height |
|
||||
|------|------|--------|-------------|
|
||||
| Display Large | 57sp | 400 | 64sp |
|
||||
| Display Medium | 45sp | 400 | 52sp |
|
||||
| Display Small | 36sp | 400 | 44sp |
|
||||
| Headline Large | 32sp | 400 | 40sp |
|
||||
| Headline Medium | 28sp | 400 | 36sp |
|
||||
| Headline Small | 24sp | 400 | 32sp |
|
||||
| Title Large | 22sp | 400 | 28sp |
|
||||
| Title Medium | 16sp | 500 | 24sp |
|
||||
| Title Small | 14sp | 500 | 20sp |
|
||||
| Body Large | 16sp | 400 | 24sp |
|
||||
| Body Medium | 14sp | 400 | 20sp |
|
||||
| Body Small | 12sp | 400 | 16sp |
|
||||
| Label Large | 14sp | 500 | 20sp |
|
||||
| Label Medium | 12sp | 500 | 16sp |
|
||||
| Label Small | 11sp | 500 | 16sp |
|
||||
|
||||
### Creating Custom Scale
|
||||
|
||||
```
|
||||
If creating custom scale, use modular ratio:
|
||||
|
||||
Recommended ratios:
|
||||
├── 1.125 (Major second): Dense UI
|
||||
├── 1.200 (Minor third): Compact
|
||||
├── 1.250 (Major third): Balanced (common)
|
||||
├── 1.333 (Perfect fourth): Spacious
|
||||
└── 1.500 (Perfect fifth): Dramatic
|
||||
|
||||
Example with 1.25 ratio, 16px base:
|
||||
├── xs: 10px (16 ÷ 1.25 ÷ 1.25)
|
||||
├── sm: 13px (16 ÷ 1.25)
|
||||
├── base: 16px
|
||||
├── lg: 20px (16 × 1.25)
|
||||
├── xl: 25px (16 × 1.25 × 1.25)
|
||||
├── 2xl: 31px
|
||||
├── 3xl: 39px
|
||||
└── 4xl: 49px
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Dynamic Type / Text Scaling
|
||||
|
||||
### iOS Dynamic Type (MANDATORY)
|
||||
|
||||
```swift
|
||||
// ❌ WRONG: Fixed size (doesn't scale)
|
||||
Text("Hello")
|
||||
.font(.system(size: 17))
|
||||
|
||||
// ✅ CORRECT: Dynamic Type
|
||||
Text("Hello")
|
||||
.font(.body) // Scales with user setting
|
||||
|
||||
// Custom font with scaling
|
||||
Text("Hello")
|
||||
.font(.custom("MyFont", size: 17, relativeTo: .body))
|
||||
```
|
||||
|
||||
### Android Text Scaling (MANDATORY)
|
||||
|
||||
```
|
||||
ALWAYS use sp for text:
|
||||
├── sp = Scale-independent pixels
|
||||
├── Scales with user font preference
|
||||
├── dp does NOT scale (don't use for text)
|
||||
|
||||
User can scale from 85% to 200%:
|
||||
├── Default (100%): 14sp = 14dp
|
||||
├── Largest (200%): 14sp = 28dp
|
||||
|
||||
Test at 200%!
|
||||
```
|
||||
|
||||
### Scaling Challenges
|
||||
|
||||
```
|
||||
Problems at large text sizes:
|
||||
├── Text overflows containers
|
||||
├── Buttons become too tall
|
||||
├── Icons look small relative to text
|
||||
├── Layouts break
|
||||
|
||||
Solutions:
|
||||
├── Use flexible containers (not fixed height)
|
||||
├── Allow text wrapping
|
||||
├── Scale icons with text
|
||||
├── Test at extremes during development
|
||||
├── Use scrollable containers for long text
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Typography Accessibility
|
||||
|
||||
### Minimum Sizes
|
||||
|
||||
| Element | Minimum | Recommended |
|
||||
|---------|---------|-------------|
|
||||
| Body text | 14px/pt/sp | 16px/pt/sp |
|
||||
| Secondary text | 12px/pt/sp | 13-14px/pt/sp |
|
||||
| Captions | 11px/pt/sp | 12px/pt/sp |
|
||||
| Buttons | 14px/pt/sp | 14-16px/pt/sp |
|
||||
| **Nothing smaller** | 11px | - |
|
||||
|
||||
### Contrast Requirements (WCAG)
|
||||
|
||||
```
|
||||
Normal text (< 18pt or < 14pt bold):
|
||||
├── AA: 4.5:1 ratio minimum
|
||||
├── AAA: 7:1 ratio recommended
|
||||
|
||||
Large text (≥ 18pt or ≥ 14pt bold):
|
||||
├── AA: 3:1 ratio minimum
|
||||
├── AAA: 4.5:1 ratio recommended
|
||||
|
||||
Logos/decorative: No requirement
|
||||
```
|
||||
|
||||
### Line Height for Accessibility
|
||||
|
||||
```
|
||||
WCAG Success Criterion 1.4.12:
|
||||
|
||||
Line height (line spacing): ≥ 1.5×
|
||||
Paragraph spacing: ≥ 2× font size
|
||||
Letter spacing: ≥ 0.12× font size
|
||||
Word spacing: ≥ 0.16× font size
|
||||
|
||||
Mobile recommendation:
|
||||
├── Body: 1.4-1.6 line height
|
||||
├── Headings: 1.2-1.3 line height
|
||||
├── Never below 1.2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Dark Mode Typography
|
||||
|
||||
### Color Adjustments
|
||||
|
||||
```
|
||||
Light Mode: Dark Mode:
|
||||
├── Black text (#000) ├── White/light gray (#E0E0E0)
|
||||
├── High contrast ├── Slightly reduced contrast
|
||||
├── Full saturation ├── Desaturated colors
|
||||
└── Dark = emphasis └── Light = emphasis
|
||||
|
||||
RULE: Don't use pure white (#FFF) on dark.
|
||||
Use off-white (#E0E0E0 to #F0F0F0) to reduce eye strain.
|
||||
```
|
||||
|
||||
### Dark Mode Hierarchy
|
||||
|
||||
| Level | Light Mode | Dark Mode |
|
||||
|-------|------------|-----------|
|
||||
| Primary text | #000000 | #E8E8E8 |
|
||||
| Secondary text | #666666 | #A0A0A0 |
|
||||
| Tertiary text | #999999 | #707070 |
|
||||
| Disabled text | #CCCCCC | #505050 |
|
||||
|
||||
### Weight in Dark Mode
|
||||
|
||||
```
|
||||
Dark mode text appears thinner due to halation
|
||||
(light bleeding into dark background)
|
||||
|
||||
Consider:
|
||||
├── Using medium weight for body (instead of regular)
|
||||
├── Increasing letter-spacing slightly
|
||||
├── Testing on actual OLED displays
|
||||
└── Using slightly bolder weight than light mode
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Typography Anti-Patterns
|
||||
|
||||
### ❌ Common Mistakes
|
||||
|
||||
| Mistake | Problem | Fix |
|
||||
|---------|---------|-----|
|
||||
| **Fixed font sizes** | Ignores accessibility | Use dynamic sizing |
|
||||
| **Too small text** | Unreadable | Min 14pt/sp |
|
||||
| **Low contrast** | Invisible in sunlight | Min 4.5:1 |
|
||||
| **Long lines** | Hard to track | Max 60 chars |
|
||||
| **Tight line height** | Cramped, hard to read | Min 1.4× |
|
||||
| **Too many sizes** | Visual chaos | Max 5-7 sizes |
|
||||
| **All caps body** | Hard to read | Headlines only |
|
||||
| **Light gray on white** | Impossible in bright light | Higher contrast |
|
||||
|
||||
### ❌ AI Typography Mistakes
|
||||
|
||||
```
|
||||
AI tends to:
|
||||
├── Use fixed px values instead of pt/sp
|
||||
├── Skip Dynamic Type support
|
||||
├── Use too small text (12-14px body)
|
||||
├── Ignore line height settings
|
||||
├── Use low contrast "aesthetic" grays
|
||||
├── Apply same scale to mobile as desktop
|
||||
└── Skip testing at large text sizes
|
||||
|
||||
RULE: Typography must SCALE.
|
||||
Test at smallest and largest settings.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Font Loading & Performance
|
||||
|
||||
### Font File Optimization
|
||||
|
||||
```
|
||||
Font file sizes matter on mobile:
|
||||
├── Full font: 100-300KB per weight
|
||||
├── Subset (Latin): 15-40KB per weight
|
||||
├── Variable font: 100-200KB (all weights)
|
||||
|
||||
Recommendations:
|
||||
├── Subset to needed characters
|
||||
├── Use WOFF2 format
|
||||
├── Max 2-3 font files
|
||||
├── Consider variable fonts
|
||||
├── Cache fonts appropriately
|
||||
```
|
||||
|
||||
### Loading Strategy
|
||||
|
||||
```
|
||||
1. SYSTEM FONT FALLBACK
|
||||
Show system font → swap when custom loads
|
||||
|
||||
2. FONT DISPLAY SWAP
|
||||
font-display: swap (CSS)
|
||||
|
||||
3. PRELOAD CRITICAL FONTS
|
||||
Preload fonts needed above the fold
|
||||
|
||||
4. DON'T BLOCK RENDER
|
||||
Don't wait for fonts to show content
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Typography Checklist
|
||||
|
||||
### Before Any Text Design
|
||||
|
||||
- [ ] Body text ≥ 16px/pt/sp?
|
||||
- [ ] Line height ≥ 1.4?
|
||||
- [ ] Line length ≤ 60 chars?
|
||||
- [ ] Type scale defined (max 5-7 sizes)?
|
||||
- [ ] Using pt (iOS) or sp (Android)?
|
||||
|
||||
### Before Release
|
||||
|
||||
- [ ] Dynamic Type tested (iOS)?
|
||||
- [ ] Font scaling tested at 200% (Android)?
|
||||
- [ ] Dark mode contrast checked?
|
||||
- [ ] Sunlight readability tested?
|
||||
- [ ] All text has proper hierarchy?
|
||||
- [ ] Custom fonts have fallbacks?
|
||||
- [ ] Long text scrolls properly?
|
||||
|
||||
---
|
||||
|
||||
## 10. Quick Reference
|
||||
|
||||
### Typography Tokens
|
||||
|
||||
```
|
||||
// iOS
|
||||
.largeTitle // 34pt, Bold
|
||||
.title // 28pt, Bold
|
||||
.title2 // 22pt, Bold
|
||||
.title3 // 20pt, Semibold
|
||||
.headline // 17pt, Semibold
|
||||
.body // 17pt, Regular
|
||||
.subheadline // 15pt, Regular
|
||||
.footnote // 13pt, Regular
|
||||
.caption // 12pt, Regular
|
||||
|
||||
// Android (Material 3)
|
||||
displayLarge // 57sp
|
||||
headlineLarge // 32sp
|
||||
titleLarge // 22sp
|
||||
bodyLarge // 16sp
|
||||
labelLarge // 14sp
|
||||
```
|
||||
|
||||
### Minimum Sizes
|
||||
|
||||
```
|
||||
Body: 14-16pt/sp (16 preferred)
|
||||
Secondary: 12-13pt/sp
|
||||
Caption: 11-12pt/sp
|
||||
Nothing: < 11pt/sp
|
||||
```
|
||||
|
||||
### Line Height
|
||||
|
||||
```
|
||||
Headings: 1.1-1.3
|
||||
Body: 1.4-1.6
|
||||
Long text: 1.5-1.75
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** If users can't read your text, your app is broken. Typography isn't decoration—it's the primary interface. Test on real devices, in real conditions, with accessibility settings enabled.
|
||||
666
skills/mobile-design/platform-android.md
Normal file
666
skills/mobile-design/platform-android.md
Normal file
@@ -0,0 +1,666 @@
|
||||
# Android Platform Guidelines
|
||||
|
||||
> Material Design 3 essentials, Android design conventions, Roboto typography, and native patterns.
|
||||
> **Read this file when building for Android devices.**
|
||||
|
||||
---
|
||||
|
||||
## 1. Material Design 3 Philosophy
|
||||
|
||||
### Core Material Principles
|
||||
|
||||
```
|
||||
MATERIAL AS METAPHOR:
|
||||
├── Surfaces exist in 3D space
|
||||
├── Light and shadow define hierarchy
|
||||
├── Motion provides continuity
|
||||
└── Bold, graphic, intentional design
|
||||
|
||||
ADAPTIVE DESIGN:
|
||||
├── Responds to device capabilities
|
||||
├── One UI for all form factors
|
||||
├── Dynamic color from wallpaper
|
||||
└── Personalized per user
|
||||
|
||||
ACCESSIBLE BY DEFAULT:
|
||||
├── Large touch targets
|
||||
├── Clear visual hierarchy
|
||||
├── Semantic colors
|
||||
└── Motion respects preferences
|
||||
```
|
||||
|
||||
### Material Design Values
|
||||
|
||||
| Value | Implementation |
|
||||
|-------|----------------|
|
||||
| **Dynamic Color** | Colors adapt to wallpaper/user preference |
|
||||
| **Personalization** | User-specific themes |
|
||||
| **Accessibility** | Built into every component |
|
||||
| **Responsiveness** | Works on all screen sizes |
|
||||
| **Consistency** | Unified design language |
|
||||
|
||||
---
|
||||
|
||||
## 2. Android Typography
|
||||
|
||||
### Roboto Font Family
|
||||
|
||||
```
|
||||
Android System Fonts:
|
||||
├── Roboto: Default sans-serif
|
||||
├── Roboto Flex: Variable font (API 33+)
|
||||
├── Roboto Serif: Serif alternative
|
||||
├── Roboto Mono: Monospace
|
||||
└── Google Sans: Google products (special license)
|
||||
```
|
||||
|
||||
### Material Type Scale
|
||||
|
||||
| Role | Size | Weight | Line Height | Usage |
|
||||
|------|------|--------|-------------|-------|
|
||||
| **Display Large** | 57sp | Regular | 64sp | Hero text, splash |
|
||||
| **Display Medium** | 45sp | Regular | 52sp | Large headers |
|
||||
| **Display Small** | 36sp | Regular | 44sp | Medium headers |
|
||||
| **Headline Large** | 32sp | Regular | 40sp | Page titles |
|
||||
| **Headline Medium** | 28sp | Regular | 36sp | Section headers |
|
||||
| **Headline Small** | 24sp | Regular | 32sp | Subsections |
|
||||
| **Title Large** | 22sp | Regular | 28sp | Dialogs, cards |
|
||||
| **Title Medium** | 16sp | Medium | 24sp | Lists, navigation |
|
||||
| **Title Small** | 14sp | Medium | 20sp | Tabs, secondary |
|
||||
| **Body Large** | 16sp | Regular | 24sp | Primary content |
|
||||
| **Body Medium** | 14sp | Regular | 20sp | Secondary content |
|
||||
| **Body Small** | 12sp | Regular | 16sp | Captions |
|
||||
| **Label Large** | 14sp | Medium | 20sp | Buttons, FAB |
|
||||
| **Label Medium** | 12sp | Medium | 16sp | Navigation |
|
||||
| **Label Small** | 11sp | Medium | 16sp | Chips, badges |
|
||||
|
||||
### Scalable Pixels (sp)
|
||||
|
||||
```
|
||||
sp = Scale-independent pixels
|
||||
|
||||
sp automatically scales with:
|
||||
├── User font size preference
|
||||
├── Display density
|
||||
└── Accessibility settings
|
||||
|
||||
RULE: ALWAYS use sp for text, dp for everything else.
|
||||
```
|
||||
|
||||
### Font Weight Usage
|
||||
|
||||
| Weight | Use Case |
|
||||
|--------|----------|
|
||||
| Regular (400) | Body text, display |
|
||||
| Medium (500) | Buttons, labels, emphasis |
|
||||
| Bold (700) | Rarely, strong emphasis only |
|
||||
|
||||
---
|
||||
|
||||
## 3. Material Color System
|
||||
|
||||
### Dynamic Color (Material You)
|
||||
|
||||
```
|
||||
Android 12+ Dynamic Color:
|
||||
|
||||
User's wallpaper → Color extraction → App theme
|
||||
|
||||
Your app automatically adapts to:
|
||||
├── Primary color (from wallpaper)
|
||||
├── Secondary color (complementary)
|
||||
├── Tertiary color (accent)
|
||||
├── Surface colors (derived)
|
||||
└── All semantic colors adjust
|
||||
|
||||
RULE: Implement dynamic color for personalized feel.
|
||||
```
|
||||
|
||||
### Semantic Color Roles
|
||||
|
||||
```
|
||||
Surface Colors:
|
||||
├── Surface → Main background
|
||||
├── SurfaceVariant → Cards, containers
|
||||
├── SurfaceTint → Elevation overlay
|
||||
├── InverseSurface → Snackbars, tooltips
|
||||
|
||||
On-Surface Colors:
|
||||
├── OnSurface → Primary text
|
||||
├── OnSurfaceVariant → Secondary text
|
||||
├── Outline → Borders, dividers
|
||||
├── OutlineVariant → Subtle dividers
|
||||
|
||||
Primary Colors:
|
||||
├── Primary → Key actions, FAB
|
||||
├── OnPrimary → Text on primary
|
||||
├── PrimaryContainer → Less emphasis
|
||||
├── OnPrimaryContainer → Text on container
|
||||
|
||||
Secondary/Tertiary: Similar pattern
|
||||
```
|
||||
|
||||
### Error, Warning, Success Colors
|
||||
|
||||
| Role | Light | Dark | Usage |
|
||||
|------|-------|------|-------|
|
||||
| Error | #B3261E | #F2B8B5 | Errors, destructive |
|
||||
| OnError | #FFFFFF | #601410 | Text on error |
|
||||
| ErrorContainer | #F9DEDC | #8C1D18 | Error backgrounds |
|
||||
|
||||
### Dark Theme
|
||||
|
||||
```
|
||||
Material Dark Theme:
|
||||
|
||||
├── Background: #121212 (not pure black by default)
|
||||
├── Surface: #1E1E1E, #232323, etc. (elevation)
|
||||
├── Elevation: Higher = lighter overlay
|
||||
├── Reduce saturation on colors
|
||||
└── Check contrast ratios
|
||||
|
||||
Elevation overlays (dark mode):
|
||||
├── 0dp → 0% overlay
|
||||
├── 1dp → 5% overlay
|
||||
├── 3dp → 8% overlay
|
||||
├── 6dp → 11% overlay
|
||||
├── 8dp → 12% overlay
|
||||
├── 12dp → 14% overlay
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Android Layout & Spacing
|
||||
|
||||
### Layout Grid
|
||||
|
||||
```
|
||||
Android uses 8dp baseline grid:
|
||||
|
||||
All spacing in multiples of 8dp:
|
||||
├── 4dp: Component internal (half-step)
|
||||
├── 8dp: Minimum spacing
|
||||
├── 16dp: Standard spacing
|
||||
├── 24dp: Section spacing
|
||||
├── 32dp: Large spacing
|
||||
|
||||
Margins:
|
||||
├── Compact (phone): 16dp
|
||||
├── Medium (small tablet): 24dp
|
||||
├── Expanded (large): 24dp+ or columns
|
||||
```
|
||||
|
||||
### Responsive Layout
|
||||
|
||||
```
|
||||
Window Size Classes:
|
||||
|
||||
COMPACT (< 600dp width):
|
||||
├── Phones in portrait
|
||||
├── Single column layout
|
||||
├── Bottom navigation
|
||||
|
||||
MEDIUM (600-840dp width):
|
||||
├── Tablets, foldables
|
||||
├── Consider 2 columns
|
||||
├── Navigation rail option
|
||||
|
||||
EXPANDED (> 840dp width):
|
||||
├── Large tablets, desktop
|
||||
├── Multi-column layouts
|
||||
├── Navigation drawer
|
||||
```
|
||||
|
||||
### Canonical Layouts
|
||||
|
||||
| Layout | Use Case | Window Class |
|
||||
|--------|----------|--------------|
|
||||
| **List-Detail** | Email, messages | Medium, Expanded |
|
||||
| **Feed** | Social, news | All |
|
||||
| **Supporting Pane** | Reference content | Medium, Expanded |
|
||||
|
||||
---
|
||||
|
||||
## 5. Android Navigation Patterns
|
||||
|
||||
### Navigation Components
|
||||
|
||||
| Component | Use Case | Position |
|
||||
|-----------|----------|----------|
|
||||
| **Bottom Navigation** | 3-5 top-level destinations | Bottom |
|
||||
| **Navigation Rail** | Tablets, foldables | Left side, vertical |
|
||||
| **Navigation Drawer** | Many destinations, large screens | Left side, hidden/visible |
|
||||
| **Top App Bar** | Current context, actions | Top |
|
||||
|
||||
### Bottom Navigation
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ │
|
||||
│ Content Area │
|
||||
│ │
|
||||
├─────────────────────────────────────┤
|
||||
│ 🏠 🔍 ➕ ❤️ 👤 │ ← 80dp height
|
||||
│ Home Search FAB Saved Profile│
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Rules:
|
||||
├── 3-5 destinations
|
||||
├── Icons: Material Symbols (24dp)
|
||||
├── Labels: Always visible (accessibility)
|
||||
├── Active: Filled icon + indicator pill
|
||||
├── Badge: For notifications
|
||||
├── FAB can integrate (optional)
|
||||
```
|
||||
|
||||
### Top App Bar
|
||||
|
||||
```
|
||||
Types:
|
||||
├── Center-aligned: Logo apps, simple
|
||||
├── Small: Compact, scrolls away
|
||||
├── Medium: Title + actions, collapses
|
||||
├── Large: Display title, collapses to small
|
||||
|
||||
┌─────────────────────────────────────┐
|
||||
│ ☰ App Title 🔔 ⋮ │ ← 64dp (small)
|
||||
├─────────────────────────────────────┤
|
||||
│ │
|
||||
│ Content Area │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Actions: Max 3 icons, overflow menu ( ⋮ ) for more
|
||||
```
|
||||
|
||||
### Navigation Rail (Tablets)
|
||||
|
||||
```
|
||||
┌───────┬─────────────────────────────┐
|
||||
│ ≡ │ │
|
||||
│ │ │
|
||||
│ 🏠 │ │
|
||||
│ Home │ Content Area │
|
||||
│ │ │
|
||||
│ 🔍 │ │
|
||||
│Search │ │
|
||||
│ │ │
|
||||
│ 👤 │ │
|
||||
│Profile│ │
|
||||
└───────┴─────────────────────────────┘
|
||||
|
||||
Width: 80dp
|
||||
Icons: 24dp
|
||||
Labels: Below icon
|
||||
FAB: Can be at top
|
||||
```
|
||||
|
||||
### Back Navigation
|
||||
|
||||
```
|
||||
Android provides system back:
|
||||
├── Back button (3-button nav)
|
||||
├── Back gesture (swipe from edge)
|
||||
├── Predictive back (Android 14+)
|
||||
|
||||
Your app must:
|
||||
├── Handle back correctly (pop stack)
|
||||
├── Support predictive back animation
|
||||
├── Never hijack/override back unexpectedly
|
||||
└── Confirm before discarding unsaved work
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Material Components
|
||||
|
||||
### Buttons
|
||||
|
||||
```
|
||||
Button Types:
|
||||
|
||||
┌──────────────────────┐
|
||||
│ Filled Button │ ← Primary action
|
||||
└──────────────────────┘
|
||||
|
||||
┌──────────────────────┐
|
||||
│ Tonal Button │ ← Secondary, less emphasis
|
||||
└──────────────────────┘
|
||||
|
||||
┌──────────────────────┐
|
||||
│ Outlined Button │ ← Tertiary, lower emphasis
|
||||
└──────────────────────┘
|
||||
|
||||
Text Button ← Lowest emphasis
|
||||
|
||||
Heights:
|
||||
├── Small: 40dp (when constrained)
|
||||
├── Standard: 40dp
|
||||
├── Large: 56dp (FAB size when needed)
|
||||
|
||||
Min touch target: 48dp (even if visual is smaller)
|
||||
```
|
||||
|
||||
### Floating Action Button (FAB)
|
||||
|
||||
```
|
||||
FAB Types:
|
||||
├── Standard: 56dp diameter
|
||||
├── Small: 40dp diameter
|
||||
├── Large: 96dp diameter
|
||||
├── Extended: Icon + text, variable width
|
||||
|
||||
Position: Bottom right, 16dp from edges
|
||||
Elevation: Floats above content
|
||||
|
||||
┌─────────────────────────────────────┐
|
||||
│ │
|
||||
│ Content │
|
||||
│ │
|
||||
│ ┌────┐ │
|
||||
│ │ ➕ │ │ ← FAB
|
||||
│ └────┘ │
|
||||
├─────────────────────────────────────┤
|
||||
│ Bottom Navigation │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Cards
|
||||
|
||||
```
|
||||
Card Types:
|
||||
├── Elevated: Shadow, resting state
|
||||
├── Filled: Background color, no shadow
|
||||
├── Outlined: Border, no shadow
|
||||
|
||||
Card Anatomy:
|
||||
┌─────────────────────────────────────┐
|
||||
│ Header Image │ ← Optional
|
||||
├─────────────────────────────────────┤
|
||||
│ Title / Headline │
|
||||
│ Subhead / Supporting text │
|
||||
├─────────────────────────────────────┤
|
||||
│ [ Action ] [ Action ] │ ← Optional actions
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Corner radius: 12dp (M3 default)
|
||||
Padding: 16dp
|
||||
```
|
||||
|
||||
### Text Fields
|
||||
|
||||
```
|
||||
Types:
|
||||
├── Filled: Background fill, underline
|
||||
├── Outlined: Border all around
|
||||
|
||||
┌─────────────────────────────────────┐
|
||||
│ Label │ ← Floats up on focus
|
||||
│ ________________________________________________
|
||||
│ │ Input text here... │ ← Leading/trailing icons
|
||||
│ ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
│ Supporting text or error │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Height: 56dp
|
||||
Label: Animates from placeholder to top
|
||||
Error: Red color + icon + message
|
||||
```
|
||||
|
||||
### Chips
|
||||
|
||||
```
|
||||
Types:
|
||||
├── Assist: Smart actions (directions, call)
|
||||
├── Filter: Toggle filters
|
||||
├── Input: Represent entities (tags, contacts)
|
||||
├── Suggestion: Dynamic recommendations
|
||||
|
||||
┌───────────────┐
|
||||
│ 🏷️ Filter │ ← 32dp height, 8dp corner radius
|
||||
└───────────────┘
|
||||
|
||||
States: Unselected, Selected, Disabled
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Android-Specific Patterns
|
||||
|
||||
### Snackbars
|
||||
|
||||
```
|
||||
Position: Bottom, above navigation
|
||||
Duration: 4-10 seconds
|
||||
Action: One optional text action
|
||||
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ Archived 1 item [ UNDO ] │
|
||||
└─────────────────────────────────────────────────┘
|
||||
|
||||
Rules:
|
||||
├── Brief message, single line if possible
|
||||
├── Max 2 lines
|
||||
├── One action (text, not icon)
|
||||
├── Can be dismissed by swipe
|
||||
└── Don't stack, queue them
|
||||
```
|
||||
|
||||
### Bottom Sheets
|
||||
|
||||
```
|
||||
Types:
|
||||
├── Standard: Interactive content
|
||||
├── Modal: Blocks background (with scrim)
|
||||
|
||||
Modal Bottom Sheet:
|
||||
┌─────────────────────────────────────┐
|
||||
│ │
|
||||
│ (Scrim over content) │
|
||||
│ │
|
||||
├═════════════════════════════════════┤
|
||||
│ ───── (Drag handle, optional) │
|
||||
│ │
|
||||
│ Sheet Content │
|
||||
│ │
|
||||
│ Actions / Options │
|
||||
│ │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Corner radius: 28dp (top corners)
|
||||
```
|
||||
|
||||
### Dialogs
|
||||
|
||||
```
|
||||
Types:
|
||||
├── Basic: Title + content + actions
|
||||
├── Full-screen: Complex editing (mobile)
|
||||
├── Date/Time picker
|
||||
├── Confirmation dialog
|
||||
|
||||
┌─────────────────────────────────────┐
|
||||
│ Title │
|
||||
│ │
|
||||
│ Supporting text that │
|
||||
│ explains the dialog │
|
||||
│ │
|
||||
│ [ Cancel ] [ Confirm ] │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Rules:
|
||||
├── Centered on screen
|
||||
├── Scrim behind (dim background)
|
||||
├── Max 2 actions aligned right
|
||||
├── Destructive action can be on left
|
||||
```
|
||||
|
||||
### Pull to Refresh
|
||||
|
||||
```
|
||||
Android uses SwipeRefreshLayout pattern:
|
||||
|
||||
┌─────────────────────────────────────┐
|
||||
│ ○ (Spinner) │ ← Circular progress
|
||||
├─────────────────────────────────────┤
|
||||
│ │
|
||||
│ Content │
|
||||
│ │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Spinner: Material circular indicator
|
||||
Position: Top center, pulls down with content
|
||||
```
|
||||
|
||||
### Ripple Effect
|
||||
|
||||
```
|
||||
Every touchable element needs ripple:
|
||||
|
||||
Touch down → Ripple expands from touch point
|
||||
Touch up → Ripple completes and fades
|
||||
|
||||
Color:
|
||||
├── On light: Black at ~12% opacity
|
||||
├── On dark: White at ~12% opacity
|
||||
├── On colored: Appropriate contrast
|
||||
|
||||
This is MANDATORY for Android feel.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Material Symbols
|
||||
|
||||
### Usage Guidelines
|
||||
|
||||
```
|
||||
Material Symbols: Google's icon library
|
||||
|
||||
Styles:
|
||||
├── Outlined: Default, most common
|
||||
├── Rounded: Softer, friendly
|
||||
├── Sharp: Angular, precise
|
||||
|
||||
Variable font axes:
|
||||
├── FILL: 0 (outline) to 1 (filled)
|
||||
├── wght: 100-700 (weight)
|
||||
├── GRAD: -25 to 200 (emphasis)
|
||||
├── opsz: 20, 24, 40, 48 (optical size)
|
||||
```
|
||||
|
||||
### Icon Sizes
|
||||
|
||||
| Size | Usage |
|
||||
|------|-------|
|
||||
| 20dp | Dense UI, inline |
|
||||
| 24dp | Standard (most common) |
|
||||
| 40dp | Larger touch targets |
|
||||
| 48dp | Emphasis, standalone |
|
||||
|
||||
### States
|
||||
|
||||
```
|
||||
Icon States:
|
||||
├── Default: Full opacity
|
||||
├── Disabled: 38% opacity
|
||||
├── Hover/Focus: Container highlight
|
||||
├── Selected: Filled variant + tint
|
||||
|
||||
Active vs Inactive:
|
||||
├── Inactive: Outlined
|
||||
├── Active: Filled + indicator
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Android Accessibility
|
||||
|
||||
### TalkBack Requirements
|
||||
|
||||
```
|
||||
Every interactive element needs:
|
||||
├── contentDescription (what it is)
|
||||
├── Correct semantics (button, checkbox, etc.)
|
||||
├── State announcements (selected, disabled)
|
||||
└── Grouping where logical
|
||||
|
||||
Jetpack Compose:
|
||||
Modifier.semantics {
|
||||
contentDescription = "Play button"
|
||||
role = Role.Button
|
||||
}
|
||||
|
||||
React Native:
|
||||
accessibilityLabel="Play button"
|
||||
accessibilityRole="button"
|
||||
accessibilityState={{ disabled: false }}
|
||||
```
|
||||
|
||||
### Touch Target Size
|
||||
|
||||
```
|
||||
MANDATORY: 48dp × 48dp minimum
|
||||
|
||||
Even if visual element is smaller:
|
||||
├── Icon: 24dp visual, 48dp touch area
|
||||
├── Checkbox: 20dp visual, 48dp touch area
|
||||
└── Add padding to reach 48dp
|
||||
|
||||
Spacing between targets: 8dp minimum
|
||||
```
|
||||
|
||||
### Font Scaling
|
||||
|
||||
```
|
||||
Android supports font scaling:
|
||||
├── 85% (smaller)
|
||||
├── 100% (default)
|
||||
├── 115%, 130%, 145%...
|
||||
├── Up to 200% (largest)
|
||||
|
||||
RULE: Test your UI at 200% font scale.
|
||||
Use sp units and avoid fixed heights.
|
||||
```
|
||||
|
||||
### Reduce Motion
|
||||
|
||||
```kotlin
|
||||
// Check motion preference
|
||||
val reduceMotion = Settings.Global.getFloat(
|
||||
contentResolver,
|
||||
Settings.Global.ANIMATOR_DURATION_SCALE,
|
||||
1f
|
||||
) == 0f
|
||||
|
||||
if (reduceMotion) {
|
||||
// Skip or reduce animations
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Android Checklist
|
||||
|
||||
### Before Every Android Screen
|
||||
|
||||
- [ ] Using Material 3 components
|
||||
- [ ] Touch targets ≥ 48dp
|
||||
- [ ] Ripple effect on all touchables
|
||||
- [ ] Roboto or Material type scale
|
||||
- [ ] Semantic colors (dynamic color support)
|
||||
- [ ] Back navigation works correctly
|
||||
|
||||
### Before Android Release
|
||||
|
||||
- [ ] Dark theme tested
|
||||
- [ ] Dynamic color tested (if supported)
|
||||
- [ ] All font sizes tested (200% scale)
|
||||
- [ ] TalkBack tested
|
||||
- [ ] Predictive back implemented (Android 14+)
|
||||
- [ ] Edge-to-edge display (Android 15+)
|
||||
- [ ] Different screen sizes tested (phones, tablets)
|
||||
- [ ] Navigation patterns match platform (back, gestures)
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Android users expect Material Design. Custom designs that ignore Material patterns feel foreign and broken. Use Material components as your foundation, customize thoughtfully.
|
||||
561
skills/mobile-design/platform-ios.md
Normal file
561
skills/mobile-design/platform-ios.md
Normal file
@@ -0,0 +1,561 @@
|
||||
# iOS Platform Guidelines
|
||||
|
||||
> Human Interface Guidelines (HIG) essentials, iOS design conventions, SF Pro typography, and native patterns.
|
||||
> **Read this file when building for iPhone/iPad.**
|
||||
|
||||
---
|
||||
|
||||
## 1. Human Interface Guidelines Philosophy
|
||||
|
||||
### Core Apple Design Principles
|
||||
|
||||
```
|
||||
CLARITY:
|
||||
├── Text is legible at every size
|
||||
├── Icons are precise and lucid
|
||||
├── Adornments are subtle and appropriate
|
||||
└── Focus on functionality drives design
|
||||
|
||||
DEFERENCE:
|
||||
├── UI helps people understand and interact
|
||||
├── Content fills the screen
|
||||
├── UI never competes with content
|
||||
└── Translucency hints at more content
|
||||
|
||||
DEPTH:
|
||||
├── Distinct visual layers convey hierarchy
|
||||
├── Transitions provide sense of depth
|
||||
├── Touch reveals functionality
|
||||
└── Content is elevated over UI
|
||||
```
|
||||
|
||||
### iOS Design Values
|
||||
|
||||
| Value | Implementation |
|
||||
|-------|----------------|
|
||||
| **Aesthetic Integrity** | Design matches function (game ≠ productivity) |
|
||||
| **Consistency** | Use system controls, familiar patterns |
|
||||
| **Direct Manipulation** | Touch directly affects content |
|
||||
| **Feedback** | Actions are acknowledged |
|
||||
| **Metaphors** | Real-world comparisons aid understanding |
|
||||
| **User Control** | User initiates actions, can cancel |
|
||||
|
||||
---
|
||||
|
||||
## 2. iOS Typography
|
||||
|
||||
### SF Pro Font Family
|
||||
|
||||
```
|
||||
iOS System Fonts:
|
||||
├── SF Pro Text: Body text (< 20pt)
|
||||
├── SF Pro Display: Large titles (≥ 20pt)
|
||||
├── SF Pro Rounded: Friendly contexts
|
||||
├── SF Mono: Code, tabular data
|
||||
└── SF Compact: Apple Watch, smaller screens
|
||||
```
|
||||
|
||||
### iOS Type Scale (Dynamic Type)
|
||||
|
||||
| Style | Default Size | Weight | Usage |
|
||||
|-------|--------------|--------|-------|
|
||||
| **Large Title** | 34pt | Bold | Navigation bar (scroll collapse) |
|
||||
| **Title 1** | 28pt | Bold | Page titles |
|
||||
| **Title 2** | 22pt | Bold | Section headers |
|
||||
| **Title 3** | 20pt | Semibold | Subsection headers |
|
||||
| **Headline** | 17pt | Semibold | Emphasized body |
|
||||
| **Body** | 17pt | Regular | Primary content |
|
||||
| **Callout** | 16pt | Regular | Secondary content |
|
||||
| **Subhead** | 15pt | Regular | Tertiary content |
|
||||
| **Footnote** | 13pt | Regular | Caption, timestamps |
|
||||
| **Caption 1** | 12pt | Regular | Annotations |
|
||||
| **Caption 2** | 11pt | Regular | Fine print |
|
||||
|
||||
### Dynamic Type Support (MANDATORY)
|
||||
|
||||
```swift
|
||||
// ❌ WRONG: Fixed font size
|
||||
Text("Hello")
|
||||
.font(.system(size: 17))
|
||||
|
||||
// ✅ CORRECT: Dynamic Type
|
||||
Text("Hello")
|
||||
.font(.body) // Scales with user settings
|
||||
|
||||
// React Native equivalent
|
||||
<Text style={{ fontSize: 17 }}> // ❌ Fixed
|
||||
<Text style={styles.body}> // Use a dynamic scale system
|
||||
```
|
||||
|
||||
### Font Weight Usage
|
||||
|
||||
| Weight | iOS Constant | Use Case |
|
||||
|--------|--------------|----------|
|
||||
| Regular (400) | `.regular` | Body text |
|
||||
| Medium (500) | `.medium` | Buttons, emphasis |
|
||||
| Semibold (600) | `.semibold` | Subheadings |
|
||||
| Bold (700) | `.bold` | Titles, key info |
|
||||
| Heavy (800) | `.heavy` | Rarely, marketing |
|
||||
|
||||
---
|
||||
|
||||
## 3. iOS Color System
|
||||
|
||||
### System Colors (Semantic)
|
||||
|
||||
```
|
||||
Use semantic colors for automatic dark mode:
|
||||
|
||||
Primary:
|
||||
├── .label → Primary text
|
||||
├── .secondaryLabel → Secondary text
|
||||
├── .tertiaryLabel → Tertiary text
|
||||
├── .quaternaryLabel → Watermarks
|
||||
|
||||
Backgrounds:
|
||||
├── .systemBackground → Main background
|
||||
├── .secondarySystemBackground → Grouped content
|
||||
├── .tertiarySystemBackground → Elevated content
|
||||
|
||||
Fills:
|
||||
├── .systemFill → Large shapes
|
||||
├── .secondarySystemFill → Medium shapes
|
||||
├── .tertiarySystemFill → Small shapes
|
||||
├── .quaternarySystemFill → Subtle shapes
|
||||
```
|
||||
|
||||
### System Accent Colors
|
||||
|
||||
| Color | Light Mode | Dark Mode | Usage |
|
||||
|-------|------------|-----------|-------|
|
||||
| Blue | #007AFF | #0A84FF | Links, highlights, default tint |
|
||||
| Green | #34C759 | #30D158 | Success, positive |
|
||||
| Red | #FF3B30 | #FF453A | Errors, destructive |
|
||||
| Orange | #FF9500 | #FF9F0A | Warnings |
|
||||
| Yellow | #FFCC00 | #FFD60A | Attention |
|
||||
| Purple | #AF52DE | #BF5AF2 | Special features |
|
||||
| Pink | #FF2D55 | #FF375F | Affection, favorites |
|
||||
| Teal | #5AC8FA | #64D2FF | Information |
|
||||
|
||||
### Dark Mode Considerations
|
||||
|
||||
```
|
||||
iOS Dark Mode is not inverted light mode:
|
||||
|
||||
LIGHT MODE: DARK MODE:
|
||||
├── White backgrounds ├── True black (#000) or near-black
|
||||
├── High saturation ├── Desaturated colors
|
||||
├── Black text ├── White/light gray text
|
||||
└── Drop shadows └── Glows or no shadows
|
||||
|
||||
RULE: Always use semantic colors for automatic adaptation.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. iOS Layout & Spacing
|
||||
|
||||
### Safe Areas
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│░░░░░░░░░░░ Status Bar ░░░░░░░░░░░░░│ ← Top safe area inset
|
||||
├─────────────────────────────────────┤
|
||||
│ │
|
||||
│ │
|
||||
│ Safe Content Area │
|
||||
│ │
|
||||
│ │
|
||||
├─────────────────────────────────────┤
|
||||
│░░░░░░░░░ Home Indicator ░░░░░░░░░░░│ ← Bottom safe area inset
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
RULE: Never place interactive content in unsafe areas.
|
||||
```
|
||||
|
||||
### Standard Margins & Padding
|
||||
|
||||
| Element | Margin | Notes |
|
||||
|---------|--------|-------|
|
||||
| Screen edge → content | 16pt | Standard horizontal margin |
|
||||
| Grouped table sections | 16pt top/bottom | Breathing room |
|
||||
| List item padding | 16pt horizontal | Standard cell padding |
|
||||
| Card internal padding | 16pt | Content within cards |
|
||||
| Button internal padding | 12pt vertical, 16pt horizontal | Minimum |
|
||||
|
||||
### iOS Grid System
|
||||
|
||||
```
|
||||
iPhone Grid (Standard):
|
||||
├── 16pt margins (left/right)
|
||||
├── 8pt minimum spacing
|
||||
├── Content in 8pt multiples
|
||||
|
||||
iPhone Grid (Compact):
|
||||
├── 8pt margins (when needed)
|
||||
├── 4pt minimum spacing
|
||||
|
||||
iPad Grid:
|
||||
├── 20pt margins (or more)
|
||||
├── Consider multi-column layouts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. iOS Navigation Patterns
|
||||
|
||||
### Navigation Types
|
||||
|
||||
| Pattern | Use Case | Implementation |
|
||||
|---------|----------|----------------|
|
||||
| **Tab Bar** | 3-5 top-level sections | Bottom, always visible |
|
||||
| **Navigation Controller** | Hierarchical drill-down | Stack-based, back button |
|
||||
| **Modal** | Focused task, interruption | Sheet or full-screen |
|
||||
| **Sidebar** | iPad, multi-column | Left sidebar (iPad) |
|
||||
|
||||
### Tab Bar Guidelines
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ │
|
||||
│ Content Area │
|
||||
│ │
|
||||
├─────────────────────────────────────┤
|
||||
│ 🏠 🔍 ➕ ❤️ 👤 │ ← Tab bar (49pt height)
|
||||
│ Home Search New Saved Profile │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Rules:
|
||||
├── 3-5 items maximum
|
||||
├── Icons: SF Symbols or custom (25×25pt)
|
||||
├── Labels: Always include (accessibility)
|
||||
├── Active state: Filled icon + tint color
|
||||
└── Tab bar always visible (don't hide on scroll)
|
||||
```
|
||||
|
||||
### Navigation Bar Guidelines
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ < Back Page Title Edit │ ← Navigation bar (44pt)
|
||||
├─────────────────────────────────────┤
|
||||
│ │
|
||||
│ Content Area │
|
||||
│ │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Rules:
|
||||
├── Back button: System chevron + previous title (or "Back")
|
||||
├── Title: Centered, dynamic font
|
||||
├── Right actions: Max 2 items
|
||||
├── Large title: Collapses on scroll (optional)
|
||||
└── Prefer text buttons over icons (clarity)
|
||||
```
|
||||
|
||||
### Modal Presentations
|
||||
|
||||
| Style | Use Case | Appearance |
|
||||
|-------|----------|------------|
|
||||
| **Sheet (default)** | Secondary tasks | Card slides up, parent visible |
|
||||
| **Full Screen** | Immersive tasks | Covers entire screen |
|
||||
| **Popover** | iPad, quick info | Arrow-pointed bubble |
|
||||
| **Alert** | Critical interruption | Centered dialog |
|
||||
| **Action Sheet** | Choices from context | Bottom sheet with options |
|
||||
|
||||
### Gestures
|
||||
|
||||
| Gesture | iOS Convention |
|
||||
|---------|----------------|
|
||||
| **Edge swipe (left)** | Navigate back |
|
||||
| **Pull down (sheet)** | Dismiss modal |
|
||||
| **Long press** | Context menu |
|
||||
| **Deep press** | Peek/Pop (legacy) |
|
||||
| **Two-finger swipe** | Scroll in nested scroll |
|
||||
|
||||
---
|
||||
|
||||
## 6. iOS Components
|
||||
|
||||
### Buttons
|
||||
|
||||
```
|
||||
Button Styles (UIKit/SwiftUI):
|
||||
|
||||
┌──────────────────────────────┐
|
||||
│ Tinted │ ← Primary action (filled)
|
||||
├──────────────────────────────┤
|
||||
│ Bordered │ ← Secondary action (outline)
|
||||
├──────────────────────────────┤
|
||||
│ Plain │ ← Tertiary action (text only)
|
||||
└──────────────────────────────┘
|
||||
|
||||
Sizes:
|
||||
├── Mini: Tight spaces
|
||||
├── Small: Compact UI
|
||||
├── Medium: Inline actions
|
||||
├── Large: Primary CTAs (44pt minimum height)
|
||||
```
|
||||
|
||||
### Lists & Tables
|
||||
|
||||
```
|
||||
List Styles:
|
||||
|
||||
.plain → No separators, edge-to-edge
|
||||
.insetGrouped → Rounded cards (default iOS 14+)
|
||||
.grouped → Full-width sections
|
||||
.sidebar → iPad sidebar navigation
|
||||
|
||||
Cell Accessories:
|
||||
├── Disclosure indicator (>) → Navigates to detail
|
||||
├── Detail button (i) → Shows info without navigation
|
||||
├── Checkmark (✓) → Selection
|
||||
├── Reorder (≡) → Drag to reorder
|
||||
└── Delete (-) → Swipe/edit mode delete
|
||||
```
|
||||
|
||||
### Text Fields
|
||||
|
||||
```
|
||||
iOS Text Field Anatomy:
|
||||
|
||||
┌─────────────────────────────────────┐
|
||||
│ 🔍 Search... ✕ │
|
||||
└─────────────────────────────────────┘
|
||||
↑ ↑
|
||||
Leading icon Clear button
|
||||
|
||||
Borders: Rounded rectangle
|
||||
Height: 36pt minimum
|
||||
Placeholder: Secondary text color
|
||||
Clear button: Appears when has text
|
||||
```
|
||||
|
||||
### Segmented Controls
|
||||
|
||||
```
|
||||
When to Use:
|
||||
├── 2-5 related options
|
||||
├── Filter content
|
||||
├── Switch views
|
||||
|
||||
┌───────┬───────┬───────┐
|
||||
│ All │ Active│ Done │
|
||||
└───────┴───────┴───────┘
|
||||
|
||||
Rules:
|
||||
├── Equal width segments
|
||||
├── Text or icons (not both mixed)
|
||||
├── Max 5 segments
|
||||
└── Consider tabs if more complex
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. iOS Specific Patterns
|
||||
|
||||
### Pull to Refresh
|
||||
|
||||
```
|
||||
Native UIRefreshControl behavior:
|
||||
├── Pull beyond threshold → Spinner appears
|
||||
├── Release → Refresh action triggered
|
||||
├── Loading state → Spinner spins
|
||||
├── Complete → Spinner disappears
|
||||
|
||||
RULE: Always use native UIRefreshControl (don't custom build).
|
||||
```
|
||||
|
||||
### Swipe Actions
|
||||
|
||||
```
|
||||
iOS swipe actions:
|
||||
|
||||
← Swipe Left (Destructive) Swipe Right (Constructive) →
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ List Item Content │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
Left swipe reveals: Archive, Delete, Flag
|
||||
Right swipe reveals: Pin, Star, Mark as Read
|
||||
|
||||
Full swipe: Triggers first action
|
||||
```
|
||||
|
||||
### Context Menus
|
||||
|
||||
```
|
||||
Long press → Context menu appears
|
||||
|
||||
┌─────────────────────────────┐
|
||||
│ Preview Card │
|
||||
├─────────────────────────────┤
|
||||
│ 📋 Copy │
|
||||
│ 📤 Share │
|
||||
│ ➕ Add to... │
|
||||
├─────────────────────────────┤
|
||||
│ 🗑️ Delete (Red) │
|
||||
└─────────────────────────────┘
|
||||
|
||||
Rules:
|
||||
├── Preview: Show enlarged content
|
||||
├── Actions: Related to content
|
||||
├── Destructive: Last, in red
|
||||
└── Max ~8 actions (scrollable if more)
|
||||
```
|
||||
|
||||
### Sheets & Half-Sheets
|
||||
|
||||
```
|
||||
iOS 15+ Sheets:
|
||||
|
||||
┌─────────────────────────────────────┐
|
||||
│ │
|
||||
│ Parent View (dimmed) │
|
||||
│ │
|
||||
├─────────────────────────────────────┤
|
||||
│ ═══ (Grabber) │ ← Drag to resize
|
||||
│ │
|
||||
│ Sheet Content │
|
||||
│ │
|
||||
│ │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
Detents:
|
||||
├── .medium → Half screen
|
||||
├── .large → Full screen (with safe area)
|
||||
├── Custom → Specific height
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. SF Symbols
|
||||
|
||||
### Usage Guidelines
|
||||
|
||||
```
|
||||
SF Symbols: Apple's icon library (5000+ icons)
|
||||
|
||||
Weights: Match text weight
|
||||
├── Ultralight / Thin / Light
|
||||
├── Regular / Medium / Semibold
|
||||
├── Bold / Heavy / Black
|
||||
|
||||
Scales:
|
||||
├── .small → Inline with small text
|
||||
├── .medium → Standard UI
|
||||
├── .large → Emphasis, standalone
|
||||
```
|
||||
|
||||
### Symbol Configurations
|
||||
|
||||
```swift
|
||||
// SwiftUI
|
||||
Image(systemName: "star.fill")
|
||||
.font(.title2)
|
||||
.foregroundStyle(.yellow)
|
||||
|
||||
// With rendering mode
|
||||
Image(systemName: "heart.fill")
|
||||
.symbolRenderingMode(.multicolor)
|
||||
|
||||
// Animated (iOS 17+)
|
||||
Image(systemName: "checkmark.circle")
|
||||
.symbolEffect(.bounce)
|
||||
```
|
||||
|
||||
### Symbol Best Practices
|
||||
|
||||
| Guideline | Implementation |
|
||||
|-----------|----------------|
|
||||
| Match text weight | Symbol weight = font weight |
|
||||
| Use standard symbols | Users recognize them |
|
||||
| Multicolor when meaningful | Not just decoration |
|
||||
| Fallback for older iOS | Check availability |
|
||||
|
||||
---
|
||||
|
||||
## 9. iOS Accessibility
|
||||
|
||||
### VoiceOver Requirements
|
||||
|
||||
```
|
||||
Every interactive element needs:
|
||||
├── Accessibility label (what it is)
|
||||
├── Accessibility hint (what it does) - optional
|
||||
├── Accessibility traits (button, link, etc.)
|
||||
└── Accessibility value (current state)
|
||||
|
||||
SwiftUI:
|
||||
.accessibilityLabel("Play")
|
||||
.accessibilityHint("Plays the selected track")
|
||||
|
||||
React Native:
|
||||
accessibilityLabel="Play"
|
||||
accessibilityHint="Plays the selected track"
|
||||
accessibilityRole="button"
|
||||
```
|
||||
|
||||
### Dynamic Type Scaling
|
||||
|
||||
```
|
||||
MANDATORY: Support Dynamic Type
|
||||
|
||||
Users can set text size from:
|
||||
├── xSmall → 14pt body
|
||||
├── Small → 15pt body
|
||||
├── Medium → 16pt body
|
||||
├── Large (Default) → 17pt body
|
||||
├── xLarge → 19pt body
|
||||
├── xxLarge → 21pt body
|
||||
├── xxxLarge → 23pt body
|
||||
├── Accessibility sizes → up to 53pt
|
||||
|
||||
Your app MUST scale gracefully at all sizes.
|
||||
```
|
||||
|
||||
### Reduce Motion
|
||||
|
||||
```
|
||||
Respect motion preferences:
|
||||
|
||||
@Environment(\.accessibilityReduceMotion) var reduceMotion
|
||||
|
||||
if reduceMotion {
|
||||
// Use instant transitions
|
||||
} else {
|
||||
// Use animations
|
||||
}
|
||||
|
||||
React Native:
|
||||
import { AccessibilityInfo } from 'react-native';
|
||||
AccessibilityInfo.isReduceMotionEnabled()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. iOS Checklist
|
||||
|
||||
### Before Every iOS Screen
|
||||
|
||||
- [ ] Using SF Pro or SF Symbols
|
||||
- [ ] Dynamic Type supported
|
||||
- [ ] Safe areas respected
|
||||
- [ ] Navigation follows HIG (back gesture works)
|
||||
- [ ] Tab bar items ≤ 5
|
||||
- [ ] Touch targets ≥ 44pt
|
||||
|
||||
### Before iOS Release
|
||||
|
||||
- [ ] Dark mode tested
|
||||
- [ ] All text sizes tested (Accessibility Inspector)
|
||||
- [ ] VoiceOver tested
|
||||
- [ ] Edge swipe back works everywhere
|
||||
- [ ] Keyboard avoidance implemented
|
||||
- [ ] Notch/Dynamic Island handled
|
||||
- [ ] Home indicator area respected
|
||||
- [ ] Native components used where possible
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** iOS users have strong expectations from other iOS apps. Deviating from HIG patterns feels "broken" to them. When in doubt, use the native component.
|
||||
670
skills/mobile-design/scripts/mobile_audit.py
Normal file
670
skills/mobile-design/scripts/mobile_audit.py
Normal file
@@ -0,0 +1,670 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Mobile UX Audit Script - Full Mobile Design Coverage
|
||||
|
||||
Analyzes React Native / Flutter code for compliance with:
|
||||
|
||||
1. TOUCH PSYCHOLOGY (touch-psychology.md):
|
||||
- Touch Target Sizes (44pt iOS, 48dp Android, 44px WCAG)
|
||||
- Touch Target Spacing (8px minimum gap)
|
||||
- Thumb Zone Placement (primary CTAs at bottom)
|
||||
- Gesture Alternatives (visible buttons for swipe)
|
||||
- Haptic Feedback Patterns
|
||||
- Touch Feedback Timing (<50ms)
|
||||
- Touch Accessibility (motor impairment support)
|
||||
|
||||
2. MOBILE PERFORMANCE (mobile-performance.md):
|
||||
- ScrollView vs FlatList (CRITICAL)
|
||||
- React.memo for List Items
|
||||
- useCallback for renderItem
|
||||
- Stable keyExtractor (NOT index)
|
||||
- useNativeDriver for Animations
|
||||
- Memory Leak Prevention (cleanup)
|
||||
- Console.log Detection
|
||||
- Inline Function Detection
|
||||
- Animation Performance (transform/opacity only)
|
||||
|
||||
3. MOBILE NAVIGATION (mobile-navigation.md):
|
||||
- Tab Bar Max Items (5)
|
||||
- Tab State Preservation
|
||||
- Proper Back Handling
|
||||
- Deep Link Support
|
||||
- Navigation Structure
|
||||
|
||||
4. MOBILE TYPOGRAPHY (mobile-typography.md):
|
||||
- System Font Usage
|
||||
- Dynamic Type Support (iOS)
|
||||
- Text Scaling Constraints
|
||||
- Mobile Line Height
|
||||
- Font Size Limits
|
||||
|
||||
5. MOBILE COLOR SYSTEM (mobile-color-system.md):
|
||||
- Pure Black Avoidance (#000000)
|
||||
- OLED Optimization
|
||||
- Dark Mode Support
|
||||
- Contrast Ratios
|
||||
|
||||
6. PLATFORM iOS (platform-ios.md):
|
||||
- SF Symbols Usage
|
||||
- iOS Navigation Patterns
|
||||
- iOS Haptic Types
|
||||
- iOS-Specific Components
|
||||
|
||||
7. PLATFORM ANDROID (platform-android.md):
|
||||
- Material Icons Usage
|
||||
- Android Navigation Patterns
|
||||
- Ripple Effects
|
||||
- Android-Specific Components
|
||||
|
||||
8. MOBILE BACKEND (mobile-backend.md):
|
||||
- Secure Storage (NOT AsyncStorage)
|
||||
- Offline Handling
|
||||
- Push Notification Support
|
||||
- API Response Caching
|
||||
|
||||
Total: 50+ mobile-specific checks
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
class MobileAuditor:
|
||||
def __init__(self):
|
||||
self.issues = []
|
||||
self.warnings = []
|
||||
self.passed_count = 0
|
||||
self.files_checked = 0
|
||||
|
||||
def audit_file(self, filepath: str) -> None:
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
|
||||
content = f.read()
|
||||
except:
|
||||
return
|
||||
|
||||
self.files_checked += 1
|
||||
filename = os.path.basename(filepath)
|
||||
|
||||
# Detect framework
|
||||
is_react_native = bool(re.search(r'react-native|@react-navigation|React\.Native', content))
|
||||
is_flutter = bool(re.search(r'import \'package:flutter|MaterialApp|Widget\.build', content))
|
||||
|
||||
if not (is_react_native or is_flutter):
|
||||
return # Skip non-mobile files
|
||||
|
||||
# --- 1. TOUCH PSYCHOLOGY CHECKS ---
|
||||
|
||||
# 1.1 Touch Target Size Check
|
||||
# Look for small touch targets
|
||||
small_sizes = re.findall(r'(?:width|height|size):\s*([0-3]\d)', content)
|
||||
for size in small_sizes:
|
||||
if int(size) < 44:
|
||||
self.issues.append(f"[Touch Target] {filename}: Touch target size {size}px < 44px minimum (iOS: 44pt, Android: 48dp)")
|
||||
|
||||
# 1.2 Touch Target Spacing Check
|
||||
# Look for inadequate spacing between touchable elements
|
||||
small_gaps = re.findall(r'(?:margin|gap):\s*([0-7])\s*(?:px|dp)', content)
|
||||
for gap in small_gaps:
|
||||
if int(gap) < 8:
|
||||
self.warnings.append(f"[Touch Spacing] {filename}: Touch target spacing {gap}px < 8px minimum. Accidental taps risk.")
|
||||
|
||||
# 1.3 Thumb Zone Placement Check
|
||||
# Primary CTAs should be at bottom (easy thumb reach)
|
||||
primary_buttons = re.findall(r'(?:testID|id):\s*["\'](?:.*(?:primary|cta|submit|confirm)[^"\']*)["\']', content, re.IGNORECASE)
|
||||
has_bottom_placement = bool(re.search(r'position:\s*["\']?absolute["\']?|bottom:\s*\d+|style.*bottom|justifyContent:\s*["\']?flex-end', content))
|
||||
if primary_buttons and not has_bottom_placement:
|
||||
self.warnings.append(f"[Thumb Zone] {filename}: Primary CTA may not be in thumb zone (bottom). Place primary actions at bottom for easy reach.")
|
||||
|
||||
# 1.4 Gesture Alternatives Check
|
||||
# Swipe actions should have visible button alternatives
|
||||
has_swipe_gestures = bool(re.search(r'Swipeable|onSwipe|PanGestureHandler|swipe', content))
|
||||
has_visible_buttons = bool(re.search(r'Button.*(?:delete|archive|more)|TouchableOpacity|Pressable', content))
|
||||
if has_swipe_gestures and not has_visible_buttons:
|
||||
self.warnings.append(f"[Gestures] {filename}: Swipe gestures detected without visible button alternatives. Motor impaired users need alternatives.")
|
||||
|
||||
# 1.5 Haptic Feedback Check
|
||||
# Important actions should have haptic feedback
|
||||
has_important_actions = bool(re.search(r'(?:onPress|onSubmit|delete|remove|confirm|purchase)', content))
|
||||
has_haptics = bool(re.search(r'Haptics|Vibration|react-native-haptic-feedback|FeedbackManager', content))
|
||||
if has_important_actions and not has_haptics:
|
||||
self.warnings.append(f"[Haptics] {filename}: Important actions without haptic feedback. Consider adding haptic confirmation.")
|
||||
|
||||
# 1.6 Touch Feedback Timing Check
|
||||
# Touch feedback should be immediate (<50ms)
|
||||
if is_react_native:
|
||||
has_pressable = bool(re.search(r'Pressable|TouchableOpacity', content))
|
||||
has_feedback_state = bool(re.search(r'pressed|style.*opacity|underlay', content))
|
||||
if has_pressable and not has_feedback_state:
|
||||
self.warnings.append(f"[Touch Feedback] {filename}: Pressable without visual feedback state. Add opacity/scale change for tap confirmation.")
|
||||
|
||||
# --- 2. MOBILE PERFORMANCE CHECKS ---
|
||||
|
||||
# 2.1 CRITICAL: ScrollView vs FlatList
|
||||
has_scrollview = bool(re.search(r'<ScrollView|ScrollView\.', content))
|
||||
has_map_in_scrollview = bool(re.search(r'ScrollView.*\.map\(|ScrollView.*\{.*\.map', content))
|
||||
if has_scrollview and has_map_in_scrollview:
|
||||
self.issues.append(f"[Performance CRITICAL] {filename}: ScrollView with .map() detected. Use FlatList for lists to prevent memory explosion.")
|
||||
|
||||
# 2.2 React.memo Check
|
||||
if is_react_native:
|
||||
has_list = bool(re.search(r'FlatList|FlashList|SectionList', content))
|
||||
has_react_memo = bool(re.search(r'React\.memo|memo\(', content))
|
||||
if has_list and not has_react_memo:
|
||||
self.warnings.append(f"[Performance] {filename}: FlatList without React.memo on list items. Items will re-render on every parent update.")
|
||||
|
||||
# 2.3 useCallback Check
|
||||
if is_react_native:
|
||||
has_flatlist = bool(re.search(r'FlatList|FlashList', content))
|
||||
has_use_callback = bool(re.search(r'useCallback', content))
|
||||
if has_flatlist and not has_use_callback:
|
||||
self.warnings.append(f"[Performance] {filename}: FlatList renderItem without useCallback. New function created every render.")
|
||||
|
||||
# 2.4 keyExtractor Check (CRITICAL)
|
||||
if is_react_native:
|
||||
has_flatlist = bool(re.search(r'FlatList', content))
|
||||
has_key_extractor = bool(re.search(r'keyExtractor', content))
|
||||
uses_index_key = bool(re.search(r'key=\{.*index.*\}|key:\s*index', content))
|
||||
if has_flatlist and not has_key_extractor:
|
||||
self.issues.append(f"[Performance CRITICAL] {filename}: FlatList without keyExtractor. Index-based keys cause bugs on reorder/delete.")
|
||||
if uses_index_key:
|
||||
self.issues.append(f"[Performance CRITICAL] {filename}: Using index as key. This causes bugs when list changes. Use unique ID from data.")
|
||||
|
||||
# 2.5 useNativeDriver Check
|
||||
if is_react_native:
|
||||
has_animated = bool(re.search(r'Animated\.', content))
|
||||
has_native_driver = bool(re.search(r'useNativeDriver:\s*true', content))
|
||||
has_native_driver_false = bool(re.search(r'useNativeDriver:\s*false', content))
|
||||
if has_animated and has_native_driver_false:
|
||||
self.warnings.append(f"[Performance] {filename}: Animation with useNativeDriver: false. Use true for 60fps (only supports transform/opacity).")
|
||||
if has_animated and not has_native_driver:
|
||||
self.warnings.append(f"[Performance] {filename}: Animated component without useNativeDriver. Add useNativeDriver: true for 60fps.")
|
||||
|
||||
# 2.6 Memory Leak Check
|
||||
if is_react_native:
|
||||
has_effect = bool(re.search(r'useEffect', content))
|
||||
has_cleanup = bool(re.search(r'return\s*\(\)\s*=>|return\s+function', content))
|
||||
has_subscriptions = bool(re.search(r'addEventListener|subscribe|\.focus\(\)|\.off\(', content))
|
||||
if has_effect and has_subscriptions and not has_cleanup:
|
||||
self.issues.append(f"[Memory Leak] {filename}: useEffect with subscriptions but no cleanup function. Memory leak on unmount.")
|
||||
|
||||
# 2.7 Console.log Detection
|
||||
console_logs = len(re.findall(r'console\.log|console\.warn|console\.error|console\.debug', content))
|
||||
if console_logs > 5:
|
||||
self.warnings.append(f"[Performance] {filename}: {console_logs} console.log statements detected. Remove before production (blocks JS thread).")
|
||||
|
||||
# 2.8 Inline Function Detection
|
||||
if is_react_native:
|
||||
inline_functions = re.findall(r'(?:onPress|onPressIn|onPressOut|renderItem):\s*\([^)]*\)\s*=>', content)
|
||||
if len(inline_functions) > 3:
|
||||
self.warnings.append(f"[Performance] {filename}: {len(inline_functions)} inline arrow functions in props. Creates new function every render. Use useCallback.")
|
||||
|
||||
# 2.9 Animation Properties Check
|
||||
# Warn if animating expensive properties
|
||||
animating_layout = bool(re.search(r'Animated\.timing.*(?:width|height|margin|padding)', content))
|
||||
if animating_layout:
|
||||
self.issues.append(f"[Performance] {filename}: Animating layout properties (width/height/margin). Use transform/opacity for 60fps.")
|
||||
|
||||
# --- 3. MOBILE NAVIGATION CHECKS ---
|
||||
|
||||
# 3.1 Tab Bar Max Items Check
|
||||
tab_bar_items = len(re.findall(r'Tab\.Screen|createBottomTabNavigator|BottomTab', content))
|
||||
if tab_bar_items > 5:
|
||||
self.warnings.append(f"[Navigation] {filename}: {tab_bar_items} tab bar items (max 5 recommended). More than 5 becomes hard to tap.")
|
||||
|
||||
# 3.2 Tab State Preservation Check
|
||||
has_tab_nav = bool(re.search(r'createBottomTabNavigator|Tab\.Navigator', content))
|
||||
if has_tab_nav:
|
||||
# Look for lazy prop (false preserves state)
|
||||
has_lazy_false = bool(re.search(r'lazy:\s*false', content))
|
||||
if not has_lazy_false:
|
||||
self.warnings.append(f"[Navigation] {filename}: Tab navigation without lazy: false. Tabs may lose state on switch.")
|
||||
|
||||
# 3.3 Back Handling Check
|
||||
has_back_listener = bool(re.search(r'BackHandler|useFocusEffect|navigation\.addListener', content))
|
||||
has_custom_back = bool(re.search(r'onBackPress|handleBackPress', content))
|
||||
if has_custom_back and not has_back_listener:
|
||||
self.warnings.append(f"[Navigation] {filename}: Custom back handling without BackHandler listener. May not work correctly.")
|
||||
|
||||
# 3.4 Deep Link Support Check
|
||||
has_linking = bool(re.search(r'Linking\.|Linking\.openURL|deepLink|universalLink', content))
|
||||
has_config = bool(re.search(r'apollo-link|react-native-screens|navigation\.link', content))
|
||||
if not has_linking and not has_config:
|
||||
self.passed_count += 1
|
||||
else:
|
||||
if has_linking and not has_config:
|
||||
self.warnings.append(f"[Navigation] {filename}: Deep linking detected but may lack proper configuration. Test notification/share flows.")
|
||||
|
||||
# --- 4. MOBILE TYPOGRAPHY CHECKS ---
|
||||
|
||||
# 4.1 System Font Check
|
||||
if is_react_native:
|
||||
has_custom_font = bool(re.search(r"fontFamily:\s*[\"'][^\"']+", content))
|
||||
has_system_font = bool(re.search(r"fontFamily:\s*[\"']?(?:System|San Francisco|Roboto|-apple-system)", content))
|
||||
if has_custom_font and not has_system_font:
|
||||
self.warnings.append(f"[Typography] {filename}: Custom font detected. Consider system fonts (iOS: SF Pro, Android: Roboto) for native feel.")
|
||||
|
||||
# 4.2 Text Scaling Check (iOS Dynamic Type)
|
||||
if is_react_native:
|
||||
has_font_sizes = bool(re.search(r'fontSize:', content))
|
||||
has_scaling = bool(re.search(r'allowFontScaling:\s*true|responsiveFontSize|useWindowDimensions', content))
|
||||
if has_font_sizes and not has_scaling:
|
||||
self.warnings.append(f"[Typography] {filename}: Fixed font sizes without scaling support. Consider allowFontScaling for accessibility.")
|
||||
|
||||
# 4.3 Mobile Line Height Check
|
||||
line_heights = re.findall(r'lineHeight:\s*([\d.]+)', content)
|
||||
for lh in line_heights:
|
||||
if float(lh) > 1.8:
|
||||
self.warnings.append(f"[Typography] {filename}: lineHeight {lh} too high for mobile. Mobile text needs tighter spacing (1.3-1.5).")
|
||||
|
||||
# 4.4 Font Size Limits
|
||||
font_sizes = re.findall(r'fontSize:\s*([\d.]+)', content)
|
||||
for fs in font_sizes:
|
||||
size = float(fs)
|
||||
if size < 12:
|
||||
self.warnings.append(f"[Typography] {filename}: fontSize {size}px below 12px minimum readability.")
|
||||
elif size > 32:
|
||||
self.warnings.append(f"[Typography] {filename}: fontSize {size}px very large. Consider using responsive scaling.")
|
||||
|
||||
# --- 5. MOBILE COLOR SYSTEM CHECKS ---
|
||||
|
||||
# 5.1 Pure Black Avoidance
|
||||
if re.search(r'#000000|color:\s*black|backgroundColor:\s*["\']?black', content):
|
||||
self.warnings.append(f"[Color] {filename}: Pure black (#000000) detected. Use dark gray (#1C1C1E iOS, #121212 Android) for better OLED/battery.")
|
||||
|
||||
# 5.2 Dark Mode Support
|
||||
has_color_schemes = bool(re.search(r'useColorScheme|colorScheme|appearance:\s*["\']?dark', content))
|
||||
has_dark_mode_style = bool(re.search(r'\\\?.*dark|style:\s*.*dark|isDark', content))
|
||||
if not has_color_schemes and not has_dark_mode_style:
|
||||
self.warnings.append(f"[Color] {filename}: No dark mode support detected. Consider useColorScheme for system dark mode.")
|
||||
|
||||
# --- 6. PLATFORM iOS CHECKS ---
|
||||
|
||||
if is_react_native:
|
||||
# 6.1 SF Symbols Check
|
||||
has_ios_icons = bool(re.search(r'@expo/vector-icons|ionicons', content))
|
||||
has_sf_symbols = bool(re.search(r'sf-symbol|SF Symbols', content))
|
||||
if has_ios_icons and not has_sf_symbols:
|
||||
self.passed_count += 1
|
||||
|
||||
# 6.2 iOS Haptic Types
|
||||
has_haptic_import = bool(re.search(r'expo-haptics|react-native-haptic-feedback', content))
|
||||
has_haptic_types = bool(re.search(r'ImpactFeedback|NotificationFeedback|SelectionFeedback', content))
|
||||
if has_haptic_import and not has_haptic_types:
|
||||
self.warnings.append(f"[iOS Haptics] {filename}: Haptic library imported but not using typed haptics (Impact/Notification/Selection).")
|
||||
|
||||
# 6.3 iOS Safe Area
|
||||
has_safe_area = bool(re.search(r'SafeAreaView|useSafeAreaInsets|safeArea', content))
|
||||
if not has_safe_area:
|
||||
self.warnings.append(f"[iOS] {filename}: No SafeArea detected. Content may be hidden by notch/home indicator.")
|
||||
|
||||
# --- 7. PLATFORM ANDROID CHECKS ---
|
||||
|
||||
if is_react_native:
|
||||
# 7.1 Material Icons Check
|
||||
has_material_icons = bool(re.search(r'@expo/vector-icons|MaterialIcons', content))
|
||||
if has_material_icons:
|
||||
self.passed_count += 1
|
||||
|
||||
# 7.2 Ripple Effect
|
||||
has_ripple = bool(re.search(r'ripple|android_ripple|foregroundRipple', content))
|
||||
has_pressable = bool(re.search(r'Pressable|Touchable', content))
|
||||
if has_pressable and not has_ripple:
|
||||
self.warnings.append(f"[Android] {filename}: Touchable without ripple effect. Android users expect ripple feedback.")
|
||||
|
||||
# 7.3 Hardware Back Button
|
||||
if is_react_native:
|
||||
has_back_button = bool(re.search(r'BackHandler|useBackHandler', content))
|
||||
has_navigation = bool(re.search(r'@react-navigation', content))
|
||||
if has_navigation and not has_back_button:
|
||||
self.warnings.append(f"[Android] {filename}: React Navigation detected without BackHandler listener. Android hardware back may not work correctly.")
|
||||
|
||||
# --- 8. MOBILE BACKEND CHECKS ---
|
||||
|
||||
# 8.1 Secure Storage Check
|
||||
has_async_storage = bool(re.search(r'AsyncStorage|@react-native-async-storage', content))
|
||||
has_secure_storage = bool(re.search(r'SecureStore|Keychain|EncryptedSharedPreferences', content))
|
||||
has_token_storage = bool(re.search(r'token|jwt|auth.*storage', content, re.IGNORECASE))
|
||||
if has_token_storage and has_async_storage and not has_secure_storage:
|
||||
self.issues.append(f"[Security] {filename}: Storing auth tokens in AsyncStorage (insecure). Use SecureStore (iOS) / EncryptedSharedPreferences (Android).")
|
||||
|
||||
# 8.2 Offline Handling Check
|
||||
has_network = bool(re.search(r'fetch|axios|netinfo|@react-native-community/netinfo', content))
|
||||
has_offline = bool(re.search(r'offline|isConnected|netInfo|cache.*offline', content))
|
||||
if has_network and not has_offline:
|
||||
self.warnings.append(f"[Offline] {filename}: Network requests detected without offline handling. Consider NetInfo for connection status.")
|
||||
|
||||
# 8.3 Push Notification Support
|
||||
has_push = bool(re.search(r'Notifications|pushNotification|Firebase\.messaging|PushNotificationIOS', content))
|
||||
has_push_handler = bool(re.search(r'onNotification|addNotificationListener|notification\.open', content))
|
||||
if has_push and not has_push_handler:
|
||||
self.warnings.append(f"[Push] {filename}: Push notifications imported but no handler found. May miss notifications.")
|
||||
|
||||
# --- 9. EXTENDED MOBILE TYPOGRAPHY CHECKS ---
|
||||
|
||||
# 9.1 iOS Type Scale Check
|
||||
if is_react_native:
|
||||
# Check for iOS text styles that match HIG
|
||||
has_large_title = bool(re.search(r'fontSize:\s*34|largeTitle|font-weight:\s*["\']?bold', content))
|
||||
has_title_1 = bool(re.search(r'fontSize:\s*28', content))
|
||||
has_headline = bool(re.search(r'fontSize:\s*17.*semibold|headline', content))
|
||||
has_body = bool(re.search(r'fontSize:\s*17.*regular|body', content))
|
||||
|
||||
# Check if following iOS scale roughly
|
||||
font_sizes = re.findall(r'fontSize:\s*([\d.]+)', content)
|
||||
ios_scale_sizes = [34, 28, 22, 20, 17, 16, 15, 13, 12, 11]
|
||||
matching_ios = sum(1 for size in font_sizes if any(abs(float(size) - ios_size) < 1 for ios_size in ios_scale_sizes))
|
||||
|
||||
if len(font_sizes) > 3 and matching_ios < len(font_sizes) / 2:
|
||||
self.warnings.append(f"[iOS Typography] {filename}: Font sizes don't match iOS type scale. Consider iOS text styles for native feel.")
|
||||
|
||||
# 9.2 Android Material Type Scale Check
|
||||
if is_react_native:
|
||||
# Check for Material 3 text styles
|
||||
has_display = bool(re.search(r'fontSize:\s*[456][0-9]|display', content))
|
||||
has_headline_material = bool(re.search(r'fontSize:\s*[23][0-9]|headline', content))
|
||||
has_title_material = bool(re.search(r'fontSize:\s*2[12][0-9].*medium|title', content))
|
||||
has_body_material = bool(re.search(r'fontSize:\s*1[456].*regular|body', content))
|
||||
has_label = bool(re.search(r'fontSize:\s*1[1234].*medium|label', content))
|
||||
|
||||
# Check if using sp (scale-independent pixels)
|
||||
uses_sp = bool(re.search(r'\d+\s*sp\b', content))
|
||||
if has_display or has_headline_material:
|
||||
if not uses_sp:
|
||||
self.warnings.append(f"[Android Typography] {filename}: Material typography detected without sp units. Use sp for text to respect user font size preferences.")
|
||||
|
||||
# 9.3 Modular Scale Check
|
||||
# Check if font sizes follow modular scale
|
||||
font_sizes = re.findall(r'fontSize:\s*(\d+(?:\.\d+)?)', content)
|
||||
if len(font_sizes) > 3:
|
||||
sorted_sizes = sorted(set([float(s) for s in font_sizes]))
|
||||
ratios = []
|
||||
for i in range(1, len(sorted_sizes)):
|
||||
if sorted_sizes[i-1] > 0:
|
||||
ratios.append(sorted_sizes[i] / sorted_sizes[i-1])
|
||||
|
||||
# Common ratios: 1.125, 1.2, 1.25, 1.333, 1.5
|
||||
common_ratios = {1.125, 1.2, 1.25, 1.333, 1.5}
|
||||
for ratio in ratios[:3]:
|
||||
if not any(abs(ratio - cr) < 0.03 for cr in common_ratios):
|
||||
self.warnings.append(f"[Typography] {filename}: Font sizes may not follow modular scale (ratio: {ratio:.2f}). Consider consistent ratio.")
|
||||
break
|
||||
|
||||
# 9.4 Line Length Check (Mobile-specific)
|
||||
# Mobile text should be 40-60 characters max
|
||||
if is_react_native:
|
||||
has_long_text = bool(re.search(r'<Text[^>]*>[^<]{40,}', content))
|
||||
has_max_width = bool(re.search(r'maxWidth|max-w-\d+|width:\s*["\']?\d+', content))
|
||||
if has_long_text and not has_max_width:
|
||||
self.warnings.append(f"[Mobile Typography] {filename}: Text without max-width constraint. Mobile text should be 40-60 characters per line for readability.")
|
||||
|
||||
# 9.5 Font Weight Pattern Check
|
||||
# Check for font weight distribution
|
||||
if is_react_native:
|
||||
font_weights = re.findall(r'fontWeight:\s*["\']?(\d+|normal|bold|medium|light)', content)
|
||||
weight_map = {'normal': '400', 'light': '300', 'medium': '500', 'bold': '700'}
|
||||
numeric_weights = []
|
||||
for w in font_weights:
|
||||
val = weight_map.get(w.lower(), w)
|
||||
try:
|
||||
numeric_weights.append(int(val))
|
||||
except:
|
||||
pass
|
||||
|
||||
# Check if overusing bold (mobile should be regular-dominant)
|
||||
bold_count = sum(1 for w in numeric_weights if w >= 700)
|
||||
regular_count = sum(1 for w in numeric_weights if 400 <= w < 500)
|
||||
if bold_count > regular_count:
|
||||
self.warnings.append(f"[Mobile Typography] {filename}: More bold weights than regular. Mobile typography should be regular-dominant for readability.")
|
||||
|
||||
# --- 10. EXTENDED MOBILE COLOR SYSTEM CHECKS ---
|
||||
|
||||
# 10.1 OLED Optimization Check
|
||||
# Check for near-black colors instead of pure black
|
||||
if re.search(r'#121212|#1A1A1A|#0D0D0D', content):
|
||||
self.passed_count += 1 # Good OLED optimization
|
||||
elif re.search(r'backgroundColor:\s*["\']?#000000', content):
|
||||
# Using pure black for background is OK for OLED
|
||||
pass
|
||||
elif re.search(r'backgroundColor:\s*["\']?#[0-9A-Fa-f]{6}', content):
|
||||
# Check if using light colors in dark mode (bad for OLED)
|
||||
self.warnings.append(f"[Mobile Color] {filename}: Consider OLED-optimized dark backgrounds (#121212 Android, #000000 iOS) for battery savings.")
|
||||
|
||||
# 10.2 Saturated Color Detection (Battery)
|
||||
# Highly saturated colors consume more power on OLED
|
||||
hex_colors = re.findall(r'#([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})', content)
|
||||
saturated_count = 0
|
||||
for r, g, b in hex_colors:
|
||||
# Convert to RGB 0-255
|
||||
try:
|
||||
r_val, g_val, b_val = int(r, 16), int(g, 16), int(b, 16)
|
||||
max_val = max(r_val, g_val, b_val)
|
||||
min_val = min(r_val, g_val, b_val)
|
||||
# Saturation = (max - min) / max
|
||||
if max_val > 0:
|
||||
saturation = (max_val - min_val) / max_val
|
||||
if saturation > 0.8: # Highly saturated
|
||||
saturated_count += 1
|
||||
except:
|
||||
pass
|
||||
|
||||
if saturated_count > 10:
|
||||
self.warnings.append(f"[Mobile Color] {filename}: {saturated_count} highly saturated colors detected. Desaturated colors save battery on OLED screens.")
|
||||
|
||||
# 10.3 Outdoor Visibility Check
|
||||
# Low contrast combinations fail in outdoor sunlight
|
||||
light_colors = re.findall(r'#[0-9A-Fa-f]{6}|rgba?\([^)]+\)', content)
|
||||
# Check for potential low contrast (light gray on white, dark gray on black)
|
||||
potential_low_contrast = bool(re.search(r'#[EeEeEeEe].*#ffffff|#999999.*#ffffff|#333333.*#000000|#666666.*#000000', content))
|
||||
if potential_low_contrast:
|
||||
self.warnings.append(f"[Mobile Color] {filename}: Possible low contrast combination detected. Critical for outdoor visibility. Ensure WCAG AAA (7:1) for mobile.")
|
||||
|
||||
# 10.4 Dark Mode Text Color Check
|
||||
# In dark mode, text should not be pure white
|
||||
has_dark_mode = bool(re.search(r'dark:\s*|isDark|useColorScheme|colorScheme:\s*["\']?dark', content))
|
||||
if has_dark_mode:
|
||||
has_pure_white_text = bool(re.search(r'color:\s*["\']?#ffffff|#fff["\']?\}|textColor:\s*["\']?white', content))
|
||||
if has_pure_white_text:
|
||||
self.warnings.append(f"[Mobile Color] {filename}: Pure white text (#FFFFFF) in dark mode. Use #E8E8E8 or light gray for better readability.")
|
||||
|
||||
# --- 11. EXTENDED PLATFORM IOS CHECKS ---
|
||||
|
||||
if is_react_native:
|
||||
# 11.1 SF Pro Font Detection
|
||||
has_sf_pro = bool(re.search(r'SF Pro|SFPro|fontFamily:\s*["\']?[-\s]*SF', content))
|
||||
has_custom_font = bool(re.search(r'fontFamily:\s*["\'][^"\']+', content))
|
||||
if has_custom_font and not has_sf_pro:
|
||||
self.warnings.append(f"[iOS] {filename}: Custom font without SF Pro fallback. Consider SF Pro Text for body, SF Pro Display for headings.")
|
||||
|
||||
# 11.2 iOS System Colors Check
|
||||
# Check for semantic color usage
|
||||
has_label = bool(re.search(r'color:\s*["\']?label|\.label', content))
|
||||
has_secondaryLabel = bool(re.search(r'secondaryLabel|\.secondaryLabel', content))
|
||||
has_systemBackground = bool(re.search(r'systemBackground|\.systemBackground', content))
|
||||
|
||||
has_hardcoded_gray = bool(re.search(r'#[78]0{4}', content))
|
||||
if has_hardcoded_gray and not (has_label or has_secondaryLabel):
|
||||
self.warnings.append(f"[iOS] {filename}: Hardcoded gray colors detected. Consider iOS semantic colors (label, secondaryLabel) for automatic dark mode.")
|
||||
|
||||
# 11.3 iOS Accent Colors Check
|
||||
ios_blue = bool(re.search(r'#007AFF|#0A84FF|systemBlue', content))
|
||||
ios_green = bool(re.search(r'#34C759|#30D158|systemGreen', content))
|
||||
ios_red = bool(re.search(r'#FF3B30|#FF453A|systemRed', content))
|
||||
|
||||
has_custom_primary = bool(re.search(r'primaryColor|theme.*primary|colors\.primary', content))
|
||||
if has_custom_primary and not (ios_blue or ios_green or ios_red):
|
||||
self.warnings.append(f"[iOS] {filename}: Custom primary color without iOS system color fallback. Consider systemBlue for consistent iOS feel.")
|
||||
|
||||
# 11.4 iOS Navigation Patterns Check
|
||||
has_navigation_bar = bool(re.search(r'navigationOptions|headerStyle|cardStyle', content))
|
||||
has_header_title = bool(re.search(r'title:\s*["\']|headerTitle|navigation\.setOptions', content))
|
||||
if has_navigation_bar and not has_header_title:
|
||||
self.warnings.append(f"[iOS] {filename}: Navigation bar detected without title. iOS apps should have clear context in nav bar.")
|
||||
|
||||
# 11.5 iOS Component Patterns Check
|
||||
# Check for iOS-specific components
|
||||
has_alert = bool(re.search(r'Alert\.alert|showAlert', content))
|
||||
has_action_sheet = bool(re.search(r'ActionSheet|ActionSheetIOS|showActionSheetWithOptions', content))
|
||||
has_activity_indicator = bool(re.search(r'ActivityIndicator|ActivityIndic', content))
|
||||
|
||||
if has_alert or has_action_sheet or has_activity_indicator:
|
||||
self.passed_count += 1 # Good iOS component usage
|
||||
|
||||
# --- 12. EXTENDED PLATFORM ANDROID CHECKS ---
|
||||
|
||||
if is_react_native:
|
||||
# 12.1 Roboto Font Detection
|
||||
has_roboto = bool(re.search(r'Roboto|fontFamily:\s*["\']?[-\s]*Roboto', content))
|
||||
has_custom_font = bool(re.search(r'fontFamily:\s*["\'][^"\']+', content))
|
||||
if has_custom_font and not has_roboto:
|
||||
self.warnings.append(f"[Android] {filename}: Custom font without Roboto fallback. Roboto is optimized for Android displays.")
|
||||
|
||||
# 12.2 Material 3 Dynamic Color Check
|
||||
has_material_colors = bool(re.search(r'MD3|MaterialYou|dynamicColor|useColorScheme', content))
|
||||
has_theme_provider = bool(re.search(r'MaterialTheme|ThemeProvider|PaperProvider|ThemeProvider', content))
|
||||
if not has_material_colors and not has_theme_provider:
|
||||
self.warnings.append(f"[Android] {filename}: No Material 3 dynamic color detected. Consider Material 3 theming for personalized feel.")
|
||||
|
||||
# 12.3 Material Elevation Check
|
||||
# Check for elevation values (Material 3 uses elevation for depth)
|
||||
has_elevation = bool(re.search(r'elevation:\s*\d+|shadowOpacity|shadowRadius|android:elevation', content))
|
||||
has_box_shadow = bool(re.search(r'boxShadow:', content))
|
||||
if has_box_shadow and not has_elevation:
|
||||
self.warnings.append(f"[Android] {filename}: CSS box-shadow detected without elevation. Consider Material elevation system for consistent depth.")
|
||||
|
||||
# 12.4 Material Component Patterns Check
|
||||
# Check for Material components
|
||||
has_ripple = bool(re.search(r'ripple|android_ripple|foregroundRipple', content))
|
||||
has_card = bool(re.search(r'Card|Paper|elevation.*\d+', content))
|
||||
has_fab = bool(re.search(r'FAB|FloatingActionButton|fab', content))
|
||||
has_snackbar = bool(re.search(r'Snackbar|showSnackBar|Toast', content))
|
||||
|
||||
material_component_count = sum([has_ripple, has_card, has_fab, has_snackbar])
|
||||
if material_component_count >= 2:
|
||||
self.passed_count += 1 # Good Material design usage
|
||||
|
||||
# 12.5 Android Navigation Patterns Check
|
||||
has_top_app_bar = bool(re.search(r'TopAppBar|AppBar|CollapsingToolbar', content))
|
||||
has_bottom_nav = bool(re.search(r'BottomNavigation|BottomNav', content))
|
||||
has_navigation_rail = bool(re.search(r'NavigationRail', content))
|
||||
|
||||
if has_bottom_nav:
|
||||
self.passed_count += 1 # Good Android pattern
|
||||
elif has_top_app_bar and not (has_bottom_nav or has_navigation_rail):
|
||||
self.warnings.append(f"[Android] {filename}: TopAppBar without bottom navigation. Consider BottomNavigation for thumb-friendly access.")
|
||||
|
||||
# --- 13. MOBILE TESTING CHECKS ---
|
||||
|
||||
# 13.1 Testing Tool Detection
|
||||
has_rntl = bool(re.search(r'react-native-testing-library|@testing-library', content))
|
||||
has_detox = bool(re.search(r'detox|element\(|by\.text|by\.id', content))
|
||||
has_maestro = bool(re.search(r'maestro|\.yaml$', content))
|
||||
has_jest = bool(re.search(r'jest|describe\(|test\(|it\(', content))
|
||||
|
||||
testing_tools = []
|
||||
if has_jest: testing_tools.append('Jest')
|
||||
if has_rntl: testing_tools.append('RNTL')
|
||||
if has_detox: testing_tools.append('Detox')
|
||||
if has_maestro: testing_tools.append('Maestro')
|
||||
|
||||
if len(testing_tools) == 0:
|
||||
self.warnings.append(f"[Testing] {filename}: No testing framework detected. Consider Jest (unit) + Detox/Maestro (E2E) for mobile.")
|
||||
|
||||
# 13.2 Test Pyramid Balance Check
|
||||
test_files = len(re.findall(r'\.test\.(tsx|ts|js|jsx)|\.spec\.', content))
|
||||
e2e_tests = len(re.findall(r'detox|maestro|e2e|spec\.e2e', content.lower()))
|
||||
|
||||
if test_files > 0 and e2e_tests == 0:
|
||||
self.warnings.append(f"[Testing] {filename}: Unit tests found but no E2E tests. Mobile needs E2E on real devices for complete coverage.")
|
||||
|
||||
# 13.3 Accessibility Label Check (Mobile-specific)
|
||||
if is_react_native:
|
||||
has_pressable = bool(re.search(r'Pressable|TouchableOpacity|TouchableHighlight', content))
|
||||
has_a11y_label = bool(re.search(r'accessibilityLabel|aria-label|testID', content))
|
||||
if has_pressable and not has_a11y_label:
|
||||
self.warnings.append(f"[A11y Mobile] {filename}: Touchable element without accessibilityLabel. Screen readers need labels for all interactive elements.")
|
||||
|
||||
# --- 14. MOBILE DEBUGGING CHECKS ---
|
||||
|
||||
# 14.1 Performance Profiling Check
|
||||
has_performance = bool(re.search(r'Performance|systrace|profile|Flipper', content))
|
||||
has_console_log = len(re.findall(r'console\.(log|warn|error|debug|info)', content))
|
||||
has_debugger = bool(re.search(r'debugger|__DEV__|React\.DevTools', content))
|
||||
|
||||
if has_console_log > 10:
|
||||
self.warnings.append(f"[Debugging] {filename}: {has_console_log} console.log statements. Remove before production; they block JS thread.")
|
||||
|
||||
if has_performance:
|
||||
self.passed_count += 1 # Good performance monitoring
|
||||
|
||||
# 14.2 Error Boundary Check
|
||||
has_error_boundary = bool(re.search(r'ErrorBoundary|componentDidCatch|getDerivedStateFromError', content))
|
||||
if not has_error_boundary and is_react_native:
|
||||
self.warnings.append(f"[Debugging] {filename}: No ErrorBoundary detected. Consider adding ErrorBoundary to prevent app crashes.")
|
||||
|
||||
# 14.3 Hermes Check (React Native specific)
|
||||
if is_react_native:
|
||||
# Check if using Hermes engine (should be default in modern RN)
|
||||
# This is more of a configuration check, not code pattern
|
||||
self.passed_count += 1 # Hermes is default in RN 0.70+
|
||||
|
||||
def audit_directory(self, directory: str) -> None:
|
||||
extensions = {'.tsx', '.ts', '.jsx', '.js', '.dart'}
|
||||
for root, dirs, files in os.walk(directory):
|
||||
dirs[:] = [d for d in dirs if d not in {'node_modules', '.git', 'dist', 'build', '.next', 'ios', 'android', 'build', '.idea'}]
|
||||
for file in files:
|
||||
if Path(file).suffix in extensions:
|
||||
self.audit_file(os.path.join(root, file))
|
||||
|
||||
def get_report(self):
|
||||
return {
|
||||
"files_checked": self.files_checked,
|
||||
"issues": self.issues,
|
||||
"warnings": self.warnings,
|
||||
"passed_checks": self.passed_count,
|
||||
"compliant": len(self.issues) == 0
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python mobile_audit.py <directory>")
|
||||
sys.exit(1)
|
||||
|
||||
path = sys.argv[1]
|
||||
is_json = "--json" in sys.argv
|
||||
|
||||
auditor = MobileAuditor()
|
||||
if os.path.isfile(path):
|
||||
auditor.audit_file(path)
|
||||
else:
|
||||
auditor.audit_directory(path)
|
||||
|
||||
report = auditor.get_report()
|
||||
|
||||
if is_json:
|
||||
print(json.dumps(report, indent=2))
|
||||
else:
|
||||
print(f"\n[MOBILE AUDIT] {report['files_checked']} mobile files checked")
|
||||
print("-" * 50)
|
||||
if report['issues']:
|
||||
print(f"[!] ISSUES ({len(report['issues'])}):")
|
||||
for i in report['issues'][:10]:
|
||||
print(f" - {i}")
|
||||
if report['warnings']:
|
||||
print(f"[*] WARNINGS ({len(report['warnings'])}):")
|
||||
for w in report['warnings'][:15]:
|
||||
print(f" - {w}")
|
||||
print(f"[+] PASSED CHECKS: {report['passed_checks']}")
|
||||
status = "PASS" if report['compliant'] else "FAIL"
|
||||
print(f"STATUS: {status}")
|
||||
|
||||
sys.exit(0 if report['compliant'] else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Fix missing import
|
||||
import re
|
||||
main()
|
||||
537
skills/mobile-design/touch-psychology.md
Normal file
537
skills/mobile-design/touch-psychology.md
Normal file
@@ -0,0 +1,537 @@
|
||||
# Touch Psychology Reference
|
||||
|
||||
> Deep dive into mobile touch interaction, Fitts' Law for touch, thumb zone anatomy, gesture psychology, and haptic feedback.
|
||||
> **This is the mobile equivalent of ux-psychology.md - CRITICAL for all mobile work.**
|
||||
|
||||
---
|
||||
|
||||
## 1. Fitts' Law for Touch
|
||||
|
||||
### The Fundamental Difference
|
||||
|
||||
```
|
||||
DESKTOP (Mouse/Trackpad):
|
||||
├── Cursor size: 1 pixel (precision)
|
||||
├── Visual feedback: Hover states
|
||||
├── Error cost: Low (easy to retry)
|
||||
└── Target acquisition: Fast, precise
|
||||
|
||||
MOBILE (Finger):
|
||||
├── Contact area: ~7mm diameter (imprecise)
|
||||
├── Visual feedback: No hover, only tap
|
||||
├── Error cost: High (frustrating retries)
|
||||
├── Occlusion: Finger covers the target
|
||||
└── Target acquisition: Slower, needs larger targets
|
||||
```
|
||||
|
||||
### Fitts' Law Formula Adapted
|
||||
|
||||
```
|
||||
Touch acquisition time = a + b × log₂(1 + D/W)
|
||||
|
||||
Where:
|
||||
├── D = Distance to target
|
||||
├── W = Width of target
|
||||
└── For touch: W must be MUCH larger than desktop
|
||||
```
|
||||
|
||||
### Minimum Touch Target Sizes
|
||||
|
||||
| Platform | Minimum | Recommended | Use For |
|
||||
|----------|---------|-------------|---------|
|
||||
| **iOS (HIG)** | 44pt × 44pt | 48pt+ | All tappable elements |
|
||||
| **Android (Material)** | 48dp × 48dp | 56dp+ | All tappable elements |
|
||||
| **WCAG 2.2** | 44px × 44px | - | Accessibility compliance |
|
||||
| **Critical Actions** | - | 56-64px | Primary CTAs, destructive actions |
|
||||
|
||||
### Visual Size vs Hit Area
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ [ BUTTON ] │ ← Visual: 36px
|
||||
│ │ │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │ ← Hit area: 48px (padding extends)
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
✅ CORRECT: Visual can be smaller if hit area is minimum 44-48px
|
||||
❌ WRONG: Making hit area same as small visual element
|
||||
```
|
||||
|
||||
### Application Rules
|
||||
|
||||
| Element | Visual Size | Hit Area |
|
||||
|---------|-------------|----------|
|
||||
| Icon buttons | 24-32px | 44-48px (padding) |
|
||||
| Text links | Any | 44px height minimum |
|
||||
| List items | Full width | 48-56px height |
|
||||
| Checkboxes/Radio | 20-24px | 44-48px tap area |
|
||||
| Close/X buttons | 24px | 44px minimum |
|
||||
| Tab bar items | Icon 24-28px | Full tab width, 49px height (iOS) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Thumb Zone Anatomy
|
||||
|
||||
### One-Handed Phone Usage
|
||||
|
||||
```
|
||||
Research shows: 49% of users hold phone one-handed.
|
||||
|
||||
┌─────────────────────────────────────┐
|
||||
│ │
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ HARD TO REACH │ │ ← Status bar, top nav
|
||||
│ │ (requires stretch) │ │ Put: Back, menu, settings
|
||||
│ │ │ │
|
||||
│ ├─────────────────────────────┤ │
|
||||
│ │ │ │
|
||||
│ │ OK TO REACH │ │ ← Content area
|
||||
│ │ (comfortable) │ │ Put: Secondary actions, content
|
||||
│ │ │ │
|
||||
│ ├─────────────────────────────┤ │
|
||||
│ │ │ │
|
||||
│ │ EASY TO REACH │ │ ← Tab bar, FAB zone
|
||||
│ │ (thumb's arc) │ │ Put: PRIMARY CTAs!
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
│ │
|
||||
│ [ HOME ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Thumb Arc (Right-Handed User)
|
||||
|
||||
```
|
||||
Right hand holding phone:
|
||||
|
||||
┌───────────────────────────────┐
|
||||
│ STRETCH STRETCH OK │
|
||||
│ │
|
||||
│ STRETCH OK EASY │
|
||||
│ │
|
||||
│ OK EASY EASY │
|
||||
│ │
|
||||
│ EASY EASY EASY │
|
||||
└───────────────────────────────┘
|
||||
|
||||
Left hand is mirrored.
|
||||
→ Design for BOTH hands or assume right-dominant
|
||||
```
|
||||
|
||||
### Placement Guidelines
|
||||
|
||||
| Element Type | Ideal Position | Reason |
|
||||
|--------------|----------------|--------|
|
||||
| **Primary CTA** | Bottom center/right | Easy thumb reach |
|
||||
| **Tab bar** | Bottom | Natural thumb position |
|
||||
| **FAB** | Bottom right | Easy for right hand |
|
||||
| **Navigation** | Top (stretch) | Less frequent use |
|
||||
| **Destructive actions** | Top left | Hard to reach = harder to accidentally tap |
|
||||
| **Dismiss/Cancel** | Top left | Convention + safety |
|
||||
| **Confirm/Done** | Top right or bottom | Convention |
|
||||
|
||||
### Large Phone Considerations (>6")
|
||||
|
||||
```
|
||||
On large phones, top 40% becomes "dead zone" for one-handed use.
|
||||
|
||||
Solutions:
|
||||
├── Reachability features (iOS)
|
||||
├── Pull-down interfaces (drawer pulls content down)
|
||||
├── Bottom sheet navigation
|
||||
├── Floating action buttons
|
||||
└── Gesture-based alternatives to top actions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Touch vs Click Psychology
|
||||
|
||||
### Expectation Differences
|
||||
|
||||
| Aspect | Click (Desktop) | Touch (Mobile) |
|
||||
|--------|-----------------|----------------|
|
||||
| **Feedback timing** | Can wait 100ms | Expect instant (<50ms) |
|
||||
| **Visual feedback** | Hover → Click | Immediate tap response |
|
||||
| **Error tolerance** | Easy retry | Frustrating, feels broken |
|
||||
| **Precision** | High | Low |
|
||||
| **Context menu** | Right-click | Long press |
|
||||
| **Cancel action** | ESC key | Swipe away, outside tap |
|
||||
|
||||
### Touch Feedback Requirements
|
||||
|
||||
```
|
||||
Tap → Immediate visual change (< 50ms)
|
||||
├── Highlight state (background color change)
|
||||
├── Scale down slightly (0.95-0.98)
|
||||
├── Ripple effect (Android Material)
|
||||
├── Haptic feedback for confirmation
|
||||
└── Never nothing!
|
||||
|
||||
Loading → Show within 100ms
|
||||
├── If action takes > 100ms
|
||||
├── Show spinner/progress
|
||||
├── Disable button (prevent double tap)
|
||||
└── Optimistic UI when possible
|
||||
```
|
||||
|
||||
### The "Fat Finger" Problem
|
||||
|
||||
```
|
||||
Problem: Finger occludes target during tap
|
||||
├── User can't see exactly where they're tapping
|
||||
├── Visual feedback appears UNDER finger
|
||||
└── Increases error rate
|
||||
|
||||
Solutions:
|
||||
├── Show feedback ABOVE touch point (tooltips)
|
||||
├── Use cursor-like offset for precision tasks
|
||||
├── Magnification loupe for text selection
|
||||
└── Large enough targets that precision doesn't matter
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Gesture Psychology
|
||||
|
||||
### Gesture Discoverability Problem
|
||||
|
||||
```
|
||||
Problem: Gestures are INVISIBLE.
|
||||
├── User must discover/remember them
|
||||
├── No hover/visual hint
|
||||
├── Different mental model than tap
|
||||
└── Many users never discover gestures
|
||||
|
||||
Solution: Always provide visible alternative
|
||||
├── Swipe to delete → Also show delete button or menu
|
||||
├── Pull to refresh → Also show refresh button
|
||||
├── Pinch to zoom → Also show zoom controls
|
||||
└── Gestures as shortcuts, not only way
|
||||
```
|
||||
|
||||
### Common Gesture Conventions
|
||||
|
||||
| Gesture | Universal Meaning | Usage |
|
||||
|---------|-------------------|-------|
|
||||
| **Tap** | Select, activate | Primary action |
|
||||
| **Double tap** | Zoom in, like/favorite | Quick action |
|
||||
| **Long press** | Context menu, selection mode | Secondary options |
|
||||
| **Swipe horizontal** | Navigation, delete, actions | List actions |
|
||||
| **Swipe down** | Refresh, dismiss | Pull to refresh |
|
||||
| **Pinch** | Zoom in/out | Maps, images |
|
||||
| **Two-finger scroll** | Scroll within scroll | Nested scrolls |
|
||||
|
||||
### Gesture Affordance Design
|
||||
|
||||
```
|
||||
Swipe actions need visual hints:
|
||||
|
||||
┌─────────────────────────────────────────┐
|
||||
│ ┌───┐ │
|
||||
│ │ ≡ │ Item with hidden actions... → │ ← Edge hint (partial color)
|
||||
│ └───┘ │
|
||||
└─────────────────────────────────────────┘
|
||||
|
||||
✅ Good: Slight color peek at edge suggesting swipe
|
||||
✅ Good: Drag handle icon ( ≡ ) suggesting reorder
|
||||
✅ Good: Onboarding tooltip explaining gesture
|
||||
❌ Bad: Hidden gestures with no visual affordance
|
||||
```
|
||||
|
||||
### Platform Gesture Differences
|
||||
|
||||
| Gesture | iOS | Android |
|
||||
|---------|-----|---------|
|
||||
| **Back** | Edge swipe from left | System back button/gesture |
|
||||
| **Share** | Action sheet | Share sheet |
|
||||
| **Context menu** | Long press / Force touch | Long press |
|
||||
| **Dismiss modal** | Swipe down | Back button or swipe |
|
||||
| **Delete in list** | Swipe left, tap delete | Swipe left, immediate or undo |
|
||||
|
||||
---
|
||||
|
||||
## 5. Haptic Feedback Patterns
|
||||
|
||||
### Why Haptics Matter
|
||||
|
||||
```
|
||||
Haptics provide:
|
||||
├── Confirmation without looking
|
||||
├── Richer, more premium feel
|
||||
├── Accessibility (blind users)
|
||||
├── Reduced error rate
|
||||
└── Emotional satisfaction
|
||||
|
||||
Without haptics:
|
||||
├── Feels "cheap" or web-like
|
||||
├── User unsure if action registered
|
||||
└── Missed opportunity for delight
|
||||
```
|
||||
|
||||
### iOS Haptic Types
|
||||
|
||||
| Type | Intensity | Use Case |
|
||||
|------|-----------|----------|
|
||||
| `selection` | Light | Picker scroll, toggle, selection |
|
||||
| `light` | Light | Minor actions, hover equivalent |
|
||||
| `medium` | Medium | Standard tap confirmation |
|
||||
| `heavy` | Strong | Important completed, drop |
|
||||
| `success` | Pattern | Task completed successfully |
|
||||
| `warning` | Pattern | Warning, attention needed |
|
||||
| `error` | Pattern | Error occurred |
|
||||
|
||||
### Android Haptic Types
|
||||
|
||||
| Type | Use Case |
|
||||
|------|----------|
|
||||
| `CLICK` | Standard tap feedback |
|
||||
| `HEAVY_CLICK` | Important actions |
|
||||
| `DOUBLE_CLICK` | Confirm actions |
|
||||
| `TICK` | Scroll/scrub feedback |
|
||||
| `LONG_PRESS` | Long press activation |
|
||||
| `REJECT` | Error/invalid action |
|
||||
|
||||
### Haptic Usage Guidelines
|
||||
|
||||
```
|
||||
✅ DO use haptics for:
|
||||
├── Button taps
|
||||
├── Toggle switches
|
||||
├── Picker/slider values
|
||||
├── Pull to refresh trigger
|
||||
├── Successful action completion
|
||||
├── Errors and warnings
|
||||
├── Swipe action thresholds
|
||||
└── Important state changes
|
||||
|
||||
❌ DON'T use haptics for:
|
||||
├── Every scroll position
|
||||
├── Every list item
|
||||
├── Background events
|
||||
├── Passive displays
|
||||
└── Too frequently (haptic fatigue)
|
||||
```
|
||||
|
||||
### Haptic Intensity Mapping
|
||||
|
||||
| Action Importance | Haptic Level | Example |
|
||||
|-------------------|--------------|---------|
|
||||
| Minor/Browsing | Light / None | Scrolling, hovering |
|
||||
| Standard Action | Medium / Selection | Tap, toggle |
|
||||
| Significant Action | Heavy / Success | Complete, confirm |
|
||||
| Critical/Destructive | Heavy / Warning | Delete, payment |
|
||||
| Error | Error pattern | Failed action |
|
||||
|
||||
---
|
||||
|
||||
## 6. Mobile Cognitive Load
|
||||
|
||||
### How Mobile Differs from Desktop
|
||||
|
||||
| Factor | Desktop | Mobile | Implication |
|
||||
|--------|---------|--------|-------------|
|
||||
| **Attention** | Focused sessions | Interrupted constantly | Design for micro-sessions |
|
||||
| **Context** | Controlled environment | Anywhere, any condition | Handle bad lighting, noise |
|
||||
| **Multitasking** | Multiple windows | One app visible | Complete task in-app |
|
||||
| **Input speed** | Fast (keyboard) | Slow (touch typing) | Minimize input, smart defaults |
|
||||
| **Error recovery** | Easy (undo, back) | Harder (no keyboard shortcuts) | Prevent errors, easy recovery |
|
||||
|
||||
### Reducing Mobile Cognitive Load
|
||||
|
||||
```
|
||||
1. ONE PRIMARY ACTION per screen
|
||||
└── Clear what to do next
|
||||
|
||||
2. PROGRESSIVE DISCLOSURE
|
||||
└── Show only what's needed now
|
||||
|
||||
3. SMART DEFAULTS
|
||||
└── Pre-fill what you can
|
||||
|
||||
4. CHUNKING
|
||||
└── Break long forms into steps
|
||||
|
||||
5. RECOGNITION over RECALL
|
||||
└── Show options, don't make user remember
|
||||
|
||||
6. CONTEXT PERSISTENCE
|
||||
└── Save state on interrupt/background
|
||||
```
|
||||
|
||||
### Miller's Law for Mobile
|
||||
|
||||
```
|
||||
Desktop: 7±2 items in working memory
|
||||
Mobile: Reduce to 5±1 (more distractions)
|
||||
|
||||
Navigation: Max 5 tab bar items
|
||||
Options: Max 5 per menu level
|
||||
Steps: Max 5 visible steps in progress
|
||||
```
|
||||
|
||||
### Hick's Law for Mobile
|
||||
|
||||
```
|
||||
More choices = slower decisions
|
||||
|
||||
Mobile impact: Even worse than desktop
|
||||
├── Smaller screen = less overview
|
||||
├── Scrolling required = items forgotten
|
||||
├── Interruptions = lost context
|
||||
└── Decision fatigue faster
|
||||
|
||||
Solution: Progressive disclosure
|
||||
├── Start with 3-5 options
|
||||
├── "More" for additional
|
||||
├── Smart ordering (most used first)
|
||||
└── Previous selections remembered
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Touch Accessibility
|
||||
|
||||
### Motor Impairment Considerations
|
||||
|
||||
```
|
||||
Users with motor impairments may:
|
||||
├── Have tremors (need larger targets)
|
||||
├── Use assistive devices (different input method)
|
||||
├── Have limited reach (one-handed necessity)
|
||||
├── Need more time (avoid timeouts)
|
||||
└── Make accidental touches (need confirmation)
|
||||
|
||||
Design responses:
|
||||
├── Generous touch targets (48dp+)
|
||||
├── Adjustable timing for gestures
|
||||
├── Undo for destructive actions
|
||||
├── Switch control support
|
||||
└── Voice control support
|
||||
```
|
||||
|
||||
### Touch Target Spacing (A11y)
|
||||
|
||||
```
|
||||
WCAG 2.2 Success Criterion 2.5.8:
|
||||
|
||||
Touch targets MUST have:
|
||||
├── Width: ≥ 44px
|
||||
├── Height: ≥ 44px
|
||||
├── Spacing: ≥ 8px from adjacent targets
|
||||
|
||||
OR the target is:
|
||||
├── Inline (within text)
|
||||
├── User-controlled (user can resize)
|
||||
├── Essential (no alternative design)
|
||||
```
|
||||
|
||||
### Accessible Touch Patterns
|
||||
|
||||
| Pattern | Accessible Implementation |
|
||||
|---------|---------------------------|
|
||||
| Swipe actions | Provide menu alternative |
|
||||
| Drag and drop | Provide select + move option |
|
||||
| Pinch zoom | Provide zoom buttons |
|
||||
| Force touch | Provide long press alternative |
|
||||
| Shake gesture | Provide button alternative |
|
||||
|
||||
---
|
||||
|
||||
## 8. Emotion in Touch
|
||||
|
||||
### The Premium Feel
|
||||
|
||||
```
|
||||
What makes touch feel "premium":
|
||||
├── Instant response (< 50ms)
|
||||
├── Appropriate haptic feedback
|
||||
├── Smooth 60fps animations
|
||||
├── Correct resistance/physics
|
||||
├── Sound feedback (when appropriate)
|
||||
└── Attention to spring physics
|
||||
```
|
||||
|
||||
### Emotional Touch Feedback
|
||||
|
||||
| Emotion | Touch Response |
|
||||
|---------|----------------|
|
||||
| Success | Haptic success + confetti/check |
|
||||
| Error | Haptic error + shake animation |
|
||||
| Warning | Haptic warning + attention color |
|
||||
| Delight | Unexpected smooth animation |
|
||||
| Power | Heavy haptic on significant action |
|
||||
|
||||
### Trust Building Through Touch
|
||||
|
||||
```
|
||||
Trust signals in touch interactions:
|
||||
├── Consistent behavior (same action = same response)
|
||||
├── Reliable feedback (never fails silently)
|
||||
├── Secure feel for sensitive actions
|
||||
├── Professional animations (not janky)
|
||||
└── No accidental actions (confirmation for destructive)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Touch Psychology Checklist
|
||||
|
||||
### Before Every Screen
|
||||
|
||||
- [ ] **All touch targets ≥ 44-48px?**
|
||||
- [ ] **Primary CTA in thumb zone?**
|
||||
- [ ] **Destructive actions require confirmation?**
|
||||
- [ ] **Gesture alternatives exist (visible buttons)?**
|
||||
- [ ] **Haptic feedback on important actions?**
|
||||
- [ ] **Immediate visual feedback on tap?**
|
||||
- [ ] **Loading states for actions > 100ms?**
|
||||
|
||||
### Before Release
|
||||
|
||||
- [ ] **Tested on smallest supported device?**
|
||||
- [ ] **Tested one-handed on large phone?**
|
||||
- [ ] **All gestures have visible alternatives?**
|
||||
- [ ] **Haptics work correctly (test on device)?**
|
||||
- [ ] **Touch targets tested with accessibility settings?**
|
||||
- [ ] **No tiny close buttons or icons?**
|
||||
|
||||
---
|
||||
|
||||
## 10. Quick Reference Card
|
||||
|
||||
### Touch Target Sizes
|
||||
|
||||
```
|
||||
iOS Android WCAG
|
||||
Minimum: 44pt 48dp 44px
|
||||
Recommended: 48pt+ 56dp+ -
|
||||
Spacing: 8pt+ 8dp+ 8px+
|
||||
```
|
||||
|
||||
### Thumb Zone Actions
|
||||
|
||||
```
|
||||
TOP: Navigation, settings, back (infrequent)
|
||||
MIDDLE: Content, secondary actions
|
||||
BOTTOM: Primary CTA, tab bar, FAB (frequent)
|
||||
```
|
||||
|
||||
### Haptic Selection
|
||||
|
||||
```
|
||||
Light: Selection, toggle, minor
|
||||
Medium: Tap, standard action
|
||||
Heavy: Confirm, complete, drop
|
||||
Success: Task done
|
||||
Error: Failed action
|
||||
Warning: Attention needed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Every touch is a conversation between user and device. Make it feel natural, responsive, and respectful of human fingers—not precise cursor points.
|
||||
552
skills/nestjs-expert/SKILL.md
Normal file
552
skills/nestjs-expert/SKILL.md
Normal file
@@ -0,0 +1,552 @@
|
||||
---
|
||||
name: nestjs-expert
|
||||
description: 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.
|
||||
category: framework
|
||||
displayName: Nest.js Framework Expert
|
||||
color: red
|
||||
---
|
||||
|
||||
# Nest.js Expert
|
||||
|
||||
You are an expert in Nest.js with deep knowledge of enterprise-grade Node.js application architecture, dependency injection patterns, decorators, middleware, guards, interceptors, pipes, testing strategies, database integration, and authentication systems.
|
||||
|
||||
## When invoked:
|
||||
|
||||
0. If a more specialized expert fits better, recommend switching and stop:
|
||||
- Pure TypeScript type issues → typescript-type-expert
|
||||
- Database query optimization → database-expert
|
||||
- Node.js runtime issues → nodejs-expert
|
||||
- Frontend React issues → react-expert
|
||||
|
||||
Example: "This is a TypeScript type system issue. Use the typescript-type-expert subagent. Stopping here."
|
||||
|
||||
1. Detect Nest.js project setup using internal tools first (Read, Grep, Glob)
|
||||
2. Identify architecture patterns and existing modules
|
||||
3. Apply appropriate solutions following Nest.js best practices
|
||||
4. Validate in order: typecheck → unit tests → integration tests → e2e tests
|
||||
|
||||
## Domain Coverage
|
||||
|
||||
### Module Architecture & Dependency Injection
|
||||
- Common issues: Circular dependencies, provider scope conflicts, module imports
|
||||
- Root causes: Incorrect module boundaries, missing exports, improper injection tokens
|
||||
- Solution priority: 1) Refactor module structure, 2) Use forwardRef, 3) Adjust provider scope
|
||||
- Tools: `nest generate module`, `nest generate service`
|
||||
- Resources: [Nest.js Modules](https://docs.nestjs.com/modules), [Providers](https://docs.nestjs.com/providers)
|
||||
|
||||
### Controllers & Request Handling
|
||||
- Common issues: Route conflicts, DTO validation, response serialization
|
||||
- Root causes: Decorator misconfiguration, missing validation pipes, improper interceptors
|
||||
- Solution priority: 1) Fix decorator configuration, 2) Add validation, 3) Implement interceptors
|
||||
- Tools: `nest generate controller`, class-validator, class-transformer
|
||||
- Resources: [Controllers](https://docs.nestjs.com/controllers), [Validation](https://docs.nestjs.com/techniques/validation)
|
||||
|
||||
### Middleware, Guards, Interceptors & Pipes
|
||||
- Common issues: Execution order, context access, async operations
|
||||
- Root causes: Incorrect implementation, missing async/await, improper error handling
|
||||
- Solution priority: 1) Fix execution order, 2) Handle async properly, 3) Implement error handling
|
||||
- Execution order: Middleware → Guards → Interceptors (before) → Pipes → Route handler → Interceptors (after)
|
||||
- Resources: [Middleware](https://docs.nestjs.com/middleware), [Guards](https://docs.nestjs.com/guards)
|
||||
|
||||
### Testing Strategies (Jest & Supertest)
|
||||
- Common issues: Mocking dependencies, testing modules, e2e test setup
|
||||
- Root causes: Improper test module creation, missing mock providers, incorrect async handling
|
||||
- Solution priority: 1) Fix test module setup, 2) Mock dependencies correctly, 3) Handle async tests
|
||||
- Tools: `@nestjs/testing`, Jest, Supertest
|
||||
- Resources: [Testing](https://docs.nestjs.com/fundamentals/testing)
|
||||
|
||||
### Database Integration (TypeORM & Mongoose)
|
||||
- Common issues: Connection management, entity relationships, migrations
|
||||
- Root causes: Incorrect configuration, missing decorators, improper transaction handling
|
||||
- Solution priority: 1) Fix configuration, 2) Correct entity setup, 3) Implement transactions
|
||||
- TypeORM: `@nestjs/typeorm`, entity decorators, repository pattern
|
||||
- Mongoose: `@nestjs/mongoose`, schema decorators, model injection
|
||||
- Resources: [TypeORM](https://docs.nestjs.com/techniques/database), [Mongoose](https://docs.nestjs.com/techniques/mongodb)
|
||||
|
||||
### Authentication & Authorization (Passport.js)
|
||||
- Common issues: Strategy configuration, JWT handling, guard implementation
|
||||
- Root causes: Missing strategy setup, incorrect token validation, improper guard usage
|
||||
- Solution priority: 1) Configure Passport strategy, 2) Implement guards, 3) Handle JWT properly
|
||||
- Tools: `@nestjs/passport`, `@nestjs/jwt`, passport strategies
|
||||
- Resources: [Authentication](https://docs.nestjs.com/security/authentication), [Authorization](https://docs.nestjs.com/security/authorization)
|
||||
|
||||
### Configuration & Environment Management
|
||||
- Common issues: Environment variables, configuration validation, async configuration
|
||||
- Root causes: Missing config module, improper validation, incorrect async loading
|
||||
- Solution priority: 1) Setup ConfigModule, 2) Add validation, 3) Handle async config
|
||||
- Tools: `@nestjs/config`, Joi validation
|
||||
- Resources: [Configuration](https://docs.nestjs.com/techniques/configuration)
|
||||
|
||||
### Error Handling & Logging
|
||||
- Common issues: Exception filters, logging configuration, error propagation
|
||||
- Root causes: Missing exception filters, improper logger setup, unhandled promises
|
||||
- Solution priority: 1) Implement exception filters, 2) Configure logger, 3) Handle all errors
|
||||
- Tools: Built-in Logger, custom exception filters
|
||||
- Resources: [Exception Filters](https://docs.nestjs.com/exception-filters), [Logger](https://docs.nestjs.com/techniques/logger)
|
||||
|
||||
## Environmental Adaptation
|
||||
|
||||
### Detection Phase
|
||||
I analyze the project to understand:
|
||||
- Nest.js version and configuration
|
||||
- Module structure and organization
|
||||
- Database setup (TypeORM/Mongoose/Prisma)
|
||||
- Testing framework configuration
|
||||
- Authentication implementation
|
||||
|
||||
Detection commands:
|
||||
```bash
|
||||
# Check Nest.js setup
|
||||
test -f nest-cli.json && echo "Nest.js CLI project detected"
|
||||
grep -q "@nestjs/core" package.json && echo "Nest.js framework installed"
|
||||
test -f tsconfig.json && echo "TypeScript configuration found"
|
||||
|
||||
# Detect Nest.js version
|
||||
grep "@nestjs/core" package.json | sed 's/.*"\([0-9\.]*\)".*/Nest.js version: \1/'
|
||||
|
||||
# Check database setup
|
||||
grep -q "@nestjs/typeorm" package.json && echo "TypeORM integration detected"
|
||||
grep -q "@nestjs/mongoose" package.json && echo "Mongoose integration detected"
|
||||
grep -q "@prisma/client" package.json && echo "Prisma ORM detected"
|
||||
|
||||
# Check authentication
|
||||
grep -q "@nestjs/passport" package.json && echo "Passport authentication detected"
|
||||
grep -q "@nestjs/jwt" package.json && echo "JWT authentication detected"
|
||||
|
||||
# Analyze module structure
|
||||
find src -name "*.module.ts" -type f | head -5 | xargs -I {} basename {} .module.ts
|
||||
```
|
||||
|
||||
**Safety note**: Avoid watch/serve processes; use one-shot diagnostics only.
|
||||
|
||||
### Adaptation Strategies
|
||||
- Match existing module patterns and naming conventions
|
||||
- Follow established testing patterns
|
||||
- Respect database strategy (repository pattern vs active record)
|
||||
- Use existing authentication guards and strategies
|
||||
|
||||
## Tool Integration
|
||||
|
||||
### Diagnostic Tools
|
||||
```bash
|
||||
# Analyze module dependencies
|
||||
nest info
|
||||
|
||||
# Check for circular dependencies
|
||||
npm run build -- --watch=false
|
||||
|
||||
# Validate module structure
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Fix Validation
|
||||
```bash
|
||||
# Verify fixes (validation order)
|
||||
npm run build # 1. Typecheck first
|
||||
npm run test # 2. Run unit tests
|
||||
npm run test:e2e # 3. Run e2e tests if needed
|
||||
```
|
||||
|
||||
**Validation order**: typecheck → unit tests → integration tests → e2e tests
|
||||
|
||||
## Problem-Specific Approaches (Real Issues from GitHub & Stack Overflow)
|
||||
|
||||
### 1. "Nest can't resolve dependencies of the [Service] (?)"
|
||||
**Frequency**: HIGHEST (500+ GitHub issues) | **Complexity**: LOW-MEDIUM
|
||||
**Real Examples**: GitHub #3186, #886, #2359 | SO 75483101
|
||||
When encountering this error:
|
||||
1. Check if provider is in module's providers array
|
||||
2. Verify module exports if crossing boundaries
|
||||
3. Check for typos in provider names (GitHub #598 - misleading error)
|
||||
4. Review import order in barrel exports (GitHub #9095)
|
||||
|
||||
### 2. "Circular dependency detected"
|
||||
**Frequency**: HIGH | **Complexity**: HIGH
|
||||
**Real Examples**: SO 65671318 (32 votes) | Multiple GitHub discussions
|
||||
Community-proven solutions:
|
||||
1. Use forwardRef() on BOTH sides of the dependency
|
||||
2. Extract shared logic to a third module (recommended)
|
||||
3. Consider if circular dependency indicates design flaw
|
||||
4. Note: Community warns forwardRef() can mask deeper issues
|
||||
|
||||
### 3. "Cannot test e2e because Nestjs doesn't resolve dependencies"
|
||||
**Frequency**: HIGH | **Complexity**: MEDIUM
|
||||
**Real Examples**: SO 75483101, 62942112, 62822943
|
||||
Proven testing solutions:
|
||||
1. Use @golevelup/ts-jest for createMock() helper
|
||||
2. Mock JwtService in test module providers
|
||||
3. Import all required modules in Test.createTestingModule()
|
||||
4. For Bazel users: Special configuration needed (SO 62942112)
|
||||
|
||||
### 4. "[TypeOrmModule] Unable to connect to the database"
|
||||
**Frequency**: MEDIUM | **Complexity**: HIGH
|
||||
**Real Examples**: GitHub typeorm#1151, #520, #2692
|
||||
Key insight - this error is often misleading:
|
||||
1. Check entity configuration - @Column() not @Column('description')
|
||||
2. For multiple DBs: Use named connections (GitHub #2692)
|
||||
3. Implement connection error handling to prevent app crash (#520)
|
||||
4. SQLite: Verify database file path (typeorm#8745)
|
||||
|
||||
### 5. "Unknown authentication strategy 'jwt'"
|
||||
**Frequency**: HIGH | **Complexity**: LOW
|
||||
**Real Examples**: SO 79201800, 74763077, 62799708
|
||||
Common JWT authentication fixes:
|
||||
1. Import Strategy from 'passport-jwt' NOT 'passport-local'
|
||||
2. Ensure JwtModule.secret matches JwtStrategy.secretOrKey
|
||||
3. Check Bearer token format in Authorization header
|
||||
4. Set JWT_SECRET environment variable
|
||||
|
||||
### 6. "ActorModule exporting itself instead of ActorService"
|
||||
**Frequency**: MEDIUM | **Complexity**: LOW
|
||||
**Real Example**: GitHub #866
|
||||
Module export configuration fix:
|
||||
1. Export the SERVICE not the MODULE from exports array
|
||||
2. Common mistake: exports: [ActorModule] → exports: [ActorService]
|
||||
3. Check all module exports for this pattern
|
||||
4. Validate with nest info command
|
||||
|
||||
### 7. "secretOrPrivateKey must have a value" (JWT)
|
||||
**Frequency**: HIGH | **Complexity**: LOW
|
||||
**Real Examples**: Multiple community reports
|
||||
JWT configuration fixes:
|
||||
1. Set JWT_SECRET in environment variables
|
||||
2. Check ConfigModule loads before JwtModule
|
||||
3. Verify .env file is in correct location
|
||||
4. Use ConfigService for dynamic configuration
|
||||
|
||||
### 8. Version-Specific Regressions
|
||||
**Frequency**: LOW | **Complexity**: MEDIUM
|
||||
**Real Example**: GitHub #2359 (v6.3.1 regression)
|
||||
Handling version-specific bugs:
|
||||
1. Check GitHub issues for your specific version
|
||||
2. Try downgrading to previous stable version
|
||||
3. Update to latest patch version
|
||||
4. Report regressions with minimal reproduction
|
||||
|
||||
### 9. "Nest can't resolve dependencies of the UserController (?, +)"
|
||||
**Frequency**: HIGH | **Complexity**: LOW
|
||||
**Real Example**: GitHub #886
|
||||
Controller dependency resolution:
|
||||
1. The "?" indicates missing provider at that position
|
||||
2. Count constructor parameters to identify which is missing
|
||||
3. Add missing service to module providers
|
||||
4. Check service is properly decorated with @Injectable()
|
||||
|
||||
### 10. "Nest can't resolve dependencies of the Repository" (Testing)
|
||||
**Frequency**: MEDIUM | **Complexity**: MEDIUM
|
||||
**Real Examples**: Community reports
|
||||
TypeORM repository testing:
|
||||
1. Use getRepositoryToken(Entity) for provider token
|
||||
2. Mock DataSource in test module
|
||||
3. Provide test database connection
|
||||
4. Consider mocking repository completely
|
||||
|
||||
### 11. "Unauthorized 401 (Missing credentials)" with Passport JWT
|
||||
**Frequency**: HIGH | **Complexity**: LOW
|
||||
**Real Example**: SO 74763077
|
||||
JWT authentication debugging:
|
||||
1. Verify Authorization header format: "Bearer [token]"
|
||||
2. Check token expiration (use longer exp for testing)
|
||||
3. Test without nginx/proxy to isolate issue
|
||||
4. Use jwt.io to decode and verify token structure
|
||||
|
||||
### 12. Memory Leaks in Production
|
||||
**Frequency**: LOW | **Complexity**: HIGH
|
||||
**Real Examples**: Community reports
|
||||
Memory leak detection and fixes:
|
||||
1. Profile with node --inspect and Chrome DevTools
|
||||
2. Remove event listeners in onModuleDestroy()
|
||||
3. Close database connections properly
|
||||
4. Monitor heap snapshots over time
|
||||
|
||||
### 13. "More informative error message when dependencies are improperly setup"
|
||||
**Frequency**: N/A | **Complexity**: N/A
|
||||
**Real Example**: GitHub #223 (Feature Request)
|
||||
Debugging dependency injection:
|
||||
1. NestJS errors are intentionally generic for security
|
||||
2. Use verbose logging during development
|
||||
3. Add custom error messages in your providers
|
||||
4. Consider using dependency injection debugging tools
|
||||
|
||||
### 14. Multiple Database Connections
|
||||
**Frequency**: MEDIUM | **Complexity**: MEDIUM
|
||||
**Real Example**: GitHub #2692
|
||||
Configuring multiple databases:
|
||||
1. Use named connections in TypeOrmModule
|
||||
2. Specify connection name in @InjectRepository()
|
||||
3. Configure separate connection options
|
||||
4. Test each connection independently
|
||||
|
||||
### 15. "Connection with sqlite database is not established"
|
||||
**Frequency**: LOW | **Complexity**: LOW
|
||||
**Real Example**: typeorm#8745
|
||||
SQLite-specific issues:
|
||||
1. Check database file path is absolute
|
||||
2. Ensure directory exists before connection
|
||||
3. Verify file permissions
|
||||
4. Use synchronize: true for development
|
||||
|
||||
### 16. Misleading "Unable to connect" Errors
|
||||
**Frequency**: MEDIUM | **Complexity**: HIGH
|
||||
**Real Example**: typeorm#1151
|
||||
True causes of connection errors:
|
||||
1. Entity syntax errors show as connection errors
|
||||
2. Wrong decorator usage: @Column() not @Column('description')
|
||||
3. Missing decorators on entity properties
|
||||
4. Always check entity files when connection errors occur
|
||||
|
||||
### 17. "Typeorm connection error breaks entire nestjs application"
|
||||
**Frequency**: MEDIUM | **Complexity**: MEDIUM
|
||||
**Real Example**: typeorm#520
|
||||
Preventing app crash on DB failure:
|
||||
1. Wrap connection in try-catch in useFactory
|
||||
2. Allow app to start without database
|
||||
3. Implement health checks for DB status
|
||||
4. Use retryAttempts and retryDelay options
|
||||
|
||||
## Common Patterns & Solutions
|
||||
|
||||
### Module Organization
|
||||
```typescript
|
||||
// Feature module pattern
|
||||
@Module({
|
||||
imports: [CommonModule, DatabaseModule],
|
||||
controllers: [FeatureController],
|
||||
providers: [FeatureService, FeatureRepository],
|
||||
exports: [FeatureService] // Export for other modules
|
||||
})
|
||||
export class FeatureModule {}
|
||||
```
|
||||
|
||||
### Custom Decorator Pattern
|
||||
```typescript
|
||||
// Combine multiple decorators
|
||||
export const Auth = (...roles: Role[]) =>
|
||||
applyDecorators(
|
||||
UseGuards(JwtAuthGuard, RolesGuard),
|
||||
Roles(...roles),
|
||||
);
|
||||
```
|
||||
|
||||
### Testing Pattern
|
||||
```typescript
|
||||
// Comprehensive test setup
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
providers: [
|
||||
ServiceUnderTest,
|
||||
{
|
||||
provide: DependencyService,
|
||||
useValue: mockDependency,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<ServiceUnderTest>(ServiceUnderTest);
|
||||
});
|
||||
```
|
||||
|
||||
### Exception Filter Pattern
|
||||
```typescript
|
||||
@Catch(HttpException)
|
||||
export class HttpExceptionFilter implements ExceptionFilter {
|
||||
catch(exception: HttpException, host: ArgumentsHost) {
|
||||
// Custom error handling
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Code Review Checklist
|
||||
|
||||
When reviewing Nest.js applications, focus on:
|
||||
|
||||
### Module Architecture & Dependency Injection
|
||||
- [ ] All services are properly decorated with @Injectable()
|
||||
- [ ] Providers are listed in module's providers array and exports when needed
|
||||
- [ ] No circular dependencies between modules (check for forwardRef usage)
|
||||
- [ ] Module boundaries follow domain/feature separation
|
||||
- [ ] Custom providers use proper injection tokens (avoid string tokens)
|
||||
|
||||
### Testing & Mocking
|
||||
- [ ] Test modules use minimal, focused provider mocks
|
||||
- [ ] TypeORM repositories use getRepositoryToken(Entity) for mocking
|
||||
- [ ] No actual database dependencies in unit tests
|
||||
- [ ] All async operations are properly awaited in tests
|
||||
- [ ] JwtService and external dependencies are mocked appropriately
|
||||
|
||||
### Database Integration (TypeORM Focus)
|
||||
- [ ] Entity decorators use correct syntax (@Column() not @Column('description'))
|
||||
- [ ] Connection errors don't crash the entire application
|
||||
- [ ] Multiple database connections use named connections
|
||||
- [ ] Database connections have proper error handling and retry logic
|
||||
- [ ] Entities are properly registered in TypeOrmModule.forFeature()
|
||||
|
||||
### Authentication & Security (JWT + Passport)
|
||||
- [ ] JWT Strategy imports from 'passport-jwt' not 'passport-local'
|
||||
- [ ] JwtModule secret matches JwtStrategy secretOrKey exactly
|
||||
- [ ] Authorization headers follow 'Bearer [token]' format
|
||||
- [ ] Token expiration times are appropriate for use case
|
||||
- [ ] JWT_SECRET environment variable is properly configured
|
||||
|
||||
### Request Lifecycle & Middleware
|
||||
- [ ] Middleware execution order follows: Middleware → Guards → Interceptors → Pipes
|
||||
- [ ] Guards properly protect routes and return boolean/throw exceptions
|
||||
- [ ] Interceptors handle async operations correctly
|
||||
- [ ] Exception filters catch and transform errors appropriately
|
||||
- [ ] Pipes validate DTOs with class-validator decorators
|
||||
|
||||
### Performance & Optimization
|
||||
- [ ] Caching is implemented for expensive operations
|
||||
- [ ] Database queries avoid N+1 problems (use DataLoader pattern)
|
||||
- [ ] Connection pooling is configured for database connections
|
||||
- [ ] Memory leaks are prevented (clean up event listeners)
|
||||
- [ ] Compression middleware is enabled for production
|
||||
|
||||
## Decision Trees for Architecture
|
||||
|
||||
### Choosing Database ORM
|
||||
```
|
||||
Project Requirements:
|
||||
├─ Need migrations? → TypeORM or Prisma
|
||||
├─ NoSQL database? → Mongoose
|
||||
├─ Type safety priority? → Prisma
|
||||
├─ Complex relations? → TypeORM
|
||||
└─ Existing database? → TypeORM (better legacy support)
|
||||
```
|
||||
|
||||
### Module Organization Strategy
|
||||
```
|
||||
Feature Complexity:
|
||||
├─ Simple CRUD → Single module with controller + service
|
||||
├─ Domain logic → Separate domain module + infrastructure
|
||||
├─ Shared logic → Create shared module with exports
|
||||
├─ Microservice → Separate app with message patterns
|
||||
└─ External API → Create client module with HttpModule
|
||||
```
|
||||
|
||||
### Testing Strategy Selection
|
||||
```
|
||||
Test Type Required:
|
||||
├─ Business logic → Unit tests with mocks
|
||||
├─ API contracts → Integration tests with test database
|
||||
├─ User flows → E2E tests with Supertest
|
||||
├─ Performance → Load tests with k6 or Artillery
|
||||
└─ Security → OWASP ZAP or security middleware tests
|
||||
```
|
||||
|
||||
### Authentication Method
|
||||
```
|
||||
Security Requirements:
|
||||
├─ Stateless API → JWT with refresh tokens
|
||||
├─ Session-based → Express sessions with Redis
|
||||
├─ OAuth/Social → Passport with provider strategies
|
||||
├─ Multi-tenant → JWT with tenant claims
|
||||
└─ Microservices → Service-to-service auth with mTLS
|
||||
```
|
||||
|
||||
### Caching Strategy
|
||||
```
|
||||
Data Characteristics:
|
||||
├─ User-specific → Redis with user key prefix
|
||||
├─ Global data → In-memory cache with TTL
|
||||
├─ Database results → Query result cache
|
||||
├─ Static assets → CDN with cache headers
|
||||
└─ Computed values → Memoization decorators
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Caching Strategies
|
||||
- Use built-in cache manager for response caching
|
||||
- Implement cache interceptors for expensive operations
|
||||
- Configure TTL based on data volatility
|
||||
- Use Redis for distributed caching
|
||||
|
||||
### Database Optimization
|
||||
- Use DataLoader pattern for N+1 query problems
|
||||
- Implement proper indexes on frequently queried fields
|
||||
- Use query builder for complex queries vs. ORM methods
|
||||
- Enable query logging in development for analysis
|
||||
|
||||
### Request Processing
|
||||
- Implement compression middleware
|
||||
- Use streaming for large responses
|
||||
- Configure proper rate limiting
|
||||
- Enable clustering for multi-core utilization
|
||||
|
||||
## External Resources
|
||||
|
||||
### Core Documentation
|
||||
- [Nest.js Documentation](https://docs.nestjs.com)
|
||||
- [Nest.js CLI](https://docs.nestjs.com/cli/overview)
|
||||
- [Nest.js Recipes](https://docs.nestjs.com/recipes)
|
||||
|
||||
### Testing Resources
|
||||
- [Jest Documentation](https://jestjs.io/docs/getting-started)
|
||||
- [Supertest](https://github.com/visionmedia/supertest)
|
||||
- [Testing Best Practices](https://github.com/goldbergyoni/javascript-testing-best-practices)
|
||||
|
||||
### Database Resources
|
||||
- [TypeORM Documentation](https://typeorm.io)
|
||||
- [Mongoose Documentation](https://mongoosejs.com)
|
||||
|
||||
### Authentication
|
||||
- [Passport.js Strategies](http://www.passportjs.org)
|
||||
- [JWT Best Practices](https://tools.ietf.org/html/rfc8725)
|
||||
|
||||
## Quick Reference Patterns
|
||||
|
||||
### Dependency Injection Tokens
|
||||
```typescript
|
||||
// Custom provider token
|
||||
export const CONFIG_OPTIONS = Symbol('CONFIG_OPTIONS');
|
||||
|
||||
// Usage in module
|
||||
@Module({
|
||||
providers: [
|
||||
{
|
||||
provide: CONFIG_OPTIONS,
|
||||
useValue: { apiUrl: 'https://api.example.com' }
|
||||
}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
### Global Module Pattern
|
||||
```typescript
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [GlobalService],
|
||||
exports: [GlobalService],
|
||||
})
|
||||
export class GlobalModule {}
|
||||
```
|
||||
|
||||
### Dynamic Module Pattern
|
||||
```typescript
|
||||
@Module({})
|
||||
export class ConfigModule {
|
||||
static forRoot(options: ConfigOptions): DynamicModule {
|
||||
return {
|
||||
module: ConfigModule,
|
||||
providers: [
|
||||
{
|
||||
provide: 'CONFIG_OPTIONS',
|
||||
useValue: options,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Success Metrics
|
||||
- ✅ Problem correctly identified and located in module structure
|
||||
- ✅ Solution follows Nest.js architectural patterns
|
||||
- ✅ All tests pass (unit, integration, e2e)
|
||||
- ✅ No circular dependencies introduced
|
||||
- ✅ Performance metrics maintained or improved
|
||||
- ✅ Code follows established project conventions
|
||||
- ✅ Proper error handling implemented
|
||||
- ✅ Security best practices applied
|
||||
- ✅ Documentation updated for API changes
|
||||
203
skills/nextjs-best-practices/SKILL.md
Normal file
203
skills/nextjs-best-practices/SKILL.md
Normal file
@@ -0,0 +1,203 @@
|
||||
---
|
||||
name: nextjs-best-practices
|
||||
description: Next.js App Router principles. Server Components, data fetching, routing patterns.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# Next.js Best Practices
|
||||
|
||||
> Principles for Next.js App Router development.
|
||||
|
||||
---
|
||||
|
||||
## 1. Server vs Client Components
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
Does it need...?
|
||||
│
|
||||
├── useState, useEffect, event handlers
|
||||
│ └── Client Component ('use client')
|
||||
│
|
||||
├── Direct data fetching, no interactivity
|
||||
│ └── Server Component (default)
|
||||
│
|
||||
└── Both?
|
||||
└── Split: Server parent + Client child
|
||||
```
|
||||
|
||||
### By Default
|
||||
|
||||
| Type | Use |
|
||||
|------|-----|
|
||||
| **Server** | Data fetching, layout, static content |
|
||||
| **Client** | Forms, buttons, interactive UI |
|
||||
|
||||
---
|
||||
|
||||
## 2. Data Fetching Patterns
|
||||
|
||||
### Fetch Strategy
|
||||
|
||||
| Pattern | Use |
|
||||
|---------|-----|
|
||||
| **Default** | Static (cached at build) |
|
||||
| **Revalidate** | ISR (time-based refresh) |
|
||||
| **No-store** | Dynamic (every request) |
|
||||
|
||||
### Data Flow
|
||||
|
||||
| Source | Pattern |
|
||||
|--------|---------|
|
||||
| Database | Server Component fetch |
|
||||
| API | fetch with caching |
|
||||
| User input | Client state + server action |
|
||||
|
||||
---
|
||||
|
||||
## 3. Routing Principles
|
||||
|
||||
### File Conventions
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `page.tsx` | Route UI |
|
||||
| `layout.tsx` | Shared layout |
|
||||
| `loading.tsx` | Loading state |
|
||||
| `error.tsx` | Error boundary |
|
||||
| `not-found.tsx` | 404 page |
|
||||
|
||||
### Route Organization
|
||||
|
||||
| Pattern | Use |
|
||||
|---------|-----|
|
||||
| Route groups `(name)` | Organize without URL |
|
||||
| Parallel routes `@slot` | Multiple same-level pages |
|
||||
| Intercepting `(.)` | Modal overlays |
|
||||
|
||||
---
|
||||
|
||||
## 4. API Routes
|
||||
|
||||
### Route Handlers
|
||||
|
||||
| Method | Use |
|
||||
|--------|-----|
|
||||
| GET | Read data |
|
||||
| POST | Create data |
|
||||
| PUT/PATCH | Update data |
|
||||
| DELETE | Remove data |
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Validate input with Zod
|
||||
- Return proper status codes
|
||||
- Handle errors gracefully
|
||||
- Use Edge runtime when possible
|
||||
|
||||
---
|
||||
|
||||
## 5. Performance Principles
|
||||
|
||||
### Image Optimization
|
||||
|
||||
- Use next/image component
|
||||
- Set priority for above-fold
|
||||
- Provide blur placeholder
|
||||
- Use responsive sizes
|
||||
|
||||
### Bundle Optimization
|
||||
|
||||
- Dynamic imports for heavy components
|
||||
- Route-based code splitting (automatic)
|
||||
- Analyze with bundle analyzer
|
||||
|
||||
---
|
||||
|
||||
## 6. Metadata
|
||||
|
||||
### Static vs Dynamic
|
||||
|
||||
| Type | Use |
|
||||
|------|-----|
|
||||
| Static export | Fixed metadata |
|
||||
| generateMetadata | Dynamic per-route |
|
||||
|
||||
### Essential Tags
|
||||
|
||||
- title (50-60 chars)
|
||||
- description (150-160 chars)
|
||||
- Open Graph images
|
||||
- Canonical URL
|
||||
|
||||
---
|
||||
|
||||
## 7. Caching Strategy
|
||||
|
||||
### Cache Layers
|
||||
|
||||
| Layer | Control |
|
||||
|-------|---------|
|
||||
| Request | fetch options |
|
||||
| Data | revalidate/tags |
|
||||
| Full route | route config |
|
||||
|
||||
### Revalidation
|
||||
|
||||
| Method | Use |
|
||||
|--------|-----|
|
||||
| Time-based | `revalidate: 60` |
|
||||
| On-demand | `revalidatePath/Tag` |
|
||||
| No cache | `no-store` |
|
||||
|
||||
---
|
||||
|
||||
## 8. Server Actions
|
||||
|
||||
### Use Cases
|
||||
|
||||
- Form submissions
|
||||
- Data mutations
|
||||
- Revalidation triggers
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Mark with 'use server'
|
||||
- Validate all inputs
|
||||
- Return typed responses
|
||||
- Handle errors
|
||||
|
||||
---
|
||||
|
||||
## 9. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| 'use client' everywhere | Server by default |
|
||||
| Fetch in client components | Fetch in server |
|
||||
| Skip loading states | Use loading.tsx |
|
||||
| Ignore error boundaries | Use error.tsx |
|
||||
| Large client bundles | Dynamic imports |
|
||||
|
||||
---
|
||||
|
||||
## 10. Project Structure
|
||||
|
||||
```
|
||||
app/
|
||||
├── (marketing)/ # Route group
|
||||
│ └── page.tsx
|
||||
├── (dashboard)/
|
||||
│ ├── layout.tsx # Dashboard layout
|
||||
│ └── page.tsx
|
||||
├── api/
|
||||
│ └── [resource]/
|
||||
│ └── route.ts
|
||||
└── components/
|
||||
└── ui/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Server Components are the default for a reason. Start there, add client only when needed.
|
||||
333
skills/nodejs-best-practices/SKILL.md
Normal file
333
skills/nodejs-best-practices/SKILL.md
Normal file
@@ -0,0 +1,333 @@
|
||||
---
|
||||
name: nodejs-best-practices
|
||||
description: Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# Node.js Best Practices
|
||||
|
||||
> Principles and decision-making for Node.js development in 2025.
|
||||
> **Learn to THINK, not memorize code patterns.**
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ How to Use This Skill
|
||||
|
||||
This skill teaches **decision-making principles**, not fixed code to copy.
|
||||
|
||||
- ASK user for preferences when unclear
|
||||
- Choose framework/pattern based on CONTEXT
|
||||
- Don't default to same solution every time
|
||||
|
||||
---
|
||||
|
||||
## 1. Framework Selection (2025)
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
What are you building?
|
||||
│
|
||||
├── Edge/Serverless (Cloudflare, Vercel)
|
||||
│ └── Hono (zero-dependency, ultra-fast cold starts)
|
||||
│
|
||||
├── High Performance API
|
||||
│ └── Fastify (2-3x faster than Express)
|
||||
│
|
||||
├── Enterprise/Team familiarity
|
||||
│ └── NestJS (structured, DI, decorators)
|
||||
│
|
||||
├── Legacy/Stable/Maximum ecosystem
|
||||
│ └── Express (mature, most middleware)
|
||||
│
|
||||
└── Full-stack with frontend
|
||||
└── Next.js API Routes or tRPC
|
||||
```
|
||||
|
||||
### Comparison Principles
|
||||
|
||||
| Factor | Hono | Fastify | Express |
|
||||
|--------|------|---------|---------|
|
||||
| **Best for** | Edge, serverless | Performance | Legacy, learning |
|
||||
| **Cold start** | Fastest | Fast | Moderate |
|
||||
| **Ecosystem** | Growing | Good | Largest |
|
||||
| **TypeScript** | Native | Excellent | Good |
|
||||
| **Learning curve** | Low | Medium | Low |
|
||||
|
||||
### Selection Questions to Ask:
|
||||
1. What's the deployment target?
|
||||
2. Is cold start time critical?
|
||||
3. Does team have existing experience?
|
||||
4. Is there legacy code to maintain?
|
||||
|
||||
---
|
||||
|
||||
## 2. Runtime Considerations (2025)
|
||||
|
||||
### Native TypeScript
|
||||
|
||||
```
|
||||
Node.js 22+: --experimental-strip-types
|
||||
├── Run .ts files directly
|
||||
├── No build step needed for simple projects
|
||||
└── Consider for: scripts, simple APIs
|
||||
```
|
||||
|
||||
### Module System Decision
|
||||
|
||||
```
|
||||
ESM (import/export)
|
||||
├── Modern standard
|
||||
├── Better tree-shaking
|
||||
├── Async module loading
|
||||
└── Use for: new projects
|
||||
|
||||
CommonJS (require)
|
||||
├── Legacy compatibility
|
||||
├── More npm packages support
|
||||
└── Use for: existing codebases, some edge cases
|
||||
```
|
||||
|
||||
### Runtime Selection
|
||||
|
||||
| Runtime | Best For |
|
||||
|---------|----------|
|
||||
| **Node.js** | General purpose, largest ecosystem |
|
||||
| **Bun** | Performance, built-in bundler |
|
||||
| **Deno** | Security-first, built-in TypeScript |
|
||||
|
||||
---
|
||||
|
||||
## 3. Architecture Principles
|
||||
|
||||
### Layered Structure Concept
|
||||
|
||||
```
|
||||
Request Flow:
|
||||
│
|
||||
├── Controller/Route Layer
|
||||
│ ├── Handles HTTP specifics
|
||||
│ ├── Input validation at boundary
|
||||
│ └── Calls service layer
|
||||
│
|
||||
├── Service Layer
|
||||
│ ├── Business logic
|
||||
│ ├── Framework-agnostic
|
||||
│ └── Calls repository layer
|
||||
│
|
||||
└── Repository Layer
|
||||
├── Data access only
|
||||
├── Database queries
|
||||
└── ORM interactions
|
||||
```
|
||||
|
||||
### Why This Matters:
|
||||
- **Testability**: Mock layers independently
|
||||
- **Flexibility**: Swap database without touching business logic
|
||||
- **Clarity**: Each layer has single responsibility
|
||||
|
||||
### When to Simplify:
|
||||
- Small scripts → Single file OK
|
||||
- Prototypes → Less structure acceptable
|
||||
- Always ask: "Will this grow?"
|
||||
|
||||
---
|
||||
|
||||
## 4. Error Handling Principles
|
||||
|
||||
### Centralized Error Handling
|
||||
|
||||
```
|
||||
Pattern:
|
||||
├── Create custom error classes
|
||||
├── Throw from any layer
|
||||
├── Catch at top level (middleware)
|
||||
└── Format consistent response
|
||||
```
|
||||
|
||||
### Error Response Philosophy
|
||||
|
||||
```
|
||||
Client gets:
|
||||
├── Appropriate HTTP status
|
||||
├── Error code for programmatic handling
|
||||
├── User-friendly message
|
||||
└── NO internal details (security!)
|
||||
|
||||
Logs get:
|
||||
├── Full stack trace
|
||||
├── Request context
|
||||
├── User ID (if applicable)
|
||||
└── Timestamp
|
||||
```
|
||||
|
||||
### Status Code Selection
|
||||
|
||||
| Situation | Status | When |
|
||||
|-----------|--------|------|
|
||||
| Bad input | 400 | Client sent invalid data |
|
||||
| No auth | 401 | Missing or invalid credentials |
|
||||
| No permission | 403 | Valid auth, but not allowed |
|
||||
| Not found | 404 | Resource doesn't exist |
|
||||
| Conflict | 409 | Duplicate or state conflict |
|
||||
| Validation | 422 | Schema valid but business rules fail |
|
||||
| Server error | 500 | Our fault, log everything |
|
||||
|
||||
---
|
||||
|
||||
## 5. Async Patterns Principles
|
||||
|
||||
### When to Use Each
|
||||
|
||||
| Pattern | Use When |
|
||||
|---------|----------|
|
||||
| `async/await` | Sequential async operations |
|
||||
| `Promise.all` | Parallel independent operations |
|
||||
| `Promise.allSettled` | Parallel where some can fail |
|
||||
| `Promise.race` | Timeout or first response wins |
|
||||
|
||||
### Event Loop Awareness
|
||||
|
||||
```
|
||||
I/O-bound (async helps):
|
||||
├── Database queries
|
||||
├── HTTP requests
|
||||
├── File system
|
||||
└── Network operations
|
||||
|
||||
CPU-bound (async doesn't help):
|
||||
├── Crypto operations
|
||||
├── Image processing
|
||||
├── Complex calculations
|
||||
└── → Use worker threads or offload
|
||||
```
|
||||
|
||||
### Avoiding Event Loop Blocking
|
||||
|
||||
- Never use sync methods in production (fs.readFileSync, etc.)
|
||||
- Offload CPU-intensive work
|
||||
- Use streaming for large data
|
||||
|
||||
---
|
||||
|
||||
## 6. Validation Principles
|
||||
|
||||
### Validate at Boundaries
|
||||
|
||||
```
|
||||
Where to validate:
|
||||
├── API entry point (request body/params)
|
||||
├── Before database operations
|
||||
├── External data (API responses, file uploads)
|
||||
└── Environment variables (startup)
|
||||
```
|
||||
|
||||
### Validation Library Selection
|
||||
|
||||
| Library | Best For |
|
||||
|---------|----------|
|
||||
| **Zod** | TypeScript first, inference |
|
||||
| **Valibot** | Smaller bundle (tree-shakeable) |
|
||||
| **ArkType** | Performance critical |
|
||||
| **Yup** | Existing React Form usage |
|
||||
|
||||
### Validation Philosophy
|
||||
|
||||
- Fail fast: Validate early
|
||||
- Be specific: Clear error messages
|
||||
- Don't trust: Even "internal" data
|
||||
|
||||
---
|
||||
|
||||
## 7. Security Principles
|
||||
|
||||
### Security Checklist (Not Code)
|
||||
|
||||
- [ ] **Input validation**: All inputs validated
|
||||
- [ ] **Parameterized queries**: No string concatenation for SQL
|
||||
- [ ] **Password hashing**: bcrypt or argon2
|
||||
- [ ] **JWT verification**: Always verify signature and expiry
|
||||
- [ ] **Rate limiting**: Protect from abuse
|
||||
- [ ] **Security headers**: Helmet.js or equivalent
|
||||
- [ ] **HTTPS**: Everywhere in production
|
||||
- [ ] **CORS**: Properly configured
|
||||
- [ ] **Secrets**: Environment variables only
|
||||
- [ ] **Dependencies**: Regularly audited
|
||||
|
||||
### Security Mindset
|
||||
|
||||
```
|
||||
Trust nothing:
|
||||
├── Query params → validate
|
||||
├── Request body → validate
|
||||
├── Headers → verify
|
||||
├── Cookies → validate
|
||||
├── File uploads → scan
|
||||
└── External APIs → validate response
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Testing Principles
|
||||
|
||||
### Test Strategy Selection
|
||||
|
||||
| Type | Purpose | Tools |
|
||||
|------|---------|-------|
|
||||
| **Unit** | Business logic | node:test, Vitest |
|
||||
| **Integration** | API endpoints | Supertest |
|
||||
| **E2E** | Full flows | Playwright |
|
||||
|
||||
### What to Test (Priorities)
|
||||
|
||||
1. **Critical paths**: Auth, payments, core business
|
||||
2. **Edge cases**: Empty inputs, boundaries
|
||||
3. **Error handling**: What happens when things fail?
|
||||
4. **Not worth testing**: Framework code, trivial getters
|
||||
|
||||
### Built-in Test Runner (Node.js 22+)
|
||||
|
||||
```
|
||||
node --test src/**/*.test.ts
|
||||
├── No external dependency
|
||||
├── Good coverage reporting
|
||||
└── Watch mode available
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Anti-Patterns to Avoid
|
||||
|
||||
### ❌ DON'T:
|
||||
- Use Express for new edge projects (use Hono)
|
||||
- Use sync methods in production code
|
||||
- Put business logic in controllers
|
||||
- Skip input validation
|
||||
- Hardcode secrets
|
||||
- Trust external data without validation
|
||||
- Block event loop with CPU work
|
||||
|
||||
### ✅ DO:
|
||||
- Choose framework based on context
|
||||
- Ask user for preferences when unclear
|
||||
- Use layered architecture for growing projects
|
||||
- Validate all inputs
|
||||
- Use environment variables for secrets
|
||||
- Profile before optimizing
|
||||
|
||||
---
|
||||
|
||||
## 11. Decision Checklist
|
||||
|
||||
Before implementing:
|
||||
|
||||
- [ ] **Asked user about stack preference?**
|
||||
- [ ] **Chosen framework for THIS context?** (not just default)
|
||||
- [ ] **Considered deployment target?**
|
||||
- [ ] **Planned error handling strategy?**
|
||||
- [ ] **Identified validation points?**
|
||||
- [ ] **Considered security requirements?**
|
||||
|
||||
---
|
||||
|
||||
> **Remember**: Node.js best practices are about decision-making, not memorizing patterns. Every project deserves fresh consideration based on its requirements.
|
||||
175
skills/parallel-agents/SKILL.md
Normal file
175
skills/parallel-agents/SKILL.md
Normal file
@@ -0,0 +1,175 @@
|
||||
---
|
||||
name: parallel-agents
|
||||
description: Multi-agent orchestration patterns. Use when multiple independent tasks can run with different domain expertise or when comprehensive analysis requires multiple perspectives.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Native Parallel Agents
|
||||
|
||||
> Orchestration through Claude Code's built-in Agent Tool
|
||||
|
||||
## Overview
|
||||
|
||||
This skill enables coordinating multiple specialized agents through Claude Code's native agent system. Unlike external scripts, this approach keeps all orchestration within Claude's control.
|
||||
|
||||
## When to Use Orchestration
|
||||
|
||||
✅ **Good for:**
|
||||
- Complex tasks requiring multiple expertise domains
|
||||
- Code analysis from security, performance, and quality perspectives
|
||||
- Comprehensive reviews (architecture + security + testing)
|
||||
- Feature implementation needing backend + frontend + database work
|
||||
|
||||
❌ **Not for:**
|
||||
- Simple, single-domain tasks
|
||||
- Quick fixes or small changes
|
||||
- Tasks where one agent suffices
|
||||
|
||||
---
|
||||
|
||||
## Native Agent Invocation
|
||||
|
||||
### Single Agent
|
||||
```
|
||||
Use the security-auditor agent to review authentication
|
||||
```
|
||||
|
||||
### Sequential Chain
|
||||
```
|
||||
First, use the explorer-agent to discover project structure.
|
||||
Then, use the backend-specialist to review API endpoints.
|
||||
Finally, use the test-engineer to identify test gaps.
|
||||
```
|
||||
|
||||
### With Context Passing
|
||||
```
|
||||
Use the frontend-specialist to analyze React components.
|
||||
Based on those findings, have the test-engineer generate component tests.
|
||||
```
|
||||
|
||||
### Resume Previous Work
|
||||
```
|
||||
Resume agent [agentId] and continue with additional requirements.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Orchestration Patterns
|
||||
|
||||
### Pattern 1: Comprehensive Analysis
|
||||
```
|
||||
Agents: explorer-agent → [domain-agents] → synthesis
|
||||
|
||||
1. explorer-agent: Map codebase structure
|
||||
2. security-auditor: Security posture
|
||||
3. backend-specialist: API quality
|
||||
4. frontend-specialist: UI/UX patterns
|
||||
5. test-engineer: Test coverage
|
||||
6. Synthesize all findings
|
||||
```
|
||||
|
||||
### Pattern 2: Feature Review
|
||||
```
|
||||
Agents: affected-domain-agents → test-engineer
|
||||
|
||||
1. Identify affected domains (backend? frontend? both?)
|
||||
2. Invoke relevant domain agents
|
||||
3. test-engineer verifies changes
|
||||
4. Synthesize recommendations
|
||||
```
|
||||
|
||||
### Pattern 3: Security Audit
|
||||
```
|
||||
Agents: security-auditor → penetration-tester → synthesis
|
||||
|
||||
1. security-auditor: Configuration and code review
|
||||
2. penetration-tester: Active vulnerability testing
|
||||
3. Synthesize with prioritized remediation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Available Agents
|
||||
|
||||
| Agent | Expertise | Trigger Phrases |
|
||||
|-------|-----------|-----------------|
|
||||
| `orchestrator` | Coordination | "comprehensive", "multi-perspective" |
|
||||
| `security-auditor` | Security | "security", "auth", "vulnerabilities" |
|
||||
| `penetration-tester` | Security Testing | "pentest", "red team", "exploit" |
|
||||
| `backend-specialist` | Backend | "API", "server", "Node.js", "Express" |
|
||||
| `frontend-specialist` | Frontend | "React", "UI", "components", "Next.js" |
|
||||
| `test-engineer` | Testing | "tests", "coverage", "TDD" |
|
||||
| `devops-engineer` | DevOps | "deploy", "CI/CD", "infrastructure" |
|
||||
| `database-architect` | Database | "schema", "Prisma", "migrations" |
|
||||
| `mobile-developer` | Mobile | "React Native", "Flutter", "mobile" |
|
||||
| `api-designer` | API Design | "REST", "GraphQL", "OpenAPI" |
|
||||
| `debugger` | Debugging | "bug", "error", "not working" |
|
||||
| `explorer-agent` | Discovery | "explore", "map", "structure" |
|
||||
| `documentation-writer` | Documentation | "write docs", "create README", "generate API docs" |
|
||||
| `performance-optimizer` | Performance | "slow", "optimize", "profiling" |
|
||||
| `project-planner` | Planning | "plan", "roadmap", "milestones" |
|
||||
| `seo-specialist` | SEO | "SEO", "meta tags", "search ranking" |
|
||||
| `game-developer` | Game Development | "game", "Unity", "Godot", "Phaser" |
|
||||
|
||||
---
|
||||
|
||||
## Claude Code Built-in Agents
|
||||
|
||||
These work alongside custom agents:
|
||||
|
||||
| Agent | Model | Purpose |
|
||||
|-------|-------|---------|
|
||||
| **Explore** | Haiku | Fast read-only codebase search |
|
||||
| **Plan** | Sonnet | Research during plan mode |
|
||||
| **General-purpose** | Sonnet | Complex multi-step modifications |
|
||||
|
||||
Use **Explore** for quick searches, **custom agents** for domain expertise.
|
||||
|
||||
---
|
||||
|
||||
## Synthesis Protocol
|
||||
|
||||
After all agents complete, synthesize:
|
||||
|
||||
```markdown
|
||||
## Orchestration Synthesis
|
||||
|
||||
### Task Summary
|
||||
[What was accomplished]
|
||||
|
||||
### Agent Contributions
|
||||
| Agent | Finding |
|
||||
|-------|---------|
|
||||
| security-auditor | Found X |
|
||||
| backend-specialist | Identified Y |
|
||||
|
||||
### Consolidated Recommendations
|
||||
1. **Critical**: [Issue from Agent A]
|
||||
2. **Important**: [Issue from Agent B]
|
||||
3. **Nice-to-have**: [Enhancement from Agent C]
|
||||
|
||||
### Action Items
|
||||
- [ ] Fix critical security issue
|
||||
- [ ] Refactor API endpoint
|
||||
- [ ] Add missing tests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Available agents** - 17 specialized agents can be orchestrated
|
||||
2. **Logical order** - Discovery → Analysis → Implementation → Testing
|
||||
3. **Share context** - Pass relevant findings to subsequent agents
|
||||
4. **Single synthesis** - One unified report, not separate outputs
|
||||
5. **Verify changes** - Always include test-engineer for code modifications
|
||||
|
||||
---
|
||||
|
||||
## Key Benefits
|
||||
|
||||
- ✅ **Single session** - All agents share context
|
||||
- ✅ **AI-controlled** - Claude orchestrates autonomously
|
||||
- ✅ **Native integration** - Works with built-in Explore, Plan agents
|
||||
- ✅ **Resume support** - Can continue previous agent work
|
||||
- ✅ **Context passing** - Findings flow between agents
|
||||
143
skills/performance-profiling/SKILL.md
Normal file
143
skills/performance-profiling/SKILL.md
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
name: performance-profiling
|
||||
description: Performance profiling principles. Measurement, analysis, and optimization techniques.
|
||||
allowed-tools: Read, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# Performance Profiling
|
||||
|
||||
> Measure, analyze, optimize - in that order.
|
||||
|
||||
## 🔧 Runtime Scripts
|
||||
|
||||
**Execute these for automated profiling:**
|
||||
|
||||
| Script | Purpose | Usage |
|
||||
|--------|---------|-------|
|
||||
| `scripts/lighthouse_audit.py` | Lighthouse performance audit | `python scripts/lighthouse_audit.py https://example.com` |
|
||||
|
||||
---
|
||||
|
||||
## 1. Core Web Vitals
|
||||
|
||||
### Targets
|
||||
|
||||
| Metric | Good | Poor | Measures |
|
||||
|--------|------|------|----------|
|
||||
| **LCP** | < 2.5s | > 4.0s | Loading |
|
||||
| **INP** | < 200ms | > 500ms | Interactivity |
|
||||
| **CLS** | < 0.1 | > 0.25 | Stability |
|
||||
|
||||
### When to Measure
|
||||
|
||||
| Stage | Tool |
|
||||
|-------|------|
|
||||
| Development | Local Lighthouse |
|
||||
| CI/CD | Lighthouse CI |
|
||||
| Production | RUM (Real User Monitoring) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Profiling Workflow
|
||||
|
||||
### The 4-Step Process
|
||||
|
||||
```
|
||||
1. BASELINE → Measure current state
|
||||
2. IDENTIFY → Find the bottleneck
|
||||
3. FIX → Make targeted change
|
||||
4. VALIDATE → Confirm improvement
|
||||
```
|
||||
|
||||
### Profiling Tool Selection
|
||||
|
||||
| Problem | Tool |
|
||||
|---------|------|
|
||||
| Page load | Lighthouse |
|
||||
| Bundle size | Bundle analyzer |
|
||||
| Runtime | DevTools Performance |
|
||||
| Memory | DevTools Memory |
|
||||
| Network | DevTools Network |
|
||||
|
||||
---
|
||||
|
||||
## 3. Bundle Analysis
|
||||
|
||||
### What to Look For
|
||||
|
||||
| Issue | Indicator |
|
||||
|-------|-----------|
|
||||
| Large dependencies | Top of bundle |
|
||||
| Duplicate code | Multiple chunks |
|
||||
| Unused code | Low coverage |
|
||||
| Missing splits | Single large chunk |
|
||||
|
||||
### Optimization Actions
|
||||
|
||||
| Finding | Action |
|
||||
|---------|--------|
|
||||
| Big library | Import specific modules |
|
||||
| Duplicate deps | Dedupe, update versions |
|
||||
| Route in main | Code split |
|
||||
| Unused exports | Tree shake |
|
||||
|
||||
---
|
||||
|
||||
## 4. Runtime Profiling
|
||||
|
||||
### Performance Tab Analysis
|
||||
|
||||
| Pattern | Meaning |
|
||||
|---------|---------|
|
||||
| Long tasks (>50ms) | UI blocking |
|
||||
| Many small tasks | Possible batching opportunity |
|
||||
| Layout/paint | Rendering bottleneck |
|
||||
| Script | JavaScript execution |
|
||||
|
||||
### Memory Tab Analysis
|
||||
|
||||
| Pattern | Meaning |
|
||||
|---------|---------|
|
||||
| Growing heap | Possible leak |
|
||||
| Large retained | Check references |
|
||||
| Detached DOM | Not cleaned up |
|
||||
|
||||
---
|
||||
|
||||
## 5. Common Bottlenecks
|
||||
|
||||
### By Symptom
|
||||
|
||||
| Symptom | Likely Cause |
|
||||
|---------|--------------|
|
||||
| Slow initial load | Large JS, render blocking |
|
||||
| Slow interactions | Heavy event handlers |
|
||||
| Jank during scroll | Layout thrashing |
|
||||
| Growing memory | Leaks, retained refs |
|
||||
|
||||
---
|
||||
|
||||
## 6. Quick Win Priorities
|
||||
|
||||
| Priority | Action | Impact |
|
||||
|----------|--------|--------|
|
||||
| 1 | Enable compression | High |
|
||||
| 2 | Lazy load images | High |
|
||||
| 3 | Code split routes | High |
|
||||
| 4 | Cache static assets | Medium |
|
||||
| 5 | Optimize images | Medium |
|
||||
|
||||
---
|
||||
|
||||
## 7. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Guess at problems | Profile first |
|
||||
| Micro-optimize | Fix biggest issue |
|
||||
| Optimize early | Optimize when needed |
|
||||
| Ignore real users | Use RUM data |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** The fastest code is code that doesn't run. Remove before optimizing.
|
||||
76
skills/performance-profiling/scripts/lighthouse_audit.py
Normal file
76
skills/performance-profiling/scripts/lighthouse_audit.py
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Skill: performance-profiling
|
||||
Script: lighthouse_audit.py
|
||||
Purpose: Run Lighthouse performance audit on a URL
|
||||
Usage: python lighthouse_audit.py https://example.com
|
||||
Output: JSON with performance scores
|
||||
Note: Requires lighthouse CLI (npm install -g lighthouse)
|
||||
"""
|
||||
import subprocess
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
def run_lighthouse(url: str) -> dict:
|
||||
"""Run Lighthouse audit on URL."""
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile(suffix='.json', delete=False) as f:
|
||||
output_path = f.name
|
||||
|
||||
result = subprocess.run(
|
||||
[
|
||||
"lighthouse",
|
||||
url,
|
||||
"--output=json",
|
||||
f"--output-path={output_path}",
|
||||
"--chrome-flags=--headless",
|
||||
"--only-categories=performance,accessibility,best-practices,seo"
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=120
|
||||
)
|
||||
|
||||
if os.path.exists(output_path):
|
||||
with open(output_path, 'r') as f:
|
||||
report = json.load(f)
|
||||
os.unlink(output_path)
|
||||
|
||||
categories = report.get("categories", {})
|
||||
return {
|
||||
"url": url,
|
||||
"scores": {
|
||||
"performance": int(categories.get("performance", {}).get("score", 0) * 100),
|
||||
"accessibility": int(categories.get("accessibility", {}).get("score", 0) * 100),
|
||||
"best_practices": int(categories.get("best-practices", {}).get("score", 0) * 100),
|
||||
"seo": int(categories.get("seo", {}).get("score", 0) * 100)
|
||||
},
|
||||
"summary": get_summary(categories)
|
||||
}
|
||||
else:
|
||||
return {"error": "Lighthouse failed to generate report", "stderr": result.stderr[:500]}
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
return {"error": "Lighthouse audit timed out"}
|
||||
except FileNotFoundError:
|
||||
return {"error": "Lighthouse CLI not found. Install with: npm install -g lighthouse"}
|
||||
|
||||
def get_summary(categories: dict) -> str:
|
||||
"""Generate summary based on scores."""
|
||||
perf = categories.get("performance", {}).get("score", 0) * 100
|
||||
if perf >= 90:
|
||||
return "[OK] Excellent performance"
|
||||
elif perf >= 50:
|
||||
return "[!] Needs improvement"
|
||||
else:
|
||||
return "[X] Poor performance"
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print(json.dumps({"error": "Usage: python lighthouse_audit.py <url>"}))
|
||||
sys.exit(1)
|
||||
|
||||
result = run_lighthouse(sys.argv[1])
|
||||
print(json.dumps(result, indent=2))
|
||||
152
skills/plan-writing/SKILL.md
Normal file
152
skills/plan-writing/SKILL.md
Normal file
@@ -0,0 +1,152 @@
|
||||
---
|
||||
name: plan-writing
|
||||
description: Structured task planning with clear breakdowns, dependencies, and verification criteria. Use when implementing features, refactoring, or any multi-step work.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Plan Writing
|
||||
|
||||
> Source: obra/superpowers
|
||||
|
||||
## Overview
|
||||
This skill provides a framework for breaking down work into clear, actionable tasks with verification criteria.
|
||||
|
||||
## Task Breakdown Principles
|
||||
|
||||
### 1. Small, Focused Tasks
|
||||
- Each task should take 2-5 minutes
|
||||
- One clear outcome per task
|
||||
- Independently verifiable
|
||||
|
||||
### 2. Clear Verification
|
||||
- How do you know it's done?
|
||||
- What can you check/test?
|
||||
- What's the expected output?
|
||||
|
||||
### 3. Logical Ordering
|
||||
- Dependencies identified
|
||||
- Parallel work where possible
|
||||
- Critical path highlighted
|
||||
- **Phase X: Verification is always LAST**
|
||||
|
||||
### 4. Dynamic Naming in Project Root
|
||||
- Plan files are saved as `{task-slug}.md` in the PROJECT ROOT
|
||||
- Name derived from task (e.g., "add auth" → `auth-feature.md`)
|
||||
- **NEVER** inside `.claude/`, `docs/`, or temp folders
|
||||
|
||||
## Planning Principles (NOT Templates!)
|
||||
|
||||
> 🔴 **NO fixed templates. Each plan is UNIQUE to the task.**
|
||||
|
||||
### Principle 1: Keep It SHORT
|
||||
|
||||
| ❌ Wrong | ✅ Right |
|
||||
|----------|----------|
|
||||
| 50 tasks with sub-sub-tasks | 5-10 clear tasks max |
|
||||
| Every micro-step listed | Only actionable items |
|
||||
| Verbose descriptions | One-line per task |
|
||||
|
||||
> **Rule:** If plan is longer than 1 page, it's too long. Simplify.
|
||||
|
||||
---
|
||||
|
||||
### Principle 2: Be SPECIFIC, Not Generic
|
||||
|
||||
| ❌ Wrong | ✅ Right |
|
||||
|----------|----------|
|
||||
| "Set up project" | "Run `npx create-next-app`" |
|
||||
| "Add authentication" | "Install next-auth, create `/api/auth/[...nextauth].ts`" |
|
||||
| "Style the UI" | "Add Tailwind classes to `Header.tsx`" |
|
||||
|
||||
> **Rule:** Each task should have a clear, verifiable outcome.
|
||||
|
||||
---
|
||||
|
||||
### Principle 3: Dynamic Content Based on Project Type
|
||||
|
||||
**For NEW PROJECT:**
|
||||
- What tech stack? (decide first)
|
||||
- What's the MVP? (minimal features)
|
||||
- What's the file structure?
|
||||
|
||||
**For FEATURE ADDITION:**
|
||||
- Which files are affected?
|
||||
- What dependencies needed?
|
||||
- How to verify it works?
|
||||
|
||||
**For BUG FIX:**
|
||||
- What's the root cause?
|
||||
- What file/line to change?
|
||||
- How to test the fix?
|
||||
|
||||
---
|
||||
|
||||
### Principle 4: Scripts Are Project-Specific
|
||||
|
||||
> 🔴 **DO NOT copy-paste script commands. Choose based on project type.**
|
||||
|
||||
| Project Type | Relevant Scripts |
|
||||
|--------------|------------------|
|
||||
| Frontend/React | `ux_audit.py`, `accessibility_checker.py` |
|
||||
| Backend/API | `api_validator.py`, `security_scan.py` |
|
||||
| Mobile | `mobile_audit.py` |
|
||||
| Database | `schema_validator.py` |
|
||||
| Full-stack | Mix of above based on what you touched |
|
||||
|
||||
**Wrong:** Adding all scripts to every plan
|
||||
**Right:** Only scripts relevant to THIS task
|
||||
|
||||
---
|
||||
|
||||
### Principle 5: Verification is Simple
|
||||
|
||||
| ❌ Wrong | ✅ Right |
|
||||
|----------|----------|
|
||||
| "Verify the component works correctly" | "Run `npm run dev`, click button, see toast" |
|
||||
| "Test the API" | "curl localhost:3000/api/users returns 200" |
|
||||
| "Check styles" | "Open browser, verify dark mode toggle works" |
|
||||
|
||||
---
|
||||
|
||||
## Plan Structure (Flexible, Not Fixed!)
|
||||
|
||||
```
|
||||
# [Task Name]
|
||||
|
||||
## Goal
|
||||
One sentence: What are we building/fixing?
|
||||
|
||||
## Tasks
|
||||
- [ ] Task 1: [Specific action] → Verify: [How to check]
|
||||
- [ ] Task 2: [Specific action] → Verify: [How to check]
|
||||
- [ ] Task 3: [Specific action] → Verify: [How to check]
|
||||
|
||||
## Done When
|
||||
- [ ] [Main success criteria]
|
||||
```
|
||||
|
||||
> **That's it.** No phases, no sub-sections unless truly needed.
|
||||
> Keep it minimal. Add complexity only when required.
|
||||
|
||||
## Notes
|
||||
[Any important considerations]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices (Quick Reference)
|
||||
|
||||
1. **Start with goal** - What are we building/fixing?
|
||||
2. **Max 10 tasks** - If more, break into multiple plans
|
||||
3. **Each task verifiable** - Clear "done" criteria
|
||||
4. **Project-specific** - No copy-paste templates
|
||||
5. **Update as you go** - Mark `[x]` when complete
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
- New project from scratch
|
||||
- Adding a feature
|
||||
- Fixing a bug (if complex)
|
||||
- Refactoring multiple files
|
||||
167
skills/powershell-windows/SKILL.md
Normal file
167
skills/powershell-windows/SKILL.md
Normal file
@@ -0,0 +1,167 @@
|
||||
---
|
||||
name: powershell-windows
|
||||
description: PowerShell Windows patterns. Critical pitfalls, operator syntax, error handling.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# PowerShell Windows Patterns
|
||||
|
||||
> Critical patterns and pitfalls for Windows PowerShell.
|
||||
|
||||
---
|
||||
|
||||
## 1. Operator Syntax Rules
|
||||
|
||||
### CRITICAL: Parentheses Required
|
||||
|
||||
| ❌ Wrong | ✅ Correct |
|
||||
|----------|-----------|
|
||||
| `if (Test-Path "a" -or Test-Path "b")` | `if ((Test-Path "a") -or (Test-Path "b"))` |
|
||||
| `if (Get-Item $x -and $y -eq 5)` | `if ((Get-Item $x) -and ($y -eq 5))` |
|
||||
|
||||
**Rule:** Each cmdlet call MUST be in parentheses when using logical operators.
|
||||
|
||||
---
|
||||
|
||||
## 2. Unicode/Emoji Restriction
|
||||
|
||||
### CRITICAL: No Unicode in Scripts
|
||||
|
||||
| Purpose | ❌ Don't Use | ✅ Use |
|
||||
|---------|-------------|--------|
|
||||
| Success | ✅ ✓ | [OK] [+] |
|
||||
| Error | ❌ ✗ 🔴 | [!] [X] |
|
||||
| Warning | ⚠️ 🟡 | [*] [WARN] |
|
||||
| Info | ℹ️ 🔵 | [i] [INFO] |
|
||||
| Progress | ⏳ | [...] |
|
||||
|
||||
**Rule:** Use ASCII characters only in PowerShell scripts.
|
||||
|
||||
---
|
||||
|
||||
## 3. Null Check Patterns
|
||||
|
||||
### Always Check Before Access
|
||||
|
||||
| ❌ Wrong | ✅ Correct |
|
||||
|----------|-----------|
|
||||
| `$array.Count -gt 0` | `$array -and $array.Count -gt 0` |
|
||||
| `$text.Length` | `if ($text) { $text.Length }` |
|
||||
|
||||
---
|
||||
|
||||
## 4. String Interpolation
|
||||
|
||||
### Complex Expressions
|
||||
|
||||
| ❌ Wrong | ✅ Correct |
|
||||
|----------|-----------|
|
||||
| `"Value: $($obj.prop.sub)"` | Store in variable first |
|
||||
|
||||
**Pattern:**
|
||||
```
|
||||
$value = $obj.prop.sub
|
||||
Write-Output "Value: $value"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Error Handling
|
||||
|
||||
### ErrorActionPreference
|
||||
|
||||
| Value | Use |
|
||||
|-------|-----|
|
||||
| Stop | Development (fail fast) |
|
||||
| Continue | Production scripts |
|
||||
| SilentlyContinue | When errors expected |
|
||||
|
||||
### Try/Catch Pattern
|
||||
|
||||
- Don't return inside try block
|
||||
- Use finally for cleanup
|
||||
- Return after try/catch
|
||||
|
||||
---
|
||||
|
||||
## 6. File Paths
|
||||
|
||||
### Windows Path Rules
|
||||
|
||||
| Pattern | Use |
|
||||
|---------|-----|
|
||||
| Literal path | `C:\Users\User\file.txt` |
|
||||
| Variable path | `Join-Path $env:USERPROFILE "file.txt"` |
|
||||
| Relative | `Join-Path $ScriptDir "data"` |
|
||||
|
||||
**Rule:** Use Join-Path for cross-platform safety.
|
||||
|
||||
---
|
||||
|
||||
## 7. Array Operations
|
||||
|
||||
### Correct Patterns
|
||||
|
||||
| Operation | Syntax |
|
||||
|-----------|--------|
|
||||
| Empty array | `$array = @()` |
|
||||
| Add item | `$array += $item` |
|
||||
| ArrayList add | `$list.Add($item) | Out-Null` |
|
||||
|
||||
---
|
||||
|
||||
## 8. JSON Operations
|
||||
|
||||
### CRITICAL: Depth Parameter
|
||||
|
||||
| ❌ Wrong | ✅ Correct |
|
||||
|----------|-----------|
|
||||
| `ConvertTo-Json` | `ConvertTo-Json -Depth 10` |
|
||||
|
||||
**Rule:** Always specify `-Depth` for nested objects.
|
||||
|
||||
### File Operations
|
||||
|
||||
| Operation | Pattern |
|
||||
|-----------|---------|
|
||||
| Read | `Get-Content "file.json" -Raw | ConvertFrom-Json` |
|
||||
| Write | `$data | ConvertTo-Json -Depth 10 | Out-File "file.json" -Encoding UTF8` |
|
||||
|
||||
---
|
||||
|
||||
## 9. Common Errors
|
||||
|
||||
| Error Message | Cause | Fix |
|
||||
|---------------|-------|-----|
|
||||
| "parameter 'or'" | Missing parentheses | Wrap cmdlets in () |
|
||||
| "Unexpected token" | Unicode character | Use ASCII only |
|
||||
| "Cannot find property" | Null object | Check null first |
|
||||
| "Cannot convert" | Type mismatch | Use .ToString() |
|
||||
|
||||
---
|
||||
|
||||
## 10. Script Template
|
||||
|
||||
```powershell
|
||||
# Strict mode
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
# Paths
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
|
||||
# Main
|
||||
try {
|
||||
# Logic here
|
||||
Write-Output "[OK] Done"
|
||||
exit 0
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Error: $_"
|
||||
exit 1
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** PowerShell has unique syntax rules. Parentheses, ASCII-only, and null checks are non-negotiable.
|
||||
355
skills/prisma-expert/SKILL.md
Normal file
355
skills/prisma-expert/SKILL.md
Normal file
@@ -0,0 +1,355 @@
|
||||
---
|
||||
name: prisma-expert
|
||||
description: 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.
|
||||
---
|
||||
|
||||
# Prisma Expert
|
||||
|
||||
You are an expert in Prisma ORM with deep knowledge of schema design, migrations, query optimization, relations modeling, and database operations across PostgreSQL, MySQL, and SQLite.
|
||||
|
||||
## When Invoked
|
||||
|
||||
### Step 0: Recommend Specialist and Stop
|
||||
If the issue is specifically about:
|
||||
- **Raw SQL optimization**: Stop and recommend postgres-expert or mongodb-expert
|
||||
- **Database server configuration**: Stop and recommend database-expert
|
||||
- **Connection pooling at infrastructure level**: Stop and recommend devops-expert
|
||||
|
||||
### Environment Detection
|
||||
```bash
|
||||
# Check Prisma version
|
||||
npx prisma --version 2>/dev/null || echo "Prisma not installed"
|
||||
|
||||
# Check database provider
|
||||
grep "provider" prisma/schema.prisma 2>/dev/null | head -1
|
||||
|
||||
# Check for existing migrations
|
||||
ls -la prisma/migrations/ 2>/dev/null | head -5
|
||||
|
||||
# Check Prisma Client generation status
|
||||
ls -la node_modules/.prisma/client/ 2>/dev/null | head -3
|
||||
```
|
||||
|
||||
### Apply Strategy
|
||||
1. Identify the Prisma-specific issue category
|
||||
2. Check for common anti-patterns in schema or queries
|
||||
3. Apply progressive fixes (minimal → better → complete)
|
||||
4. Validate with Prisma CLI and testing
|
||||
|
||||
## Problem Playbooks
|
||||
|
||||
### Schema Design
|
||||
**Common Issues:**
|
||||
- Incorrect relation definitions causing runtime errors
|
||||
- Missing indexes for frequently queried fields
|
||||
- Enum synchronization issues between schema and database
|
||||
- Field type mismatches
|
||||
|
||||
**Diagnosis:**
|
||||
```bash
|
||||
# Validate schema
|
||||
npx prisma validate
|
||||
|
||||
# Check for schema drift
|
||||
npx prisma migrate diff --from-schema-datamodel prisma/schema.prisma --to-schema-datasource prisma/schema.prisma
|
||||
|
||||
# Format schema
|
||||
npx prisma format
|
||||
```
|
||||
|
||||
**Prioritized Fixes:**
|
||||
1. **Minimal**: Fix relation annotations, add missing `@relation` directives
|
||||
2. **Better**: Add proper indexes with `@@index`, optimize field types
|
||||
3. **Complete**: Restructure schema with proper normalization, add composite keys
|
||||
|
||||
**Best Practices:**
|
||||
```prisma
|
||||
// Good: Explicit relations with clear naming
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
posts Post[] @relation("UserPosts")
|
||||
profile Profile? @relation("UserProfile")
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([email])
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model Post {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
author User @relation("UserPosts", fields: [authorId], references: [id], onDelete: Cascade)
|
||||
authorId String
|
||||
|
||||
@@index([authorId])
|
||||
@@map("posts")
|
||||
}
|
||||
```
|
||||
|
||||
**Resources:**
|
||||
- https://www.prisma.io/docs/concepts/components/prisma-schema
|
||||
- https://www.prisma.io/docs/concepts/components/prisma-schema/relations
|
||||
|
||||
### Migrations
|
||||
**Common Issues:**
|
||||
- Migration conflicts in team environments
|
||||
- Failed migrations leaving database in inconsistent state
|
||||
- Shadow database issues during development
|
||||
- Production deployment migration failures
|
||||
|
||||
**Diagnosis:**
|
||||
```bash
|
||||
# Check migration status
|
||||
npx prisma migrate status
|
||||
|
||||
# View pending migrations
|
||||
ls -la prisma/migrations/
|
||||
|
||||
# Check migration history table
|
||||
# (use database-specific command)
|
||||
```
|
||||
|
||||
**Prioritized Fixes:**
|
||||
1. **Minimal**: Reset development database with `prisma migrate reset`
|
||||
2. **Better**: Manually fix migration SQL, use `prisma migrate resolve`
|
||||
3. **Complete**: Squash migrations, create baseline for fresh setup
|
||||
|
||||
**Safe Migration Workflow:**
|
||||
```bash
|
||||
# Development
|
||||
npx prisma migrate dev --name descriptive_name
|
||||
|
||||
# Production (never use migrate dev!)
|
||||
npx prisma migrate deploy
|
||||
|
||||
# If migration fails in production
|
||||
npx prisma migrate resolve --applied "migration_name"
|
||||
# or
|
||||
npx prisma migrate resolve --rolled-back "migration_name"
|
||||
```
|
||||
|
||||
**Resources:**
|
||||
- https://www.prisma.io/docs/concepts/components/prisma-migrate
|
||||
- https://www.prisma.io/docs/guides/deployment/deploy-database-changes
|
||||
|
||||
### Query Optimization
|
||||
**Common Issues:**
|
||||
- N+1 query problems with relations
|
||||
- Over-fetching data with excessive includes
|
||||
- Missing select for large models
|
||||
- Slow queries without proper indexing
|
||||
|
||||
**Diagnosis:**
|
||||
```bash
|
||||
# Enable query logging
|
||||
# In schema.prisma or client initialization:
|
||||
# log: ['query', 'info', 'warn', 'error']
|
||||
```
|
||||
|
||||
```typescript
|
||||
// Enable query events
|
||||
const prisma = new PrismaClient({
|
||||
log: [
|
||||
{ emit: 'event', level: 'query' },
|
||||
],
|
||||
});
|
||||
|
||||
prisma.$on('query', (e) => {
|
||||
console.log('Query: ' + e.query);
|
||||
console.log('Duration: ' + e.duration + 'ms');
|
||||
});
|
||||
```
|
||||
|
||||
**Prioritized Fixes:**
|
||||
1. **Minimal**: Add includes for related data to avoid N+1
|
||||
2. **Better**: Use select to fetch only needed fields
|
||||
3. **Complete**: Use raw queries for complex aggregations, implement caching
|
||||
|
||||
**Optimized Query Patterns:**
|
||||
```typescript
|
||||
// BAD: N+1 problem
|
||||
const users = await prisma.user.findMany();
|
||||
for (const user of users) {
|
||||
const posts = await prisma.post.findMany({ where: { authorId: user.id } });
|
||||
}
|
||||
|
||||
// GOOD: Include relations
|
||||
const users = await prisma.user.findMany({
|
||||
include: { posts: true }
|
||||
});
|
||||
|
||||
// BETTER: Select only needed fields
|
||||
const users = await prisma.user.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
posts: {
|
||||
select: { id: true, title: true }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// BEST for complex queries: Use $queryRaw
|
||||
const result = await prisma.$queryRaw`
|
||||
SELECT u.id, u.email, COUNT(p.id) as post_count
|
||||
FROM users u
|
||||
LEFT JOIN posts p ON p.author_id = u.id
|
||||
GROUP BY u.id
|
||||
`;
|
||||
```
|
||||
|
||||
**Resources:**
|
||||
- https://www.prisma.io/docs/guides/performance-and-optimization
|
||||
- https://www.prisma.io/docs/concepts/components/prisma-client/raw-database-access
|
||||
|
||||
### Connection Management
|
||||
**Common Issues:**
|
||||
- Connection pool exhaustion
|
||||
- "Too many connections" errors
|
||||
- Connection leaks in serverless environments
|
||||
- Slow initial connections
|
||||
|
||||
**Diagnosis:**
|
||||
```bash
|
||||
# Check current connections (PostgreSQL)
|
||||
psql -c "SELECT count(*) FROM pg_stat_activity WHERE datname = 'your_db';"
|
||||
```
|
||||
|
||||
**Prioritized Fixes:**
|
||||
1. **Minimal**: Configure connection limit in DATABASE_URL
|
||||
2. **Better**: Implement proper connection lifecycle management
|
||||
3. **Complete**: Use connection pooler (PgBouncer) for high-traffic apps
|
||||
|
||||
**Connection Configuration:**
|
||||
```typescript
|
||||
// For serverless (Vercel, AWS Lambda)
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const globalForPrisma = global as unknown as { prisma: PrismaClient };
|
||||
|
||||
export const prisma =
|
||||
globalForPrisma.prisma ||
|
||||
new PrismaClient({
|
||||
log: process.env.NODE_ENV === 'development' ? ['query'] : [],
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
|
||||
|
||||
// Graceful shutdown
|
||||
process.on('beforeExit', async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
```
|
||||
|
||||
```env
|
||||
# Connection URL with pool settings
|
||||
DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=5&pool_timeout=10"
|
||||
```
|
||||
|
||||
**Resources:**
|
||||
- https://www.prisma.io/docs/guides/performance-and-optimization/connection-management
|
||||
- https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-vercel
|
||||
|
||||
### Transaction Patterns
|
||||
**Common Issues:**
|
||||
- Inconsistent data from non-atomic operations
|
||||
- Deadlocks in concurrent transactions
|
||||
- Long-running transactions blocking reads
|
||||
- Nested transaction confusion
|
||||
|
||||
**Diagnosis:**
|
||||
```typescript
|
||||
// Check for transaction issues
|
||||
try {
|
||||
const result = await prisma.$transaction([...]);
|
||||
} catch (e) {
|
||||
if (e.code === 'P2034') {
|
||||
console.log('Transaction conflict detected');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Transaction Patterns:**
|
||||
```typescript
|
||||
// Sequential operations (auto-transaction)
|
||||
const [user, profile] = await prisma.$transaction([
|
||||
prisma.user.create({ data: userData }),
|
||||
prisma.profile.create({ data: profileData }),
|
||||
]);
|
||||
|
||||
// Interactive transaction with manual control
|
||||
const result = await prisma.$transaction(async (tx) => {
|
||||
const user = await tx.user.create({ data: userData });
|
||||
|
||||
// Business logic validation
|
||||
if (user.email.endsWith('@blocked.com')) {
|
||||
throw new Error('Email domain blocked');
|
||||
}
|
||||
|
||||
const profile = await tx.profile.create({
|
||||
data: { ...profileData, userId: user.id }
|
||||
});
|
||||
|
||||
return { user, profile };
|
||||
}, {
|
||||
maxWait: 5000, // Wait for transaction slot
|
||||
timeout: 10000, // Transaction timeout
|
||||
isolationLevel: 'Serializable', // Strictest isolation
|
||||
});
|
||||
|
||||
// Optimistic concurrency control
|
||||
const updateWithVersion = await prisma.post.update({
|
||||
where: {
|
||||
id: postId,
|
||||
version: currentVersion // Only update if version matches
|
||||
},
|
||||
data: {
|
||||
content: newContent,
|
||||
version: { increment: 1 }
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**Resources:**
|
||||
- https://www.prisma.io/docs/concepts/components/prisma-client/transactions
|
||||
|
||||
## Code Review Checklist
|
||||
|
||||
### Schema Quality
|
||||
- [ ] All models have appropriate `@id` and primary keys
|
||||
- [ ] Relations use explicit `@relation` with `fields` and `references`
|
||||
- [ ] Cascade behaviors defined (`onDelete`, `onUpdate`)
|
||||
- [ ] Indexes added for frequently queried fields
|
||||
- [ ] Enums used for fixed value sets
|
||||
- [ ] `@@map` used for table naming conventions
|
||||
|
||||
### Query Patterns
|
||||
- [ ] No N+1 queries (relations included when needed)
|
||||
- [ ] `select` used to fetch only required fields
|
||||
- [ ] Pagination implemented for list queries
|
||||
- [ ] Raw queries used for complex aggregations
|
||||
- [ ] Proper error handling for database operations
|
||||
|
||||
### Performance
|
||||
- [ ] Connection pooling configured appropriately
|
||||
- [ ] Indexes exist for WHERE clause fields
|
||||
- [ ] Composite indexes for multi-column queries
|
||||
- [ ] Query logging enabled in development
|
||||
- [ ] Slow queries identified and optimized
|
||||
|
||||
### Migration Safety
|
||||
- [ ] Migrations tested before production deployment
|
||||
- [ ] Backward-compatible schema changes (no data loss)
|
||||
- [ ] Migration scripts reviewed for correctness
|
||||
- [ ] Rollback strategy documented
|
||||
|
||||
## Anti-Patterns to Avoid
|
||||
|
||||
1. **Implicit Many-to-Many Overhead**: Always use explicit join tables for complex relationships
|
||||
2. **Over-Including**: Don't include relations you don't need
|
||||
3. **Ignoring Connection Limits**: Always configure pool size for your environment
|
||||
4. **Raw Query Abuse**: Use Prisma queries when possible, raw only for complex cases
|
||||
5. **Migration in Production Dev Mode**: Never use `migrate dev` in production
|
||||
441
skills/python-patterns/SKILL.md
Normal file
441
skills/python-patterns/SKILL.md
Normal file
@@ -0,0 +1,441 @@
|
||||
---
|
||||
name: python-patterns
|
||||
description: Python development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# Python Patterns
|
||||
|
||||
> Python development principles and decision-making for 2025.
|
||||
> **Learn to THINK, not memorize patterns.**
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ How to Use This Skill
|
||||
|
||||
This skill teaches **decision-making principles**, not fixed code to copy.
|
||||
|
||||
- ASK user for framework preference when unclear
|
||||
- Choose async vs sync based on CONTEXT
|
||||
- Don't default to same framework every time
|
||||
|
||||
---
|
||||
|
||||
## 1. Framework Selection (2025)
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
What are you building?
|
||||
│
|
||||
├── API-first / Microservices
|
||||
│ └── FastAPI (async, modern, fast)
|
||||
│
|
||||
├── Full-stack web / CMS / Admin
|
||||
│ └── Django (batteries-included)
|
||||
│
|
||||
├── Simple / Script / Learning
|
||||
│ └── Flask (minimal, flexible)
|
||||
│
|
||||
├── AI/ML API serving
|
||||
│ └── FastAPI (Pydantic, async, uvicorn)
|
||||
│
|
||||
└── Background workers
|
||||
└── Celery + any framework
|
||||
```
|
||||
|
||||
### Comparison Principles
|
||||
|
||||
| Factor | FastAPI | Django | Flask |
|
||||
|--------|---------|--------|-------|
|
||||
| **Best for** | APIs, microservices | Full-stack, CMS | Simple, learning |
|
||||
| **Async** | Native | Django 5.0+ | Via extensions |
|
||||
| **Admin** | Manual | Built-in | Via extensions |
|
||||
| **ORM** | Choose your own | Django ORM | Choose your own |
|
||||
| **Learning curve** | Low | Medium | Low |
|
||||
|
||||
### Selection Questions to Ask:
|
||||
1. Is this API-only or full-stack?
|
||||
2. Need admin interface?
|
||||
3. Team familiar with async?
|
||||
4. Existing infrastructure?
|
||||
|
||||
---
|
||||
|
||||
## 2. Async vs Sync Decision
|
||||
|
||||
### When to Use Async
|
||||
|
||||
```
|
||||
async def is better when:
|
||||
├── I/O-bound operations (database, HTTP, file)
|
||||
├── Many concurrent connections
|
||||
├── Real-time features
|
||||
├── Microservices communication
|
||||
└── FastAPI/Starlette/Django ASGI
|
||||
|
||||
def (sync) is better when:
|
||||
├── CPU-bound operations
|
||||
├── Simple scripts
|
||||
├── Legacy codebase
|
||||
├── Team unfamiliar with async
|
||||
└── Blocking libraries (no async version)
|
||||
```
|
||||
|
||||
### The Golden Rule
|
||||
|
||||
```
|
||||
I/O-bound → async (waiting for external)
|
||||
CPU-bound → sync + multiprocessing (computing)
|
||||
|
||||
Don't:
|
||||
├── Mix sync and async carelessly
|
||||
├── Use sync libraries in async code
|
||||
└── Force async for CPU work
|
||||
```
|
||||
|
||||
### Async Library Selection
|
||||
|
||||
| Need | Async Library |
|
||||
|------|---------------|
|
||||
| HTTP client | httpx |
|
||||
| PostgreSQL | asyncpg |
|
||||
| Redis | aioredis / redis-py async |
|
||||
| File I/O | aiofiles |
|
||||
| Database ORM | SQLAlchemy 2.0 async, Tortoise |
|
||||
|
||||
---
|
||||
|
||||
## 3. Type Hints Strategy
|
||||
|
||||
### When to Type
|
||||
|
||||
```
|
||||
Always type:
|
||||
├── Function parameters
|
||||
├── Return types
|
||||
├── Class attributes
|
||||
├── Public APIs
|
||||
|
||||
Can skip:
|
||||
├── Local variables (let inference work)
|
||||
├── One-off scripts
|
||||
├── Tests (usually)
|
||||
```
|
||||
|
||||
### Common Type Patterns
|
||||
|
||||
```python
|
||||
# These are patterns, understand them:
|
||||
|
||||
# Optional → might be None
|
||||
from typing import Optional
|
||||
def find_user(id: int) -> Optional[User]: ...
|
||||
|
||||
# Union → one of multiple types
|
||||
def process(data: str | dict) -> None: ...
|
||||
|
||||
# Generic collections
|
||||
def get_items() -> list[Item]: ...
|
||||
def get_mapping() -> dict[str, int]: ...
|
||||
|
||||
# Callable
|
||||
from typing import Callable
|
||||
def apply(fn: Callable[[int], str]) -> str: ...
|
||||
```
|
||||
|
||||
### Pydantic for Validation
|
||||
|
||||
```
|
||||
When to use Pydantic:
|
||||
├── API request/response models
|
||||
├── Configuration/settings
|
||||
├── Data validation
|
||||
├── Serialization
|
||||
|
||||
Benefits:
|
||||
├── Runtime validation
|
||||
├── Auto-generated JSON schema
|
||||
├── Works with FastAPI natively
|
||||
└── Clear error messages
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Project Structure Principles
|
||||
|
||||
### Structure Selection
|
||||
|
||||
```
|
||||
Small project / Script:
|
||||
├── main.py
|
||||
├── utils.py
|
||||
└── requirements.txt
|
||||
|
||||
Medium API:
|
||||
├── app/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
│ ├── models/
|
||||
│ ├── routes/
|
||||
│ ├── services/
|
||||
│ └── schemas/
|
||||
├── tests/
|
||||
└── pyproject.toml
|
||||
|
||||
Large application:
|
||||
├── src/
|
||||
│ └── myapp/
|
||||
│ ├── core/
|
||||
│ ├── api/
|
||||
│ ├── services/
|
||||
│ ├── models/
|
||||
│ └── ...
|
||||
├── tests/
|
||||
└── pyproject.toml
|
||||
```
|
||||
|
||||
### FastAPI Structure Principles
|
||||
|
||||
```
|
||||
Organize by feature or layer:
|
||||
|
||||
By layer:
|
||||
├── routes/ (API endpoints)
|
||||
├── services/ (business logic)
|
||||
├── models/ (database models)
|
||||
├── schemas/ (Pydantic models)
|
||||
└── dependencies/ (shared deps)
|
||||
|
||||
By feature:
|
||||
├── users/
|
||||
│ ├── routes.py
|
||||
│ ├── service.py
|
||||
│ └── schemas.py
|
||||
└── products/
|
||||
└── ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Django Principles (2025)
|
||||
|
||||
### Django Async (Django 5.0+)
|
||||
|
||||
```
|
||||
Django supports async:
|
||||
├── Async views
|
||||
├── Async middleware
|
||||
├── Async ORM (limited)
|
||||
└── ASGI deployment
|
||||
|
||||
When to use async in Django:
|
||||
├── External API calls
|
||||
├── WebSocket (Channels)
|
||||
├── High-concurrency views
|
||||
└── Background task triggering
|
||||
```
|
||||
|
||||
### Django Best Practices
|
||||
|
||||
```
|
||||
Model design:
|
||||
├── Fat models, thin views
|
||||
├── Use managers for common queries
|
||||
├── Abstract base classes for shared fields
|
||||
|
||||
Views:
|
||||
├── Class-based for complex CRUD
|
||||
├── Function-based for simple endpoints
|
||||
├── Use viewsets with DRF
|
||||
|
||||
Queries:
|
||||
├── select_related() for FKs
|
||||
├── prefetch_related() for M2M
|
||||
├── Avoid N+1 queries
|
||||
└── Use .only() for specific fields
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. FastAPI Principles
|
||||
|
||||
### async def vs def in FastAPI
|
||||
|
||||
```
|
||||
Use async def when:
|
||||
├── Using async database drivers
|
||||
├── Making async HTTP calls
|
||||
├── I/O-bound operations
|
||||
└── Want to handle concurrency
|
||||
|
||||
Use def when:
|
||||
├── Blocking operations
|
||||
├── Sync database drivers
|
||||
├── CPU-bound work
|
||||
└── FastAPI runs in threadpool automatically
|
||||
```
|
||||
|
||||
### Dependency Injection
|
||||
|
||||
```
|
||||
Use dependencies for:
|
||||
├── Database sessions
|
||||
├── Current user / Auth
|
||||
├── Configuration
|
||||
├── Shared resources
|
||||
|
||||
Benefits:
|
||||
├── Testability (mock dependencies)
|
||||
├── Clean separation
|
||||
├── Automatic cleanup (yield)
|
||||
```
|
||||
|
||||
### Pydantic v2 Integration
|
||||
|
||||
```python
|
||||
# FastAPI + Pydantic are tightly integrated:
|
||||
|
||||
# Request validation
|
||||
@app.post("/users")
|
||||
async def create(user: UserCreate) -> UserResponse:
|
||||
# user is already validated
|
||||
...
|
||||
|
||||
# Response serialization
|
||||
# Return type becomes response schema
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Background Tasks
|
||||
|
||||
### Selection Guide
|
||||
|
||||
| Solution | Best For |
|
||||
|----------|----------|
|
||||
| **BackgroundTasks** | Simple, in-process tasks |
|
||||
| **Celery** | Distributed, complex workflows |
|
||||
| **ARQ** | Async, Redis-based |
|
||||
| **RQ** | Simple Redis queue |
|
||||
| **Dramatiq** | Actor-based, simpler than Celery |
|
||||
|
||||
### When to Use Each
|
||||
|
||||
```
|
||||
FastAPI BackgroundTasks:
|
||||
├── Quick operations
|
||||
├── No persistence needed
|
||||
├── Fire-and-forget
|
||||
└── Same process
|
||||
|
||||
Celery/ARQ:
|
||||
├── Long-running tasks
|
||||
├── Need retry logic
|
||||
├── Distributed workers
|
||||
├── Persistent queue
|
||||
└── Complex workflows
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Error Handling Principles
|
||||
|
||||
### Exception Strategy
|
||||
|
||||
```
|
||||
In FastAPI:
|
||||
├── Create custom exception classes
|
||||
├── Register exception handlers
|
||||
├── Return consistent error format
|
||||
└── Log without exposing internals
|
||||
|
||||
Pattern:
|
||||
├── Raise domain exceptions in services
|
||||
├── Catch and transform in handlers
|
||||
└── Client gets clean error response
|
||||
```
|
||||
|
||||
### Error Response Philosophy
|
||||
|
||||
```
|
||||
Include:
|
||||
├── Error code (programmatic)
|
||||
├── Message (human readable)
|
||||
├── Details (field-level when applicable)
|
||||
└── NOT stack traces (security)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Testing Principles
|
||||
|
||||
### Testing Strategy
|
||||
|
||||
| Type | Purpose | Tools |
|
||||
|------|---------|-------|
|
||||
| **Unit** | Business logic | pytest |
|
||||
| **Integration** | API endpoints | pytest + httpx/TestClient |
|
||||
| **E2E** | Full workflows | pytest + DB |
|
||||
|
||||
### Async Testing
|
||||
|
||||
```python
|
||||
# Use pytest-asyncio for async tests
|
||||
|
||||
import pytest
|
||||
from httpx import AsyncClient
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_endpoint():
|
||||
async with AsyncClient(app=app, base_url="http://test") as client:
|
||||
response = await client.get("/users")
|
||||
assert response.status_code == 200
|
||||
```
|
||||
|
||||
### Fixtures Strategy
|
||||
|
||||
```
|
||||
Common fixtures:
|
||||
├── db_session → Database connection
|
||||
├── client → Test client
|
||||
├── authenticated_user → User with token
|
||||
└── sample_data → Test data setup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Decision Checklist
|
||||
|
||||
Before implementing:
|
||||
|
||||
- [ ] **Asked user about framework preference?**
|
||||
- [ ] **Chosen framework for THIS context?** (not just default)
|
||||
- [ ] **Decided async vs sync?**
|
||||
- [ ] **Planned type hint strategy?**
|
||||
- [ ] **Defined project structure?**
|
||||
- [ ] **Planned error handling?**
|
||||
- [ ] **Considered background tasks?**
|
||||
|
||||
---
|
||||
|
||||
## 11. Anti-Patterns to Avoid
|
||||
|
||||
### ❌ DON'T:
|
||||
- Default to Django for simple APIs (FastAPI may be better)
|
||||
- Use sync libraries in async code
|
||||
- Skip type hints for public APIs
|
||||
- Put business logic in routes/views
|
||||
- Ignore N+1 queries
|
||||
- Mix async and sync carelessly
|
||||
|
||||
### ✅ DO:
|
||||
- Choose framework based on context
|
||||
- Ask about async requirements
|
||||
- Use Pydantic for validation
|
||||
- Separate concerns (routes → services → repos)
|
||||
- Test critical paths
|
||||
|
||||
---
|
||||
|
||||
> **Remember**: Python patterns are about decision-making for YOUR specific context. Don't copy code—think about what serves your application best.
|
||||
198
skills/react-patterns/SKILL.md
Normal file
198
skills/react-patterns/SKILL.md
Normal file
@@ -0,0 +1,198 @@
|
||||
---
|
||||
name: react-patterns
|
||||
description: Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# React Patterns
|
||||
|
||||
> Principles for building production-ready React applications.
|
||||
|
||||
---
|
||||
|
||||
## 1. Component Design Principles
|
||||
|
||||
### Component Types
|
||||
|
||||
| Type | Use | State |
|
||||
|------|-----|-------|
|
||||
| **Server** | Data fetching, static | None |
|
||||
| **Client** | Interactivity | useState, effects |
|
||||
| **Presentational** | UI display | Props only |
|
||||
| **Container** | Logic/state | Heavy state |
|
||||
|
||||
### Design Rules
|
||||
|
||||
- One responsibility per component
|
||||
- Props down, events up
|
||||
- Composition over inheritance
|
||||
- Prefer small, focused components
|
||||
|
||||
---
|
||||
|
||||
## 2. Hook Patterns
|
||||
|
||||
### When to Extract Hooks
|
||||
|
||||
| Pattern | Extract When |
|
||||
|---------|-------------|
|
||||
| **useLocalStorage** | Same storage logic needed |
|
||||
| **useDebounce** | Multiple debounced values |
|
||||
| **useFetch** | Repeated fetch patterns |
|
||||
| **useForm** | Complex form state |
|
||||
|
||||
### Hook Rules
|
||||
|
||||
- Hooks at top level only
|
||||
- Same order every render
|
||||
- Custom hooks start with "use"
|
||||
- Clean up effects on unmount
|
||||
|
||||
---
|
||||
|
||||
## 3. State Management Selection
|
||||
|
||||
| Complexity | Solution |
|
||||
|------------|----------|
|
||||
| Simple | useState, useReducer |
|
||||
| Shared local | Context |
|
||||
| Server state | React Query, SWR |
|
||||
| Complex global | Zustand, Redux Toolkit |
|
||||
|
||||
### State Placement
|
||||
|
||||
| Scope | Where |
|
||||
|-------|-------|
|
||||
| Single component | useState |
|
||||
| Parent-child | Lift state up |
|
||||
| Subtree | Context |
|
||||
| App-wide | Global store |
|
||||
|
||||
---
|
||||
|
||||
## 4. React 19 Patterns
|
||||
|
||||
### New Hooks
|
||||
|
||||
| Hook | Purpose |
|
||||
|------|---------|
|
||||
| **useActionState** | Form submission state |
|
||||
| **useOptimistic** | Optimistic UI updates |
|
||||
| **use** | Read resources in render |
|
||||
|
||||
### Compiler Benefits
|
||||
|
||||
- Automatic memoization
|
||||
- Less manual useMemo/useCallback
|
||||
- Focus on pure components
|
||||
|
||||
---
|
||||
|
||||
## 5. Composition Patterns
|
||||
|
||||
### Compound Components
|
||||
|
||||
- Parent provides context
|
||||
- Children consume context
|
||||
- Flexible slot-based composition
|
||||
- Example: Tabs, Accordion, Dropdown
|
||||
|
||||
### Render Props vs Hooks
|
||||
|
||||
| Use Case | Prefer |
|
||||
|----------|--------|
|
||||
| Reusable logic | Custom hook |
|
||||
| Render flexibility | Render props |
|
||||
| Cross-cutting | Higher-order component |
|
||||
|
||||
---
|
||||
|
||||
## 6. Performance Principles
|
||||
|
||||
### When to Optimize
|
||||
|
||||
| Signal | Action |
|
||||
|--------|--------|
|
||||
| Slow renders | Profile first |
|
||||
| Large lists | Virtualize |
|
||||
| Expensive calc | useMemo |
|
||||
| Stable callbacks | useCallback |
|
||||
|
||||
### Optimization Order
|
||||
|
||||
1. Check if actually slow
|
||||
2. Profile with DevTools
|
||||
3. Identify bottleneck
|
||||
4. Apply targeted fix
|
||||
|
||||
---
|
||||
|
||||
## 7. Error Handling
|
||||
|
||||
### Error Boundary Usage
|
||||
|
||||
| Scope | Placement |
|
||||
|-------|-----------|
|
||||
| App-wide | Root level |
|
||||
| Feature | Route/feature level |
|
||||
| Component | Around risky component |
|
||||
|
||||
### Error Recovery
|
||||
|
||||
- Show fallback UI
|
||||
- Log error
|
||||
- Offer retry option
|
||||
- Preserve user data
|
||||
|
||||
---
|
||||
|
||||
## 8. TypeScript Patterns
|
||||
|
||||
### Props Typing
|
||||
|
||||
| Pattern | Use |
|
||||
|---------|-----|
|
||||
| Interface | Component props |
|
||||
| Type | Unions, complex |
|
||||
| Generic | Reusable components |
|
||||
|
||||
### Common Types
|
||||
|
||||
| Need | Type |
|
||||
|------|------|
|
||||
| Children | ReactNode |
|
||||
| Event handler | MouseEventHandler |
|
||||
| Ref | RefObject<Element> |
|
||||
|
||||
---
|
||||
|
||||
## 9. Testing Principles
|
||||
|
||||
| Level | Focus |
|
||||
|-------|-------|
|
||||
| Unit | Pure functions, hooks |
|
||||
| Integration | Component behavior |
|
||||
| E2E | User flows |
|
||||
|
||||
### Test Priorities
|
||||
|
||||
- User-visible behavior
|
||||
- Edge cases
|
||||
- Error states
|
||||
- Accessibility
|
||||
|
||||
---
|
||||
|
||||
## 10. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Prop drilling deep | Use context |
|
||||
| Giant components | Split smaller |
|
||||
| useEffect for everything | Server components |
|
||||
| Premature optimization | Profile first |
|
||||
| Index as key | Stable unique ID |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** React is about composition. Build small, combine thoughtfully.
|
||||
199
skills/red-team-tactics/SKILL.md
Normal file
199
skills/red-team-tactics/SKILL.md
Normal file
@@ -0,0 +1,199 @@
|
||||
---
|
||||
name: red-team-tactics
|
||||
description: Red team tactics principles based on MITRE ATT&CK. Attack phases, detection evasion, reporting.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# Red Team Tactics
|
||||
|
||||
> Adversary simulation principles based on MITRE ATT&CK framework.
|
||||
|
||||
---
|
||||
|
||||
## 1. MITRE ATT&CK Phases
|
||||
|
||||
### Attack Lifecycle
|
||||
|
||||
```
|
||||
RECONNAISSANCE → INITIAL ACCESS → EXECUTION → PERSISTENCE
|
||||
↓ ↓ ↓ ↓
|
||||
PRIVILEGE ESC → DEFENSE EVASION → CRED ACCESS → DISCOVERY
|
||||
↓ ↓ ↓ ↓
|
||||
LATERAL MOVEMENT → COLLECTION → C2 → EXFILTRATION → IMPACT
|
||||
```
|
||||
|
||||
### Phase Objectives
|
||||
|
||||
| Phase | Objective |
|
||||
|-------|-----------|
|
||||
| **Recon** | Map attack surface |
|
||||
| **Initial Access** | Get first foothold |
|
||||
| **Execution** | Run code on target |
|
||||
| **Persistence** | Survive reboots |
|
||||
| **Privilege Escalation** | Get admin/root |
|
||||
| **Defense Evasion** | Avoid detection |
|
||||
| **Credential Access** | Harvest credentials |
|
||||
| **Discovery** | Map internal network |
|
||||
| **Lateral Movement** | Spread to other systems |
|
||||
| **Collection** | Gather target data |
|
||||
| **C2** | Maintain command channel |
|
||||
| **Exfiltration** | Extract data |
|
||||
|
||||
---
|
||||
|
||||
## 2. Reconnaissance Principles
|
||||
|
||||
### Passive vs Active
|
||||
|
||||
| Type | Trade-off |
|
||||
|------|-----------|
|
||||
| **Passive** | No target contact, limited info |
|
||||
| **Active** | Direct contact, more detection risk |
|
||||
|
||||
### Information Targets
|
||||
|
||||
| Category | Value |
|
||||
|----------|-------|
|
||||
| Technology stack | Attack vector selection |
|
||||
| Employee info | Social engineering |
|
||||
| Network ranges | Scanning scope |
|
||||
| Third parties | Supply chain attack |
|
||||
|
||||
---
|
||||
|
||||
## 3. Initial Access Vectors
|
||||
|
||||
### Selection Criteria
|
||||
|
||||
| Vector | When to Use |
|
||||
|--------|-------------|
|
||||
| **Phishing** | Human target, email access |
|
||||
| **Public exploits** | Vulnerable services exposed |
|
||||
| **Valid credentials** | Leaked or cracked |
|
||||
| **Supply chain** | Third-party access |
|
||||
|
||||
---
|
||||
|
||||
## 4. Privilege Escalation Principles
|
||||
|
||||
### Windows Targets
|
||||
|
||||
| Check | Opportunity |
|
||||
|-------|-------------|
|
||||
| Unquoted service paths | Write to path |
|
||||
| Weak service permissions | Modify service |
|
||||
| Token privileges | Abuse SeDebug, etc. |
|
||||
| Stored credentials | Harvest |
|
||||
|
||||
### Linux Targets
|
||||
|
||||
| Check | Opportunity |
|
||||
|-------|-------------|
|
||||
| SUID binaries | Execute as owner |
|
||||
| Sudo misconfiguration | Command execution |
|
||||
| Kernel vulnerabilities | Kernel exploits |
|
||||
| Cron jobs | Writable scripts |
|
||||
|
||||
---
|
||||
|
||||
## 5. Defense Evasion Principles
|
||||
|
||||
### Key Techniques
|
||||
|
||||
| Technique | Purpose |
|
||||
|-----------|---------|
|
||||
| LOLBins | Use legitimate tools |
|
||||
| Obfuscation | Hide malicious code |
|
||||
| Timestomping | Hide file modifications |
|
||||
| Log clearing | Remove evidence |
|
||||
|
||||
### Operational Security
|
||||
|
||||
- Work during business hours
|
||||
- Mimic legitimate traffic patterns
|
||||
- Use encrypted channels
|
||||
- Blend with normal behavior
|
||||
|
||||
---
|
||||
|
||||
## 6. Lateral Movement Principles
|
||||
|
||||
### Credential Types
|
||||
|
||||
| Type | Use |
|
||||
|------|-----|
|
||||
| Password | Standard auth |
|
||||
| Hash | Pass-the-hash |
|
||||
| Ticket | Pass-the-ticket |
|
||||
| Certificate | Certificate auth |
|
||||
|
||||
### Movement Paths
|
||||
|
||||
- Admin shares
|
||||
- Remote services (RDP, SSH, WinRM)
|
||||
- Exploitation of internal services
|
||||
|
||||
---
|
||||
|
||||
## 7. Active Directory Attacks
|
||||
|
||||
### Attack Categories
|
||||
|
||||
| Attack | Target |
|
||||
|--------|--------|
|
||||
| Kerberoasting | Service account passwords |
|
||||
| AS-REP Roasting | Accounts without pre-auth |
|
||||
| DCSync | Domain credentials |
|
||||
| Golden Ticket | Persistent domain access |
|
||||
|
||||
---
|
||||
|
||||
## 8. Reporting Principles
|
||||
|
||||
### Attack Narrative
|
||||
|
||||
Document the full attack chain:
|
||||
1. How initial access was gained
|
||||
2. What techniques were used
|
||||
3. What objectives were achieved
|
||||
4. Where detection failed
|
||||
|
||||
### Detection Gaps
|
||||
|
||||
For each successful technique:
|
||||
- What should have detected it?
|
||||
- Why didn't detection work?
|
||||
- How to improve detection
|
||||
|
||||
---
|
||||
|
||||
## 9. Ethical Boundaries
|
||||
|
||||
### Always
|
||||
|
||||
- Stay within scope
|
||||
- Minimize impact
|
||||
- Report immediately if real threat found
|
||||
- Document all actions
|
||||
|
||||
### Never
|
||||
|
||||
- Destroy production data
|
||||
- Cause denial of service (unless scoped)
|
||||
- Access beyond proof of concept
|
||||
- Retain sensitive data
|
||||
|
||||
---
|
||||
|
||||
## 10. Anti-Patterns
|
||||
|
||||
| ❌ Don't | ✅ Do |
|
||||
|----------|-------|
|
||||
| Rush to exploitation | Follow methodology |
|
||||
| Cause damage | Minimize impact |
|
||||
| Skip reporting | Document everything |
|
||||
| Ignore scope | Stay within boundaries |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** Red team simulates attackers to improve defenses, not to cause harm.
|
||||
129
skills/seo-fundamentals/SKILL.md
Normal file
129
skills/seo-fundamentals/SKILL.md
Normal file
@@ -0,0 +1,129 @@
|
||||
---
|
||||
name: seo-fundamentals
|
||||
description: SEO fundamentals, E-E-A-T, Core Web Vitals, and Google algorithm principles.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
---
|
||||
|
||||
# SEO Fundamentals
|
||||
|
||||
> Principles for search engine visibility.
|
||||
|
||||
---
|
||||
|
||||
## 1. E-E-A-T Framework
|
||||
|
||||
| Principle | Signals |
|
||||
|-----------|---------|
|
||||
| **Experience** | First-hand knowledge, real examples |
|
||||
| **Expertise** | Credentials, depth of knowledge |
|
||||
| **Authoritativeness** | Backlinks, mentions, industry recognition |
|
||||
| **Trustworthiness** | HTTPS, transparency, accurate info |
|
||||
|
||||
---
|
||||
|
||||
## 2. Core Web Vitals
|
||||
|
||||
| Metric | Target | Measures |
|
||||
|--------|--------|----------|
|
||||
| **LCP** | < 2.5s | Loading performance |
|
||||
| **INP** | < 200ms | Interactivity |
|
||||
| **CLS** | < 0.1 | Visual stability |
|
||||
|
||||
---
|
||||
|
||||
## 3. Technical SEO Principles
|
||||
|
||||
### Site Structure
|
||||
|
||||
| Element | Purpose |
|
||||
|---------|---------|
|
||||
| XML sitemap | Help crawling |
|
||||
| robots.txt | Control access |
|
||||
| Canonical tags | Prevent duplicates |
|
||||
| HTTPS | Security signal |
|
||||
|
||||
### Performance
|
||||
|
||||
| Factor | Impact |
|
||||
|--------|--------|
|
||||
| Page speed | Core Web Vital |
|
||||
| Mobile-friendly | Ranking factor |
|
||||
| Clean URLs | Crawlability |
|
||||
|
||||
---
|
||||
|
||||
## 4. Content SEO Principles
|
||||
|
||||
### Page Elements
|
||||
|
||||
| Element | Best Practice |
|
||||
|---------|---------------|
|
||||
| Title tag | 50-60 chars, keyword front |
|
||||
| Meta description | 150-160 chars, compelling |
|
||||
| H1 | One per page, main keyword |
|
||||
| H2-H6 | Logical hierarchy |
|
||||
| Alt text | Descriptive, not stuffed |
|
||||
|
||||
### Content Quality
|
||||
|
||||
| Factor | Importance |
|
||||
|--------|------------|
|
||||
| Depth | Comprehensive coverage |
|
||||
| Freshness | Regular updates |
|
||||
| Uniqueness | Original value |
|
||||
| Readability | Clear writing |
|
||||
|
||||
---
|
||||
|
||||
## 5. Schema Markup Types
|
||||
|
||||
| Type | Use |
|
||||
|------|-----|
|
||||
| Article | Blog posts, news |
|
||||
| Organization | Company info |
|
||||
| Person | Author profiles |
|
||||
| FAQPage | Q&A content |
|
||||
| Product | E-commerce |
|
||||
| Review | Ratings |
|
||||
| BreadcrumbList | Navigation |
|
||||
|
||||
---
|
||||
|
||||
## 6. AI Content Guidelines
|
||||
|
||||
### What Google Looks For
|
||||
|
||||
| ✅ Do | ❌ Don't |
|
||||
|-------|----------|
|
||||
| AI draft + human edit | Publish raw AI content |
|
||||
| Add original insights | Copy without value |
|
||||
| Expert review | Skip fact-checking |
|
||||
| Follow E-E-A-T | Keyword stuffing |
|
||||
|
||||
---
|
||||
|
||||
## 7. Ranking Factors (Prioritized)
|
||||
|
||||
| Priority | Factor |
|
||||
|----------|--------|
|
||||
| 1 | Quality, relevant content |
|
||||
| 2 | Backlinks from authority sites |
|
||||
| 3 | Page experience (Core Web Vitals) |
|
||||
| 4 | Mobile optimization |
|
||||
| 5 | Technical SEO fundamentals |
|
||||
|
||||
---
|
||||
|
||||
## 8. Measurement
|
||||
|
||||
| Metric | Tool |
|
||||
|--------|------|
|
||||
| Rankings | Search Console, Ahrefs |
|
||||
| Traffic | Analytics |
|
||||
| Core Web Vitals | PageSpeed Insights |
|
||||
| Indexing | Search Console |
|
||||
| Backlinks | Ahrefs, Semrush |
|
||||
|
||||
---
|
||||
|
||||
> **Remember:** SEO is a long-term game. Quality content + technical excellence + patience = results.
|
||||
219
skills/seo-fundamentals/scripts/seo_checker.py
Normal file
219
skills/seo-fundamentals/scripts/seo_checker.py
Normal file
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SEO Checker - Search Engine Optimization Audit
|
||||
Checks HTML/JSX/TSX pages for SEO best practices.
|
||||
|
||||
PURPOSE:
|
||||
- Verify meta tags, titles, descriptions
|
||||
- Check Open Graph tags for social sharing
|
||||
- Validate heading hierarchy
|
||||
- Check image accessibility (alt attributes)
|
||||
|
||||
WHAT IT CHECKS:
|
||||
- HTML files (actual web pages)
|
||||
- JSX/TSX files (React page components)
|
||||
- Only files that are likely PUBLIC pages
|
||||
|
||||
Usage:
|
||||
python seo_checker.py <project_path>
|
||||
"""
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Fix Windows console encoding
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# Directories to skip
|
||||
SKIP_DIRS = {
|
||||
'node_modules', '.next', 'dist', 'build', '.git', '.github',
|
||||
'__pycache__', '.vscode', '.idea', 'coverage', 'test', 'tests',
|
||||
'__tests__', 'spec', 'docs', 'documentation', 'examples'
|
||||
}
|
||||
|
||||
# Files to skip (not pages)
|
||||
SKIP_PATTERNS = [
|
||||
'config', 'setup', 'util', 'helper', 'hook', 'context', 'store',
|
||||
'service', 'api', 'lib', 'constant', 'type', 'interface', 'mock',
|
||||
'.test.', '.spec.', '_test.', '_spec.'
|
||||
]
|
||||
|
||||
|
||||
def is_page_file(file_path: Path) -> bool:
|
||||
"""Check if this file is likely a public-facing page."""
|
||||
name = file_path.name.lower()
|
||||
stem = file_path.stem.lower()
|
||||
|
||||
# Skip utility/config files
|
||||
if any(skip in name for skip in SKIP_PATTERNS):
|
||||
return False
|
||||
|
||||
# Check path - pages in specific directories are likely pages
|
||||
parts = [p.lower() for p in file_path.parts]
|
||||
page_dirs = ['pages', 'app', 'routes', 'views', 'screens']
|
||||
|
||||
if any(d in parts for d in page_dirs):
|
||||
return True
|
||||
|
||||
# Filename indicators for pages
|
||||
page_names = ['page', 'index', 'home', 'about', 'contact', 'blog',
|
||||
'post', 'article', 'product', 'landing', 'layout']
|
||||
|
||||
if any(p in stem for p in page_names):
|
||||
return True
|
||||
|
||||
# HTML files are usually pages
|
||||
if file_path.suffix.lower() in ['.html', '.htm']:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def find_pages(project_path: Path) -> list:
|
||||
"""Find page files to check."""
|
||||
patterns = ['**/*.html', '**/*.htm', '**/*.jsx', '**/*.tsx']
|
||||
|
||||
files = []
|
||||
for pattern in patterns:
|
||||
for f in project_path.glob(pattern):
|
||||
# Skip excluded directories
|
||||
if any(skip in f.parts for skip in SKIP_DIRS):
|
||||
continue
|
||||
|
||||
# Check if it's likely a page
|
||||
if is_page_file(f):
|
||||
files.append(f)
|
||||
|
||||
return files[:50] # Limit to 50 files
|
||||
|
||||
|
||||
def check_page(file_path: Path) -> dict:
|
||||
"""Check a single page for SEO issues."""
|
||||
issues = []
|
||||
|
||||
try:
|
||||
content = file_path.read_text(encoding='utf-8', errors='ignore')
|
||||
except Exception as e:
|
||||
return {"file": str(file_path.name), "issues": [f"Error: {e}"]}
|
||||
|
||||
# Detect if this is a layout/template file (has Head component)
|
||||
is_layout = 'Head>' in content or '<head' in content.lower()
|
||||
|
||||
# 1. Title tag
|
||||
has_title = '<title' in content.lower() or 'title=' in content or 'Head>' in content
|
||||
if not has_title and is_layout:
|
||||
issues.append("Missing <title> tag")
|
||||
|
||||
# 2. Meta description
|
||||
has_description = 'name="description"' in content.lower() or 'name=\'description\'' in content.lower()
|
||||
if not has_description and is_layout:
|
||||
issues.append("Missing meta description")
|
||||
|
||||
# 3. Open Graph tags
|
||||
has_og = 'og:' in content or 'property="og:' in content.lower()
|
||||
if not has_og and is_layout:
|
||||
issues.append("Missing Open Graph tags")
|
||||
|
||||
# 4. Heading hierarchy - multiple H1s
|
||||
h1_matches = re.findall(r'<h1[^>]*>', content, re.I)
|
||||
if len(h1_matches) > 1:
|
||||
issues.append(f"Multiple H1 tags ({len(h1_matches)})")
|
||||
|
||||
# 5. Images without alt
|
||||
img_pattern = r'<img[^>]+>'
|
||||
imgs = re.findall(img_pattern, content, re.I)
|
||||
for img in imgs:
|
||||
if 'alt=' not in img.lower():
|
||||
issues.append("Image missing alt attribute")
|
||||
break
|
||||
if 'alt=""' in img or "alt=''" in img:
|
||||
issues.append("Image has empty alt attribute")
|
||||
break
|
||||
|
||||
# 6. Check for canonical link (nice to have)
|
||||
# has_canonical = 'rel="canonical"' in content.lower()
|
||||
|
||||
return {
|
||||
"file": str(file_path.name),
|
||||
"issues": issues
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
project_path = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f" SEO CHECKER - Search Engine Optimization Audit")
|
||||
print(f"{'='*60}")
|
||||
print(f"Project: {project_path}")
|
||||
print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print("-"*60)
|
||||
|
||||
# Find pages
|
||||
pages = find_pages(project_path)
|
||||
|
||||
if not pages:
|
||||
print("\n[!] No page files found.")
|
||||
print(" Looking for: HTML, JSX, TSX in pages/app/routes directories")
|
||||
output = {"script": "seo_checker", "files_checked": 0, "passed": True}
|
||||
print("\n" + json.dumps(output, indent=2))
|
||||
sys.exit(0)
|
||||
|
||||
print(f"Found {len(pages)} page files to analyze\n")
|
||||
|
||||
# Check each page
|
||||
all_issues = []
|
||||
for f in pages:
|
||||
result = check_page(f)
|
||||
if result["issues"]:
|
||||
all_issues.append(result)
|
||||
|
||||
# Summary
|
||||
print("=" * 60)
|
||||
print("SEO ANALYSIS RESULTS")
|
||||
print("=" * 60)
|
||||
|
||||
if all_issues:
|
||||
# Group by issue type
|
||||
issue_counts = {}
|
||||
for item in all_issues:
|
||||
for issue in item["issues"]:
|
||||
issue_counts[issue] = issue_counts.get(issue, 0) + 1
|
||||
|
||||
print("\nIssue Summary:")
|
||||
for issue, count in sorted(issue_counts.items(), key=lambda x: -x[1]):
|
||||
print(f" [{count}] {issue}")
|
||||
|
||||
print(f"\nAffected files ({len(all_issues)}):")
|
||||
for item in all_issues[:5]:
|
||||
print(f" - {item['file']}")
|
||||
if len(all_issues) > 5:
|
||||
print(f" ... and {len(all_issues) - 5} more")
|
||||
else:
|
||||
print("\n[OK] No SEO issues found!")
|
||||
|
||||
total_issues = sum(len(item["issues"]) for item in all_issues)
|
||||
passed = total_issues == 0
|
||||
|
||||
output = {
|
||||
"script": "seo_checker",
|
||||
"project": str(project_path),
|
||||
"files_checked": len(pages),
|
||||
"files_with_issues": len(all_issues),
|
||||
"issues_found": total_issues,
|
||||
"passed": passed
|
||||
}
|
||||
|
||||
print("\n" + json.dumps(output, indent=2))
|
||||
|
||||
sys.exit(0 if passed else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user