Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66b777a937 | ||
|
|
63d98348d2 | ||
|
|
79f2642f4e | ||
|
|
48d458ce0b | ||
|
|
9df73a8e56 | ||
|
|
2d7529b613 | ||
|
|
283c4e6ae7 | ||
|
|
c7f7f23bd7 | ||
|
|
d2569f2107 | ||
|
|
4c272bfcbf | ||
|
|
256bfeee73 | ||
|
|
f57a068782 | ||
|
|
0c93e28ace | ||
|
|
899c8a01da | ||
|
|
4ff7187be6 | ||
|
|
d19edbebfb | ||
|
|
2001965e52 | ||
|
|
866d6954f7 | ||
|
|
7e5d8d52a1 | ||
|
|
b55e7e39cc | ||
|
|
f728d0d816 | ||
|
|
c8de7f50f8 | ||
|
|
9891cb28ed | ||
|
|
4d32a3e2af | ||
|
|
53927c5aec | ||
|
|
699ceabd57 | ||
|
|
c8e7424ea6 | ||
|
|
14fb3b5159 | ||
|
|
691b02c817 | ||
|
|
acc6dbc84f | ||
|
|
d8453057df | ||
|
|
f45abe634d | ||
|
|
85480f4ce4 | ||
|
|
e5d2a7e1ec | ||
|
|
c04d59d91d | ||
|
|
7d061238e6 | ||
|
|
805ef578f4 | ||
|
|
0792c9a505 | ||
|
|
86c74656aa | ||
|
|
a11280426c | ||
|
|
99fbad717f | ||
|
|
706a84b873 | ||
|
|
0f4a1b2fd7 | ||
|
|
c0348ca1b5 | ||
|
|
441189cd90 | ||
|
|
e242186fe2 | ||
|
|
45e2049663 | ||
|
|
c96815ed7c | ||
|
|
1e03172075 | ||
|
|
7280be2d63 | ||
|
|
b3c75a3ab0 | ||
|
|
0b9d17a95f | ||
|
|
c51ca4a4bf | ||
|
|
f155a8ff24 | ||
|
|
f7b16b436b | ||
|
|
79ed5ead64 | ||
|
|
d75824bfd0 | ||
|
|
173c634b46 | ||
|
|
41309cfd7d | ||
|
|
36107a5cae | ||
|
|
238cfc6933 | ||
|
|
f28591e648 | ||
|
|
d38e2eeab1 | ||
|
|
4fe8a1e6a4 | ||
|
|
1557826c5d | ||
|
|
bec54d7abb | ||
|
|
23f9ad547c | ||
|
|
28def60eec | ||
|
|
902063fd0a | ||
|
|
9ff0cc0b74 | ||
|
|
ae3d038711 | ||
|
|
af57b96721 | ||
|
|
d5d420d2e1 | ||
|
|
e053fd0eb7 | ||
|
|
ee5511fc59 | ||
|
|
f54c340851 | ||
|
|
ad83399403 | ||
|
|
40fd263b4e | ||
|
|
0405d4a577 | ||
|
|
00079b5bff | ||
|
|
27ce8af114 | ||
|
|
5e888ef6bb | ||
|
|
1134e1e735 | ||
|
|
4803af0b95 | ||
|
|
df0f084ac6 | ||
|
|
d962bb21ea | ||
|
|
807f72a5be | ||
|
|
c29f87c2a9 | ||
|
|
06e8811af6 | ||
|
|
afafa37a2e | ||
|
|
c69b033ada | ||
|
|
2f01e2b267 | ||
|
|
91f46351be | ||
|
|
910cbeb8e0 | ||
|
|
2e835b9d66 | ||
|
|
4057e379d9 | ||
|
|
2d5a9a3e85 | ||
|
|
5d01094479 | ||
|
|
3c38ec509d | ||
|
|
4365fba248 | ||
|
|
2885b4ebaa | ||
|
|
63074bc2b7 | ||
|
|
33d8f93c7f | ||
|
|
c688c5e0fa | ||
|
|
590ea1e5b3 | ||
|
|
33908288f1 | ||
|
|
831d87605a | ||
|
|
c6df6cee4c | ||
|
|
8c8bae5e98 | ||
|
|
a10633744d | ||
|
|
10f00a45dd | ||
|
|
29b45dd234 | ||
|
|
81ecf7cec3 | ||
|
|
f6cdf4dc59 | ||
|
|
fef11a8059 | ||
|
|
ebdc51708c | ||
|
|
41fa3734ba | ||
|
|
b64c73015c | ||
|
|
a02afe1d72 | ||
|
|
408f188262 | ||
|
|
23f58f8705 | ||
|
|
90cf84b8bb | ||
|
|
4ee8a0361f | ||
|
|
e0fdc4e263 | ||
|
|
993775eb4d | ||
|
|
d672808990 | ||
|
|
13bdb4970c | ||
|
|
2db2ca8220 | ||
|
|
9720f75ebe | ||
|
|
e56affd8c8 | ||
|
|
518edc9a3c | ||
|
|
57ce2dd084 | ||
|
|
1bd7db87b9 | ||
|
|
41576e7664 | ||
|
|
c3e5876b7c | ||
|
|
da230d00b0 | ||
|
|
674fa7703d | ||
|
|
a9ff10d511 | ||
|
|
a61c0ed79b | ||
|
|
1f753cd190 |
143
.github/MAINTENANCE.md
vendored
Normal file
143
.github/MAINTENANCE.md
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
# 🛠️ Repository Maintenance Guide (V3)
|
||||
|
||||
> **"If it's not documented, it's broken."**
|
||||
|
||||
This guide details the exact procedures for maintaining `antigravity-awesome-skills`.
|
||||
It covers the **Quality Bar**, **Documentation Consistency**, and **Release Workflows**.
|
||||
|
||||
---
|
||||
|
||||
## 1. 🚦 Daily Maintenance Routine
|
||||
|
||||
### A. Validation Chain
|
||||
|
||||
Before ANY commit that adds/modifies skills, run the chain:
|
||||
|
||||
1. **Validate Metadata & Quality**:
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_skills.py
|
||||
```
|
||||
|
||||
_Must return 0 errors for new skills._
|
||||
|
||||
2. **Regenerate Index**:
|
||||
python3 scripts/generate_index.py
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
3. **Update Readme**:
|
||||
|
||||
```bash
|
||||
python3 scripts/update_readme.py
|
||||
```
|
||||
|
||||
4. **COMMIT GENERATED FILES**:
|
||||
```bash
|
||||
git add skills_index.json README.md
|
||||
git commit -m "chore: sync generated files"
|
||||
```
|
||||
> 🔴 **CRITICAL**: If you skip this, CI will fail with "Detected uncommitted changes".
|
||||
> See [docs/CI_DRIFT_FIX.md](../docs/CI_DRIFT_FIX.md) for details.
|
||||
|
||||
### B. Post-Merge Routine (Must Do)
|
||||
|
||||
After multiple PR merges or significant changes:
|
||||
|
||||
1. **Sync Contributors List**:
|
||||
- Run: `git shortlog -sn --all`
|
||||
- Update `## Repo Contributors` in README.md.
|
||||
|
||||
2. **Verify Table of Contents**:
|
||||
- Ensure all new headers have clean anchors.
|
||||
- **NO EMOJIS** in H2 headers.
|
||||
|
||||
3. **Draft a Release**:
|
||||
- Go to [Releases Page](https://github.com/sickn33/antigravity-awesome-skills/releases).
|
||||
- Draft a new release for the merged changes.
|
||||
- Tag version (e.g., `v3.1.0`).
|
||||
|
||||
---
|
||||
|
||||
## 2. 📝 Documentation "Pixel Perfect" Rules
|
||||
|
||||
We discovered several consistency issues during V3 development. Follow these rules STRICTLY.
|
||||
|
||||
### A. Table of Contents (TOC) Anchors
|
||||
|
||||
GitHub's anchor generation breaks if headers have emojis.
|
||||
|
||||
- **BAD**: `## 🚀 New Here?` -> Anchor: `#--new-here` (Broken)
|
||||
- **GOOD**: `## New Here?` -> Anchor: `#new-here` (Clean)
|
||||
|
||||
**Rule**: **NEVER put emojis in H2 (`##`) headers.** Put them in the text below if needed.
|
||||
|
||||
### B. The "Trinity" of Docs
|
||||
|
||||
If you update installation instructions or tool compatibility, you MUST update all 3 files:
|
||||
|
||||
1. `README.md` (Source of Truth)
|
||||
2. `GETTING_STARTED.md` (Beginner Guide)
|
||||
3. `FAQ.md` (Troubleshooting)
|
||||
|
||||
_Common pitfall: Updating the clone URL in README but leaving an old one in FAQ._
|
||||
|
||||
### C. Statistics
|
||||
|
||||
If you add skills, update the counts:
|
||||
|
||||
- Title of `README.md`: "253+ Agentic Skills..."
|
||||
- `## Full Skill Registry (253/253)` header.
|
||||
- `GETTING_STARTED.md` intro.
|
||||
|
||||
### D. Badges & Links
|
||||
|
||||
- **Antigravity Badge**: Must point to `https://github.com/sickn33/antigravity-awesome-skills`, NOT `anthropics/antigravity`.
|
||||
- **License**: Ensure the link points to `LICENSE` file.
|
||||
|
||||
---
|
||||
|
||||
## 3. 🛡️ Governance & Quality Bar
|
||||
|
||||
### A. The 5-Point Quality Check
|
||||
|
||||
Reject any PR that fails this:
|
||||
|
||||
1. **Metadata**: Has `name`, `description`?
|
||||
2. **Safety**: `risk: offensive` used for red-team tools?
|
||||
3. **Clarity**: Does it say _when_ to use it?
|
||||
4. **Examples**: Copy-pasteable code blocks?
|
||||
5. **Actions**: "Run this command" vs "Think about this".
|
||||
|
||||
### B. Risk Labels (V3)
|
||||
|
||||
- ⚪ **Safe**: Default.
|
||||
- 🔴 **Risk**: Destructive/Security tools. MUST have `[Authorized Use Only]` warning.
|
||||
- 🟣 **Official**: Vendor mirrors only.
|
||||
|
||||
---
|
||||
|
||||
## 4. 🚀 Release Workflow
|
||||
|
||||
When cutting a new version (e.g., V4):
|
||||
|
||||
1. **Run Full Validation**: `python3 scripts/validate_skills.py --strict`
|
||||
2. **Update Changelog**: Create `RELEASE_NOTES.md`.
|
||||
3. **Bump Version**: Update header in `README.md`.
|
||||
4. **Tag Release**:
|
||||
```bash
|
||||
git tag -a v3.0.0 -m "V3 Enterprise Edition"
|
||||
git push origin v3.0.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 🚨 Emergency Fixes
|
||||
|
||||
If a skill is found to be harmful or broken:
|
||||
|
||||
1. **Move to broken folder** (don't detect): `mv skills/bad-skill skills/.broken/`
|
||||
2. **Or Add Warning**: Add `> [!WARNING]` to the top of `SKILL.md`.
|
||||
3. **Push Immediately**.
|
||||
21
.github/PULL_REQUEST_TEMPLATE.md
vendored
21
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,17 +1,22 @@
|
||||
## Description
|
||||
# Pull Request Description
|
||||
|
||||
Please describe your changes. What skill are you adding or modifying?
|
||||
Please include a summary of the change and which skill is added or fixed.
|
||||
|
||||
## Checklist
|
||||
## Quality Bar Checklist ✅
|
||||
|
||||
- [ ] My skill follows the [creation guidelines](https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/skill-creator)
|
||||
- [ ] I have run `validate_skills.py`
|
||||
- [ ] I have added my name to the credits (if applicable)
|
||||
**All items must be checked before merging.**
|
||||
|
||||
- [ ] **Standards**: I have read `docs/QUALITY_BAR.md` and `docs/SECURITY_GUARDRAILS.md`.
|
||||
- [ ] **Metadata**: The `SKILL.md` frontmatter is valid (checked with `scripts/validate_skills.py`).
|
||||
- [ ] **Risk Label**: I have assigned the correct `risk:` tag (`none`, `safe`, `critical`, `offensive`).
|
||||
- [ ] **Triggers**: The "When to use" section is clear and specific.
|
||||
- [ ] **Security**: If this is an _offensive_ skill, I included the "Authorized Use Only" disclaimer.
|
||||
- [ ] **Local Test**: I have verified the skill works locally.
|
||||
- [ ] **Credits**: I have added the source credit in `README.md` (if applicable).
|
||||
|
||||
## Type of Change
|
||||
|
||||
- [ ] New Skill
|
||||
- [ ] Bug Fix
|
||||
- [ ] New Skill (Feature)
|
||||
- [ ] Documentation Update
|
||||
- [ ] Infrastructure
|
||||
|
||||
|
||||
38
.github/workflows/ci.yml
vendored
Normal file
38
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Skills Registry CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main", "feat/*"]
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
|
||||
jobs:
|
||||
validate-and-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install pyyaml
|
||||
|
||||
- name: 🔍 Validate Skills (Soft Mode)
|
||||
run: |
|
||||
python3 scripts/validate_skills.py
|
||||
|
||||
- name: 🏗️ Generate Index
|
||||
run: |
|
||||
python3 scripts/generate_index.py
|
||||
|
||||
- name: 📝 Update README
|
||||
run: |
|
||||
python3 scripts/update_readme.py
|
||||
|
||||
- name: 🚨 Check for Uncommitted Drift
|
||||
run: |
|
||||
git diff --exit-code || (echo "❌ Detected uncommitted changes in README.md or skills_index.json. Please run scripts locally and commit." && exit 1)
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
|
||||
MAINTENANCE.md
|
||||
|
||||
walkthrough.md
|
||||
.agent/rules/
|
||||
.gemini/
|
||||
|
||||
219
CHANGELOG.md
219
CHANGELOG.md
@@ -7,6 +7,223 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## [3.3.0] - 2026-01-26 - "News & Research"
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skills**:
|
||||
- `last30days`: Research any topic from the last 30 days on Reddit + X + Web.
|
||||
- `daily-news-report`: Generate daily news reports from multiple sources.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Registry**: Updated `skills_index.json` and `README.md` registry (Total: 255 skills).
|
||||
|
||||
## [3.2.0] - 2026-01-26 - "Clarity & Consistency"
|
||||
|
||||
### Changed
|
||||
|
||||
- **Skills Refactoring**: Significant overhaul of `backend-dev-guidelines`, `frontend-design`, `frontend-dev-guidelines`, and `mobile-design`.
|
||||
- **Consolidation**: Merged fragmented documentation into single, authoritative `SKILL.md` files.
|
||||
- **Final Laws**: Introduced "Final Laws" sections to provide strict, non-negotiable decision frameworks.
|
||||
- **Simplification**: Removed external file dependencies to improve context retrieval for AI agents.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Validation**: Fixed critical YAML frontmatter formatting issues in `seo-fundamentals`, `programmatic-seo`, and `schema-markup` that were blocking strict validation.
|
||||
- **Merge Conflicts**: Resolved text artifact conflicts in SEO skills.
|
||||
|
||||
## [3.1.0] - 2026-01-26 - "Stable & Deterministic"
|
||||
|
||||
### Fixed
|
||||
|
||||
- **CI/CD Drift**: Resolved persistent "Uncommitted Changes" errors in CI by making the index generation script deterministic (sorting by name + ID).
|
||||
- **Registry Sync**: Synced `README.md` and `skills_index.json` to accurately reflect all 253 skills.
|
||||
|
||||
### Added (Registry Restore)
|
||||
|
||||
The following skills are now correctly indexed and visible in the registry:
|
||||
|
||||
- **Marketing & Growth**: `programmatic-seo`, `schema-markup`, `seo-fundamentals`, `form-cro`, `popup-cro`, `analytics-tracking`.
|
||||
- **Security**: `windows-privilege-escalation`, `wireshark-analysis`, `wordpress-penetration-testing`, `writing-plans`.
|
||||
- **Development**: `tdd-workflow`, `web-performance-optimization`, `webapp-testing`, `workflow-automation`, `zapier-make-patterns`.
|
||||
- **Maker Tools**: `telegram-bot-builder`, `telegram-mini-app`, `viral-generator-builder`.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Documentation**: Added `docs/CI_DRIFT_FIX.md` as a canonical reference for resolving drift issues.
|
||||
- **Guidance**: Updated `GETTING_STARTED.md` counts to match the full registry (253+ skills).
|
||||
- **Maintenance**: Updated `MAINTENANCE.md` with strict protocols for handling generated files.
|
||||
|
||||
## [3.0.0] - 2026-01-25 - "The Governance Update"
|
||||
|
||||
### Added
|
||||
|
||||
- **Governance & Security**:
|
||||
- `docs/QUALITY_BAR.md`: Defined 5-point validation standard (Metadata, Risk, Triggers).
|
||||
- `docs/SECURITY_GUARDRAILS.md`: Enforced "Authorized Use Only" for offensive skills.
|
||||
- `CODE_OF_CONDUCT.md`: Adhered to Contributor Covenant v2.1.
|
||||
- **Automation**:
|
||||
- `scripts/validate_skills.py`: Automated Quality Bar enforcement (Soft Mode supported).
|
||||
- `.github/workflows/ci.yml`: Automated PR checks.
|
||||
- `scripts/generate_index.py`: Registry generation with Risk & Source columns.
|
||||
- **Experience**:
|
||||
- `docs/BUNDLES.md`: 9 Starter Packs (Essentials, Security, Web, Agent, Game Dev, DevOps, Data, Testing, Creative).
|
||||
- **Interactive Registry**: README now features Risk Levels (🔴/🟢/🟣) and Collections.
|
||||
- **Documentation**:
|
||||
- `docs/EXAMPLES.md`: Cookbook with 3 real-world scenarios.
|
||||
- `docs/SOURCES.md`: Legal ledger for attributions and licenses.
|
||||
- `RELEASE_NOTES.md`: Generated release announcement (archived).
|
||||
|
||||
### Changed
|
||||
|
||||
- **Standardization**: All 250+ skills are now validated against the new Quality Bar schema.
|
||||
- **Project Structure**: Introduced `docs/` folder for scalable documentation.
|
||||
|
||||
## [2.14.0] - 2026-01-25 - "Web Intelligence & Windows"
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skill**:
|
||||
- `context7-auto-research`: Auto-research capability for Claude Code.
|
||||
- `codex-review`: Professional code review with AI integration.
|
||||
- `exa-search`: Semantic search and discovery using Exa API.
|
||||
- `firecrawl-scraper`: Deep web scraping and PDF parsing.
|
||||
- `tavily-web`: Content extraction and research using Tavily.
|
||||
- `busybox-on-windows`: UNIX tool suite for Windows environments.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Documentation**: Updated `obsidian-clipper-template-creator` docs and templates.
|
||||
- **Index & Registry**: Updated `skills_index.json` and `README.md` registry.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Skills**: Fixed YAML frontmatter quoting in `lint-and-validate`.
|
||||
|
||||
## [2.13.0] - 2026-01-24 - "NoSQL Expert"
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skill**:
|
||||
- `nosql-expert`: Expert guidance for distributed NoSQL databases (Cassandra, DynamoDB), focusing on query-first modeling and anti-patterns.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Index & Registry**: Updated `skills_index.json` and `README.md` registry.
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@sickn33](https://github.com/sickn33) - PR #23
|
||||
|
||||
## [2.12.0] - 2026-01-23 - "Enterprise & UI Power"
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skills**:
|
||||
- `production-code-audit`: Comprehensive enterprise auditing skill for production readiness.
|
||||
- `avalonia-layout-zafiro`: Zafiro layout guidelines for Avalonia UI.
|
||||
- `avalonia-viewmodels-zafiro`: ViewModel composition patterns for Avalonia.
|
||||
- `avalonia-zafiro-development`: Core development rules for Avalonia Zafiro applications.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Index & Registry**: Updated `skills_index.json` and `README.md` registry (Total: 243 skills).
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@SuperJMN](https://github.com/SuperJMN) - PR #20
|
||||
- [@Mohammad-Faiz-Cloud-Engineer](https://github.com/Mohammad-Faiz-Cloud-Engineer) - PR #21
|
||||
|
||||
## [2.11.0] - 2026-01-23 - "Postgres Performance"
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skill**:
|
||||
- `postgres-best-practices`: Comprehensive Supabase PostgreSQL performance optimization guide with 30+ rules covering query performance, connection management, RLS security, schema design, locking, and monitoring.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Official Sources**: Added [supabase/agent-skills](https://github.com/supabase/agent-skills) to Credits & Sources.
|
||||
- **Index & Registry**: Updated `skills_index.json` and `README.md` registry (Total: 239 skills).
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@ar27111994](https://github.com/ar27111994) - PR #19
|
||||
|
||||
---
|
||||
|
||||
## [2.10.0] - 2026-01-22 - "Developer Excellence"
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skills**:
|
||||
- `api-security-best-practices`: Comprehensive guide for secure API design and defense.
|
||||
- `environment-setup-guide`: Systematic approach to project onboarding and tool configuration.
|
||||
- `web-performance-optimization`: Methodologies for optimizing Core Web Vitals and loading speed.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Enhanced Skill**:
|
||||
- `code-review-checklist`: Replaced with a much more detailed and systematic version covering functionality, security, and quality.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Index & Registry**: Updated `skills_index.json` and `README.md` registry (Total: 238 skills).
|
||||
|
||||
### Added
|
||||
|
||||
- **Automation Support**:
|
||||
- `scripts/update_readme.py`: Automated script to sync skill counts and regenerate the registry table.
|
||||
- Updated `MAINTENANCE.md` to reflect the new automated workflow.
|
||||
- **Repository Quality**:
|
||||
- `MAINTENANCE.md` is now tracked in the repository (removed from `.gitignore`).
|
||||
- Improved contribution guidelines.
|
||||
|
||||
## [2.8.0] - 2026-01-22 - "Documentation Power"
|
||||
|
||||
### Added
|
||||
|
||||
- **API Documentation Generator**: New skill to automatically generate comprehensive API documentation (`skills/api-documentation-generator`).
|
||||
- **Remotion Best Practices**: 28 modular rules for programmatic video creation (`skills/remotion-best-practices`).
|
||||
|
||||
## [2.7.0] - 2026-01-22 - "Agent Memory"
|
||||
|
||||
### Added
|
||||
|
||||
- **Agent Memory MCP**: New skill providing persistent, searchable knowledge management for AI agents (`skills/agent-memory-mcp`).
|
||||
|
||||
### Changed
|
||||
|
||||
- **Renamed Skill**: `agent-memory` was renamed to `agent-memory-mcp` to avoid naming conflicts.
|
||||
|
||||
---
|
||||
|
||||
## [2.6.0] - 2026-01-21 - "Everything Skills Edition"
|
||||
|
||||
### Added
|
||||
|
||||
- **8 Verified Skills** from [affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code):
|
||||
- `cc-skill-backend-patterns`
|
||||
- `cc-skill-clickhouse-io`
|
||||
- `cc-skill-coding-standards`
|
||||
- `cc-skill-continuous-learning`
|
||||
- `cc-skill-frontend-patterns`
|
||||
- `cc-skill-project-guidelines-example`
|
||||
- `cc-skill-security-review`
|
||||
- `cc-skill-strategic-compact`
|
||||
- **Documentation**: New `WALKTHROUGH.md` for import process details.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Skill Cleanup**: Removed 27 unwanted agents, commands, and rules from the `everything-claude-code` import to focus strictly on skills.
|
||||
- **Index**: Regenerated `skills_index.json` (Total: 233 skills).
|
||||
- **Credits**: Updated README credits and registry.
|
||||
|
||||
## [1.0.0] - 2026-01-19 - "Marketing Edition"
|
||||
|
||||
### Added
|
||||
@@ -113,7 +330,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Total skills count: ~65
|
||||
- Total skills count: **~65**
|
||||
|
||||
---
|
||||
|
||||
|
||||
259
CONTRIBUTING.md
259
CONTRIBUTING.md
@@ -1,6 +1,19 @@
|
||||
# 🤝 Contributing Guide - Make It Easy for Everyone!
|
||||
# 🤝 Contributing Guide - V3 Enterprise Edition
|
||||
|
||||
**Thank you for wanting to make this repo better!** This guide shows you exactly how to contribute, even if you're new to open source.
|
||||
With V3, we raised the bar for quality. Please read the **new Quality Standards** below carefully.
|
||||
|
||||
---
|
||||
|
||||
## 🧐 The "Quality Bar" (V3 Standard)
|
||||
|
||||
**Critical for new skills:** Every skill submitted must pass our **5-Point Quality Check** (see `docs/QUALITY_BAR.md` for details):
|
||||
|
||||
1. **Metadata**: Correct Frontmatter (`name`, `description`).
|
||||
2. **Safety**: No harmful commands without "Risk" labels.
|
||||
3. **Clarity**: Clear "When to use" section.
|
||||
4. **Examples**: At least one copy-paste usage example.
|
||||
5. **Actions**: Must define concrete steps, not just "thoughts".
|
||||
|
||||
---
|
||||
|
||||
@@ -9,104 +22,60 @@
|
||||
You don't need to be an expert! Here are ways anyone can help:
|
||||
|
||||
### 1. Improve Documentation (Easiest!)
|
||||
|
||||
- Fix typos or grammar
|
||||
- Make explanations clearer
|
||||
- Add examples to existing skills
|
||||
- Translate documentation to other languages
|
||||
|
||||
### 2. Report Issues
|
||||
|
||||
- Found something confusing? Tell us!
|
||||
- Skill not working? Let us know!
|
||||
- Have suggestions? We want to hear them!
|
||||
|
||||
### 3. Create New Skills
|
||||
|
||||
- Share your expertise as a skill
|
||||
- Fill gaps in the current collection
|
||||
- Improve existing skills
|
||||
|
||||
### 4. Test and Validate
|
||||
|
||||
- Try skills and report what works/doesn't work
|
||||
- Test on different AI tools
|
||||
- Suggest improvements
|
||||
|
||||
---
|
||||
|
||||
## How to Improve Documentation
|
||||
|
||||
### Super Easy Method (No Git Knowledge Needed!)
|
||||
|
||||
1. **Find the file** you want to improve on GitHub
|
||||
2. **Click the pencil icon** (✏️) to edit
|
||||
3. **Make your changes** in the browser
|
||||
4. **Click "Propose changes"** at the bottom
|
||||
5. **Done!** We'll review and merge it
|
||||
|
||||
### Using Git (If You Know How)
|
||||
|
||||
```bash
|
||||
# 1. Fork the repo on GitHub (click the Fork button)
|
||||
|
||||
# 2. Clone your fork
|
||||
git clone https://github.com/YOUR-USERNAME/antigravity-awesome-skills.git
|
||||
cd antigravity-awesome-skills
|
||||
|
||||
# 3. Create a branch
|
||||
git checkout -b improve-docs
|
||||
|
||||
# 4. Make your changes
|
||||
# Edit files in your favorite editor
|
||||
|
||||
# 5. Commit and push
|
||||
git add .
|
||||
git commit -m "docs: make XYZ clearer"
|
||||
git push origin improve-docs
|
||||
|
||||
# 6. Open a Pull Request on GitHub
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How to Create a New Skill
|
||||
|
||||
### What Makes a Good Skill?
|
||||
|
||||
A skill should:
|
||||
- ✅ Solve a specific problem
|
||||
- ✅ Be reusable across projects
|
||||
- ✅ Have clear instructions
|
||||
- ✅ Include examples when possible
|
||||
|
||||
### Step-by-Step: Create Your First Skill
|
||||
### Step-by-Step Guide
|
||||
|
||||
#### Step 1: Choose Your Skill Topic
|
||||
|
||||
Ask yourself:
|
||||
- What am I good at?
|
||||
- What do I wish my AI assistant knew better?
|
||||
- What task do I do repeatedly?
|
||||
|
||||
**Examples:**
|
||||
- "I'm good at Docker, let me create a Docker skill"
|
||||
- "I wish AI understood Tailwind better"
|
||||
- "I keep setting up the same testing patterns"
|
||||
Ask yourself: "What do I wish my AI assistant knew better?".
|
||||
Example: "I'm good at Docker, let me create a Docker skill".
|
||||
|
||||
#### Step 2: Create the Folder Structure
|
||||
|
||||
Skills live in the `skills/` directory. Use `kebab-case` for folder names.
|
||||
|
||||
```bash
|
||||
# Navigate to the skills directory
|
||||
# Navigate to skills
|
||||
cd skills/
|
||||
|
||||
# Create your skill folder (use lowercase with hyphens)
|
||||
# Create your skill folder
|
||||
mkdir my-awesome-skill
|
||||
cd my-awesome-skill
|
||||
|
||||
# Create the SKILL.md file
|
||||
cd my-awesome-skill
|
||||
touch SKILL.md
|
||||
```
|
||||
|
||||
#### Step 3: Write Your SKILL.md
|
||||
|
||||
Every skill needs this basic structure:
|
||||
Every skill needs this basic structure. **Copy this template:**
|
||||
|
||||
```markdown
|
||||
---
|
||||
@@ -124,90 +93,50 @@ Explain what this skill does and when to use it.
|
||||
|
||||
- Use when [scenario 1]
|
||||
- Use when [scenario 2]
|
||||
- Use when [scenario 3]
|
||||
|
||||
## How It Works
|
||||
|
||||
### Step 1: [First Step]
|
||||
Explain what to do first...
|
||||
|
||||
### Step 2: [Second Step]
|
||||
Explain the next step...
|
||||
|
||||
### Step 3: [Final Step]
|
||||
Explain how to finish...
|
||||
Detailed step-by-step instructions for the AI...
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: [Common Use Case]
|
||||
\`\`\`
|
||||
Show example code or commands here
|
||||
\`\`\`
|
||||
### Example 1
|
||||
|
||||
### Example 2: [Another Use Case]
|
||||
\`\`\`
|
||||
More examples...
|
||||
code example here
|
||||
\`\`\`
|
||||
|
||||
## Best Practices
|
||||
|
||||
- ✅ Do this
|
||||
- ✅ Also do this
|
||||
- ❌ Don't do this
|
||||
- ❌ Avoid this
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
- **Problem:** Description of common issue
|
||||
**Solution:** How to fix it
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Link to documentation](https://example.com)
|
||||
- [Tutorial](https://example.com)
|
||||
```
|
||||
|
||||
#### Step 4: Test Your Skill
|
||||
#### Step 4: Validate (CRITICAL V3 STEP)
|
||||
|
||||
1. **Copy it to your AI tool's skills directory:**
|
||||
```bash
|
||||
cp -r skills/my-awesome-skill ~/.agent/skills/
|
||||
```
|
||||
|
||||
2. **Try using it:**
|
||||
```
|
||||
@my-awesome-skill help me with [task]
|
||||
```
|
||||
|
||||
3. **Does it work?** Great! If not, refine it.
|
||||
|
||||
#### Step 5: Validate Your Skill
|
||||
|
||||
Run the validation script:
|
||||
Run the validation script locally. **We will not merge PRs that fail this check.**
|
||||
|
||||
```bash
|
||||
# Soft mode (warnings only)
|
||||
python3 scripts/validate_skills.py
|
||||
|
||||
# Hard mode (what CI runs)
|
||||
python3 scripts/validate_skills.py --strict
|
||||
```
|
||||
|
||||
This checks:
|
||||
- ✅ SKILL.md exists
|
||||
|
||||
- ✅ `SKILL.md` exists
|
||||
- ✅ Frontmatter is correct
|
||||
- ✅ Name matches folder name
|
||||
- ✅ Description exists
|
||||
- ✅ Quality Bar checks passed
|
||||
|
||||
#### Step 6: Submit Your Skill
|
||||
#### Step 5: Submit Your Skill
|
||||
|
||||
```bash
|
||||
# 1. Add your skill
|
||||
git add skills/my-awesome-skill/
|
||||
|
||||
# 2. Commit with a clear message
|
||||
git commit -m "feat: add my-awesome-skill for [purpose]"
|
||||
|
||||
# 3. Push to your fork
|
||||
git commit -m "feat: add my-awesome-skill"
|
||||
git push origin my-branch
|
||||
|
||||
# 4. Open a Pull Request on GitHub
|
||||
```
|
||||
|
||||
---
|
||||
@@ -232,110 +161,34 @@ description: "One sentence describing what this skill does and when to use it"
|
||||
|
||||
- Use when you need to [scenario 1]
|
||||
- Use when you want to [scenario 2]
|
||||
- Use when working with [scenario 3]
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### Concept 1
|
||||
[Explain key concept]
|
||||
|
||||
### Concept 2
|
||||
[Explain another key concept]
|
||||
|
||||
## Step-by-Step Guide
|
||||
|
||||
### 1. [First Step Name]
|
||||
[Detailed instructions]
|
||||
|
||||
### 2. [Second Step Name]
|
||||
[Detailed instructions]
|
||||
|
||||
### 3. [Third Step Name]
|
||||
[Detailed instructions]
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: [Use Case Name]
|
||||
|
||||
\`\`\`language
|
||||
// Example code here
|
||||
\`\`\`
|
||||
|
||||
**Explanation:** [What this example demonstrates]
|
||||
|
||||
### Example 2: [Another Use Case]
|
||||
\`\`\`language
|
||||
// More example code
|
||||
\`\`\`
|
||||
|
||||
**Explanation:** [What this example demonstrates]
|
||||
|
||||
## Best Practices
|
||||
|
||||
- ✅ **Do:** [Good practice]
|
||||
- ✅ **Do:** [Another good practice]
|
||||
- ❌ **Don't:** [What to avoid]
|
||||
- ❌ **Don't:** [Another thing to avoid]
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: [Common Issue]
|
||||
**Symptoms:** [How you know this is the problem]
|
||||
**Problem:** [Common Issue]
|
||||
**Solution:** [How to fix it]
|
||||
|
||||
### Problem: [Another Issue]
|
||||
**Symptoms:** [How you know this is the problem]
|
||||
**Solution:** [How to fix it]
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `@related-skill-1` - [When to use this instead]
|
||||
- `@related-skill-2` - [How this complements your skill]
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Official Documentation](https://example.com)
|
||||
- [Tutorial](https://example.com)
|
||||
- [Community Guide](https://example.com)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How to Report Issues
|
||||
|
||||
### Found a Bug?
|
||||
|
||||
1. **Check existing issues** - Maybe it's already reported
|
||||
2. **Open a new issue** with this info:
|
||||
- What skill has the problem?
|
||||
- What AI tool are you using?
|
||||
- What did you expect to happen?
|
||||
- What actually happened?
|
||||
- Steps to reproduce
|
||||
|
||||
### Found Something Confusing?
|
||||
|
||||
1. **Open an issue** titled: "Documentation unclear: [topic]"
|
||||
2. **Explain:**
|
||||
- What part is confusing?
|
||||
- What did you expect to find?
|
||||
- How could it be clearer?
|
||||
|
||||
---
|
||||
|
||||
## Contribution Checklist
|
||||
|
||||
Before submitting your contribution:
|
||||
|
||||
- [ ] My skill has a clear, descriptive name
|
||||
- [ ] The `SKILL.md` has proper frontmatter (name + description)
|
||||
- [ ] I've included examples
|
||||
- [ ] I've tested the skill with an AI assistant
|
||||
- [ ] I've run `python3 scripts/validate_skills.py`
|
||||
- [ ] My commit message is clear (e.g., "feat: add docker-compose skill")
|
||||
- [ ] I've checked for typos and grammar
|
||||
|
||||
---
|
||||
|
||||
## Commit Message Guidelines
|
||||
|
||||
Use these prefixes:
|
||||
@@ -348,11 +201,11 @@ Use these prefixes:
|
||||
- `chore:` - Maintenance tasks
|
||||
|
||||
**Examples:**
|
||||
|
||||
```
|
||||
feat: add kubernetes-deployment skill
|
||||
docs: improve getting started guide
|
||||
fix: correct typo in stripe-integration skill
|
||||
docs: add examples to react-best-practices
|
||||
```
|
||||
|
||||
---
|
||||
@@ -360,30 +213,13 @@ docs: add examples to react-best-practices
|
||||
## Learning Resources
|
||||
|
||||
### New to Git/GitHub?
|
||||
|
||||
- [GitHub's Hello World Guide](https://guides.github.com/activities/hello-world/)
|
||||
- [Git Basics](https://git-scm.com/book/en/v2/Getting-Started-Git-Basics)
|
||||
|
||||
### New to Markdown?
|
||||
|
||||
- [Markdown Guide](https://www.markdownguide.org/basic-syntax/)
|
||||
- [GitHub Markdown](https://guides.github.com/features/mastering-markdown/)
|
||||
|
||||
### New to Open Source?
|
||||
- [First Contributions](https://github.com/firstcontributions/first-contributions)
|
||||
- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
- **Questions?** Open a [Discussion](https://github.com/sickn33/antigravity-awesome-skills/discussions)
|
||||
- **Stuck?** Open an [Issue](https://github.com/sickn33/antigravity-awesome-skills/issues)
|
||||
- **Want feedback?** Open a [Draft Pull Request](https://github.com/sickn33/antigravity-awesome-skills/pulls)
|
||||
|
||||
---
|
||||
|
||||
## Recognition
|
||||
|
||||
All contributors are recognized in our [Contributors](https://github.com/sickn33/antigravity-awesome-skills/graphs/contributors) page!
|
||||
|
||||
---
|
||||
|
||||
@@ -392,10 +228,9 @@ All contributors are recognized in our [Contributors](https://github.com/sickn33
|
||||
- Be respectful and inclusive
|
||||
- Welcome newcomers
|
||||
- Focus on constructive feedback
|
||||
- Help others learn
|
||||
- **No harmful content**: See `docs/SECURITY_GUARDRAILS.md`.
|
||||
|
||||
---
|
||||
|
||||
**Thank you for making this project better for everyone!**
|
||||
|
||||
Every contribution, no matter how small, makes a difference. Whether you fix a typo, improve a sentence, or create a whole new skill - you're helping thousands of developers!
|
||||
|
||||
484
FAQ.md
484
FAQ.md
@@ -9,52 +9,56 @@
|
||||
### What are "skills" exactly?
|
||||
|
||||
Skills are specialized instruction files that teach AI assistants how to handle specific tasks. Think of them as expert knowledge modules that your AI can load on-demand.
|
||||
**Simple analogy:** Just like you might consult different experts (a lawyer, a doctor, a mechanic), these skills let your AI become an expert in different areas when you need them.
|
||||
|
||||
**Simple analogy:** Just like you might consult different experts (a lawyer, a doctor, a mechanic), skills let your AI become an expert in different areas when you need them.
|
||||
### Do I need to install all 250+ skills?
|
||||
|
||||
---
|
||||
|
||||
### Do I need to install all 179 skills?
|
||||
|
||||
**No!** When you clone the repository, all skills are available, but your AI only loads them when you explicitly invoke them with `@skill-name` or `/skill-name`.
|
||||
|
||||
It's like having a library - all the books are there, but you only read the ones you need.
|
||||
|
||||
---
|
||||
**No!** When you clone the repository, all skills are available, but your AI only loads them when you explicitly invoke them with `@skill-name`.
|
||||
It's like having a library - all books are there, but you only read the ones you need.
|
||||
**Pro Tip:** Use [Starter Packs](docs/BUNDLES.md) to install only what matches your role.
|
||||
|
||||
### Which AI tools work with these skills?
|
||||
|
||||
These skills work with any AI coding assistant that supports the `SKILL.md` format:
|
||||
|
||||
- ✅ **Claude Code** (Anthropic CLI)
|
||||
- ✅ **Gemini CLI** (Google)
|
||||
- ✅ **Codex CLI** (OpenAI)
|
||||
- ✅ **Cursor** (AI IDE)
|
||||
- ✅ **Antigravity IDE**
|
||||
- ✅ **OpenCode**
|
||||
- ⚠️ **GitHub Copilot** (partial support)
|
||||
|
||||
---
|
||||
- ⚠️ **GitHub Copilot** (partial support via copy-paste)
|
||||
|
||||
### Are these skills free to use?
|
||||
|
||||
**Yes!** This repository is licensed under MIT License, which means:
|
||||
**Yes!** This repository is licensed under MIT License.
|
||||
|
||||
- ✅ Free for personal use
|
||||
- ✅ Free for commercial use
|
||||
- ✅ You can modify them
|
||||
- ✅ You can redistribute them
|
||||
|
||||
---
|
||||
|
||||
### Do skills work offline?
|
||||
|
||||
The skill files themselves are stored locally on your computer, but your AI assistant needs an internet connection to function. So:
|
||||
- ✅ Skills are local files
|
||||
- ❌ AI assistant needs internet
|
||||
The skill files themselves are stored locally on your computer, but your AI assistant needs an internet connection to function.
|
||||
|
||||
---
|
||||
|
||||
## Installation & Setup
|
||||
## 🔒 Security & Trust (V3 Update)
|
||||
|
||||
### What do the Risk Labels mean?
|
||||
|
||||
We classify skills so you know what you're running:
|
||||
|
||||
- ⚪ **Safe (White/Blue)**: Read-only, planning, or benign skills.
|
||||
- 🔴 **Risk (Red)**: Skills that modify files (delete), use network scanners, or perform destructive actions. **Use with caution.**
|
||||
- 🟣 **Official (Purple)**: Maintained by trusted vendors (Anthropic, DeepMind, etc.).
|
||||
|
||||
### Can these skills hack my computer?
|
||||
|
||||
**No.** Skills are text files. However, they _instruct_ the AI to run commands. If a skill says "delete all files", a compliant AI might try to do it.
|
||||
_Always check the Risk label and review the code._
|
||||
|
||||
---
|
||||
|
||||
## 📦 Installation & Setup
|
||||
|
||||
### Where should I install the skills?
|
||||
|
||||
@@ -65,34 +69,23 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skill
|
||||
```
|
||||
|
||||
**Tool-specific paths:**
|
||||
- Claude Code: `.claude/skills/` or `.agent/skills/`
|
||||
- Gemini CLI: `.gemini/skills/` or `.agent/skills/`
|
||||
|
||||
- Claude Code: `.claude/skills/`
|
||||
- Gemini CLI: `.gemini/skills/`
|
||||
- Cursor: `.cursor/skills/` or project root
|
||||
- Antigravity: `.agent/skills/`
|
||||
|
||||
---
|
||||
### Does this work with Windows?
|
||||
|
||||
### Can I install skills in multiple projects?
|
||||
**Yes**, but some "Official" skills use **symlinks** which Windows handles poorly by default.
|
||||
Run git with:
|
||||
|
||||
**Yes!** You have two options:
|
||||
|
||||
**Option 1: Global Installation** (recommended)
|
||||
Install once in your home directory, works for all projects:
|
||||
```bash
|
||||
cd ~
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
git clone -c core.symlinks=true https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
```
|
||||
|
||||
**Option 2: Per-Project Installation**
|
||||
Install in each project directory:
|
||||
```bash
|
||||
cd /path/to/your/project
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
```
|
||||
Or enable "Developer Mode" in Windows Settings.
|
||||
|
||||
---
|
||||
|
||||
### How do I update skills to the latest version?
|
||||
### How do I update skills?
|
||||
|
||||
Navigate to your skills directory and pull the latest changes:
|
||||
|
||||
@@ -103,413 +96,75 @@ git pull origin main
|
||||
|
||||
---
|
||||
|
||||
### Can I install only specific skills?
|
||||
|
||||
**Yes!** You can manually copy individual skill folders:
|
||||
|
||||
```bash
|
||||
# Clone the full repo first
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git temp-skills
|
||||
|
||||
# Copy only the skills you want
|
||||
mkdir -p .agent/skills
|
||||
cp -r temp-skills/skills/brainstorming .agent/skills/
|
||||
cp -r temp-skills/skills/stripe-integration .agent/skills/
|
||||
|
||||
# Clean up
|
||||
rm -rf temp-skills
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Using Skills
|
||||
## 🛠️ Using Skills
|
||||
|
||||
### How do I invoke a skill?
|
||||
|
||||
Use the `@` symbol followed by the skill name:
|
||||
|
||||
```
|
||||
@skill-name your request here
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
```
|
||||
@brainstorming help me design a todo app
|
||||
@stripe-integration add subscription billing
|
||||
@systematic-debugging fix this test failure
|
||||
```
|
||||
|
||||
Some tools also support `/skill-name` syntax.
|
||||
|
||||
---
|
||||
|
||||
### How do I know which skill to use?
|
||||
|
||||
**Method 1: Browse the README**
|
||||
Check the [Full Skill Registry](README.md#full-skill-registry-179179) organized by category
|
||||
|
||||
**Method 2: Search by keyword**
|
||||
```bash
|
||||
ls skills/ | grep "keyword"
|
||||
```
|
||||
|
||||
**Method 3: Ask your AI**
|
||||
```
|
||||
What skills are available for [topic]?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Can I use multiple skills at once?
|
||||
|
||||
**Yes!** You can invoke multiple skills in the same conversation:
|
||||
**Yes!** You can invoke multiple skills:
|
||||
|
||||
```
|
||||
@brainstorming help me design this feature
|
||||
|
||||
[After brainstorming...]
|
||||
|
||||
@test-driven-development now let's implement it with tests
|
||||
@brainstorming help me design this, then use @writing-plans to create a task list.
|
||||
```
|
||||
|
||||
---
|
||||
### How do I know which skill to use?
|
||||
|
||||
### What if a skill doesn't work?
|
||||
|
||||
**Troubleshooting steps:**
|
||||
|
||||
1. **Check installation path**
|
||||
```bash
|
||||
ls .agent/skills/
|
||||
```
|
||||
|
||||
2. **Verify skill exists**
|
||||
```bash
|
||||
ls .agent/skills/skill-name/
|
||||
```
|
||||
|
||||
3. **Check SKILL.md exists**
|
||||
```bash
|
||||
cat .agent/skills/skill-name/SKILL.md
|
||||
```
|
||||
|
||||
4. **Try restarting your AI assistant**
|
||||
|
||||
5. **Check for typos in skill name**
|
||||
- Use `@brainstorming` not `@brain-storming`
|
||||
- Names are case-sensitive in some tools
|
||||
|
||||
6. **Report the issue**
|
||||
[Open an issue](https://github.com/sickn33/antigravity-awesome-skills/issues) with details
|
||||
1. **Browse the README**: Check the [Full Skill Registry](README.md#full-skill-registry-253253).
|
||||
2. **Search**: `ls skills/ | grep "keyword"`
|
||||
3. **Ask your AI**: "What skills do you have for testing?"
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
### I'm new to open source. Can I still contribute?
|
||||
|
||||
**Absolutely!** Everyone starts somewhere. We welcome contributions from beginners:
|
||||
|
||||
- Fix typos or grammar
|
||||
- Improve documentation clarity
|
||||
- Add examples to existing skills
|
||||
- Report issues or confusing parts
|
||||
|
||||
Check out [CONTRIBUTING.md](CONTRIBUTING.md) for step-by-step instructions.
|
||||
|
||||
---
|
||||
|
||||
### Do I need to know how to code to contribute?
|
||||
|
||||
**No!** Many valuable contributions don't require coding:
|
||||
|
||||
- **Documentation improvements** - Make things clearer
|
||||
- **Examples** - Add real-world usage examples
|
||||
- **Issue reporting** - Tell us what's confusing
|
||||
- **Testing** - Try skills and report what works
|
||||
|
||||
---
|
||||
|
||||
### How do I create a new skill?
|
||||
|
||||
**Quick version:**
|
||||
|
||||
1. Create a folder: `skills/my-skill-name/`
|
||||
2. Create `SKILL.md` with frontmatter and content
|
||||
3. Test it with your AI assistant
|
||||
4. Run validation: `python3 scripts/validate_skills.py`
|
||||
5. Submit a Pull Request
|
||||
|
||||
**Detailed version:** See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
---
|
||||
|
||||
### What makes a good skill?
|
||||
|
||||
A good skill:
|
||||
- ✅ Solves a specific problem
|
||||
- ✅ Has clear, actionable instructions
|
||||
- ✅ Includes examples
|
||||
- ✅ Is reusable across projects
|
||||
- ✅ Follows the standard structure
|
||||
|
||||
See [SKILL_ANATOMY.md](docs/SKILL_ANATOMY.md) for details.
|
||||
|
||||
---
|
||||
|
||||
### How long does it take for my contribution to be reviewed?
|
||||
|
||||
Review times vary, but typically:
|
||||
- **Simple fixes** (typos, docs): 1-3 days
|
||||
- **New skills**: 3-7 days
|
||||
- **Major changes**: 1-2 weeks
|
||||
|
||||
You can speed this up by:
|
||||
- Following the contribution guidelines
|
||||
- Writing clear commit messages
|
||||
- Testing your changes
|
||||
- Responding to feedback quickly
|
||||
|
||||
---
|
||||
|
||||
## Technical Questions
|
||||
|
||||
### What's the difference between SKILL.md and README.md?
|
||||
|
||||
- **SKILL.md** (required): The actual skill definition that the AI reads
|
||||
- **README.md** (optional): Human-readable documentation about the skill
|
||||
|
||||
The AI primarily uses `SKILL.md`, while developers read `README.md`.
|
||||
|
||||
---
|
||||
|
||||
### Can I use scripts or code in my skill?
|
||||
|
||||
**Yes!** Skills can include:
|
||||
- `scripts/` - Helper scripts
|
||||
- `examples/` - Example code
|
||||
- `templates/` - Code templates
|
||||
- `references/` - Documentation
|
||||
|
||||
Reference them in your `SKILL.md`:
|
||||
```markdown
|
||||
Run the setup script:
|
||||
\`\`\`bash
|
||||
bash scripts/setup.sh
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### What programming languages can skills cover?
|
||||
|
||||
**Any language!** Current skills cover:
|
||||
- JavaScript/TypeScript
|
||||
- Python
|
||||
- Go
|
||||
- Rust
|
||||
- Swift
|
||||
- Kotlin
|
||||
- Shell scripting
|
||||
- And many more...
|
||||
|
||||
---
|
||||
|
||||
### Can skills call other skills?
|
||||
|
||||
**Yes!** Skills can reference other skills:
|
||||
|
||||
```markdown
|
||||
## Workflow
|
||||
|
||||
1. First, use `@brainstorming` to design
|
||||
2. Then, use `@writing-plans` to plan
|
||||
3. Finally, use `@test-driven-development` to implement
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### How do I validate my skill before submitting?
|
||||
|
||||
Run the validation script:
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_skills.py
|
||||
```
|
||||
|
||||
This checks:
|
||||
- ✅ SKILL.md exists
|
||||
- ✅ Frontmatter is valid
|
||||
- ✅ Name matches folder name
|
||||
- ✅ Description exists
|
||||
|
||||
---
|
||||
|
||||
## Learning & Best Practices
|
||||
|
||||
### Which skills should I try first?
|
||||
|
||||
**For beginners:**
|
||||
- `@brainstorming` - Design before coding
|
||||
- `@systematic-debugging` - Fix bugs methodically
|
||||
- `@git-pushing` - Commit with good messages
|
||||
|
||||
**For developers:**
|
||||
- `@test-driven-development` - Write tests first
|
||||
- `@react-best-practices` - Modern React patterns
|
||||
- `@senior-fullstack` - Full-stack development
|
||||
|
||||
**For security:**
|
||||
- `@ethical-hacking-methodology` - Security basics
|
||||
- `@burp-suite-testing` - Web app testing
|
||||
|
||||
---
|
||||
|
||||
### How do I learn to write good skills?
|
||||
|
||||
**Learning path:**
|
||||
|
||||
1. **Read existing skills** - Study 5-10 well-written skills
|
||||
2. **Use skills** - Try them with your AI assistant
|
||||
3. **Read guides** - Check [SKILL_ANATOMY.md](docs/SKILL_ANATOMY.md)
|
||||
4. **Start simple** - Create a basic skill first
|
||||
5. **Get feedback** - Submit and learn from reviews
|
||||
6. **Iterate** - Improve based on feedback
|
||||
|
||||
**Recommended skills to study:**
|
||||
- `skills/brainstorming/SKILL.md` - Clear structure
|
||||
- `skills/systematic-debugging/SKILL.md` - Comprehensive
|
||||
- `skills/git-pushing/SKILL.md` - Simple and focused
|
||||
|
||||
---
|
||||
|
||||
### Are there any skills for learning AI/ML?
|
||||
|
||||
**Yes!** Check out:
|
||||
- `@rag-engineer` - RAG systems
|
||||
- `@prompt-engineering` - Prompt design
|
||||
- `@langgraph` - Multi-agent systems
|
||||
- `@ai-agents-architect` - Agent architecture
|
||||
- `@llm-app-patterns` - LLM application patterns
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
## 🏗️ Troubleshooting
|
||||
|
||||
### My AI assistant doesn't recognize skills
|
||||
|
||||
**Possible causes:**
|
||||
|
||||
1. **Wrong installation path**
|
||||
- Check your tool's documentation for the correct path
|
||||
- Try `.agent/skills/` as the universal path
|
||||
|
||||
2. **Skill name typo**
|
||||
- Verify the exact skill name: `ls .agent/skills/`
|
||||
- Use the exact name from the folder
|
||||
|
||||
3. **Tool doesn't support skills**
|
||||
- Verify your tool supports the SKILL.md format
|
||||
- Check the [Compatibility](#-compatibility) section
|
||||
|
||||
4. **Need to restart**
|
||||
- Restart your AI assistant after installing skills
|
||||
|
||||
---
|
||||
1. **Wrong installation path**: Check your tool's docs. Try `.agent/skills/`.
|
||||
2. **Restart Needed**: Restart your AI/IDE after installing.
|
||||
3. **Typos**: Did you type `@brain-storming` instead of `@brainstorming`?
|
||||
|
||||
### A skill gives incorrect or outdated advice
|
||||
|
||||
**Please report it!**
|
||||
Please [Open an issue](https://github.com/sickn33/antigravity-awesome-skills/issues)!
|
||||
Include:
|
||||
|
||||
1. [Open an issue](https://github.com/sickn33/antigravity-awesome-skills/issues)
|
||||
2. Include:
|
||||
- Which skill
|
||||
- What's incorrect
|
||||
- What should it say instead
|
||||
- Links to correct documentation
|
||||
|
||||
We'll update it quickly!
|
||||
- Which skill
|
||||
- What went wrong
|
||||
- What should happen instead
|
||||
|
||||
---
|
||||
|
||||
### Can I modify skills for my own use?
|
||||
## 🤝 Contribution
|
||||
|
||||
**Yes!** The MIT License allows you to:
|
||||
- ✅ Modify skills for your needs
|
||||
- ✅ Create private versions
|
||||
- ✅ Customize for your team
|
||||
### I'm new to open source. Can I contribute?
|
||||
|
||||
**To modify:**
|
||||
1. Copy the skill to a new location
|
||||
2. Edit the SKILL.md file
|
||||
3. Use your modified version
|
||||
**Absolutely!** We welcome beginners.
|
||||
|
||||
**Consider contributing improvements back!**
|
||||
- Fix typos
|
||||
- Add examples
|
||||
- Improve docs
|
||||
Check out [CONTRIBUTING.md](CONTRIBUTING.md) for instructions.
|
||||
|
||||
---
|
||||
### My PR failed "Quality Bar" check. Why?
|
||||
|
||||
## Statistics & Info
|
||||
V3 introduces automated quality control. Your skill might be missing:
|
||||
|
||||
### How many skills are there?
|
||||
1. A valid `description`.
|
||||
2. Usage examples.
|
||||
Run `python3 scripts/validate_skills.py` locally to check before you push.
|
||||
|
||||
**179 skills** across 10+ categories as of the latest update.
|
||||
### Can I update an "Official" skill?
|
||||
|
||||
---
|
||||
|
||||
### How often are skills updated?
|
||||
|
||||
- **Bug fixes**: As soon as reported
|
||||
- **New skills**: Added regularly by contributors
|
||||
- **Updates**: When best practices change
|
||||
|
||||
**Stay updated:**
|
||||
```bash
|
||||
cd .agent/skills
|
||||
git pull origin main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Who maintains this repository?
|
||||
|
||||
This is a community-driven project with contributions from:
|
||||
- Original creators
|
||||
- Open source contributors
|
||||
- AI coding assistant users worldwide
|
||||
|
||||
See [Credits & Sources](README.md#credits--sources) for attribution.
|
||||
|
||||
---
|
||||
|
||||
## Still Have Questions?
|
||||
|
||||
### Where can I get help?
|
||||
|
||||
- **[GitHub Discussions](https://github.com/sickn33/antigravity-awesome-skills/discussions)** - Ask questions
|
||||
- **[GitHub Issues](https://github.com/sickn33/antigravity-awesome-skills/issues)** - Report bugs
|
||||
- **Documentation** - Read the guides in this repo
|
||||
- **Community** - Connect with other users
|
||||
|
||||
---
|
||||
|
||||
### How can I stay updated?
|
||||
|
||||
- **Star the repository** on GitHub
|
||||
- **Watch the repository** for updates
|
||||
- **Subscribe to releases** for notifications
|
||||
- **Follow contributors** on social media
|
||||
|
||||
---
|
||||
|
||||
### Can I use these skills commercially?
|
||||
|
||||
**Yes!** The MIT License permits commercial use. You can:
|
||||
- ✅ Use in commercial projects
|
||||
- ✅ Use in client work
|
||||
- ✅ Include in paid products
|
||||
- ✅ Modify for commercial purposes
|
||||
|
||||
**Only requirement:** Keep the license notice.
|
||||
**No.** Official skills (in `skills/official/`) are mirrored from vendors. Open an issue instead.
|
||||
|
||||
---
|
||||
|
||||
@@ -519,10 +174,5 @@ See [Credits & Sources](README.md#credits--sources) for attribution.
|
||||
- Use `@systematic-debugging` when stuck on bugs
|
||||
- Try `@test-driven-development` for better code quality
|
||||
- Explore `@skill-creator` to make your own skills
|
||||
- Read skill descriptions to understand when to use them
|
||||
|
||||
---
|
||||
|
||||
**Question not answered?**
|
||||
|
||||
[Open a discussion](https://github.com/sickn33/antigravity-awesome-skills/discussions) and we'll help you out! 🙌
|
||||
**Still confused?** [Open a discussion](https://github.com/sickn33/antigravity-awesome-skills/discussions) and we'll help you out! 🙌
|
||||
|
||||
@@ -1,201 +1,108 @@
|
||||
# Getting Started with Antigravity Awesome Skills
|
||||
# Getting Started with Antigravity Awesome Skills (V3)
|
||||
|
||||
**New here? This guide will help you understand and use this repository in 5 minutes!**
|
||||
**New here? This guide will help you supercharge your AI Agent in 5 minutes.**
|
||||
|
||||
---
|
||||
|
||||
## 🤔 What Are "Skills"?
|
||||
|
||||
Think of skills as **specialized instruction manuals** for AI coding assistants.
|
||||
AI Agents (like **Claude Code**, **Gemini**, **Cursor**) are smart, but they lack specific knowledge about your tools.
|
||||
**Skills** are specialized instruction manuals (markdown files) that teach your AI how to perform specific tasks perfectly, every time.
|
||||
|
||||
**Simple analogy:** Just like you might hire different experts (a designer, a security expert, a marketer), these skills let your AI assistant become an expert in specific areas when you need them.
|
||||
**Analogy:** Your AI is a brilliant intern. **Skills** are the SOPs (Standard Operating Procedures) that make them a Senior Engineer.
|
||||
|
||||
---
|
||||
|
||||
## 📦 What's Inside This Repository?
|
||||
## ⚡️ Quick Start: The "Starter Packs"
|
||||
|
||||
This repo contains **179 ready-to-use skills** organized in the `skills/` folder. Each skill is a folder with at least one file: `SKILL.md`
|
||||
Don't panic about the 253+ skills. You don't need them all at once.
|
||||
We have curated **Starter Packs** to get you running immediately.
|
||||
|
||||
```
|
||||
skills/
|
||||
├── brainstorming/
|
||||
│ └── SKILL.md ← The skill definition
|
||||
├── stripe-integration/
|
||||
│ └── SKILL.md
|
||||
├── react-best-practices/
|
||||
│ └── SKILL.md
|
||||
└── ... (176 more skills)
|
||||
```
|
||||
### 1. Install the Repo
|
||||
|
||||
---
|
||||
|
||||
## How Do Skills Work?
|
||||
|
||||
### Step 1: Install Skills
|
||||
Copy the skills to your AI tool's directory:
|
||||
Copy the skills to your agent's folder:
|
||||
|
||||
```bash
|
||||
# For most AI tools (Claude Code, Gemini CLI, etc.)
|
||||
# Universal Installation (works for most agents)
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
```
|
||||
|
||||
### Step 2: Use a Skill
|
||||
In your AI chat, mention the skill:
|
||||
### 2. Pick Your Persona
|
||||
|
||||
```
|
||||
@brainstorming help me design a todo app
|
||||
```
|
||||
Find the bundle that matches your role (see [docs/BUNDLES.md](docs/BUNDLES.md)):
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
/stripe-integration add payment processing to my app
|
||||
```
|
||||
|
||||
### Step 3: The AI Becomes an Expert
|
||||
The AI loads that skill's knowledge and helps you with specialized expertise!
|
||||
| Persona | Bundle Name | What's Inside? |
|
||||
| :-------------------- | :------------- | :------------------------------------------------ |
|
||||
| **Web Developer** | `Web Wizard` | React Patterns, Tailwind mastery, Frontend Design |
|
||||
| **Security Engineer** | `Hacker Pack` | OWASP, Metasploit, Pentest Methodology |
|
||||
| **Manager / PM** | `Product Pack` | Brainstorming, Planning, SEO, Strategy |
|
||||
| **Everything** | `Essentials` | Clean Code, Planning, Validation (The Basics) |
|
||||
|
||||
---
|
||||
|
||||
## Which AI Tools Work With This?
|
||||
## 🚀 How to Use a Skill
|
||||
|
||||
| Tool | Works? | Installation Path |
|
||||
|------|--------|-------------------|
|
||||
| **Claude Code** | ✅ Yes | `.claude/skills/` or `.agent/skills/` |
|
||||
| **Gemini CLI** | ✅ Yes | `.gemini/skills/` or `.agent/skills/` |
|
||||
| **Cursor** | ✅ Yes | `.cursor/skills/` |
|
||||
| **GitHub Copilot** | ⚠️ Partial | Copy to `.github/copilot/` |
|
||||
| **Antigravity IDE** | ✅ Yes | `.agent/skills/` |
|
||||
Once installed, just talk to your AI naturally.
|
||||
|
||||
### Example 1: Planning a Feature (**Essentials**)
|
||||
|
||||
> "Use **@brainstorming** to help me design a new login flow."
|
||||
|
||||
**What happens:** The AI loads the brainstorming skill, asks you structured questions, and produces a professional spec.
|
||||
|
||||
### Example 2: Checking Your Code (**Web Wizard**)
|
||||
|
||||
> "Run **@lint-and-validate** on this file and fix errors."
|
||||
|
||||
**What happens:** The AI follows strict linting rules defined in the skill to clean your code.
|
||||
|
||||
### Example 3: Security Audit (**Hacker Pack**)
|
||||
|
||||
> "Use **@api-security-best-practices** to review my API endpoints."
|
||||
|
||||
**What happens:** The AI audits your code against OWASP standards.
|
||||
|
||||
---
|
||||
|
||||
## Skill Categories (Simplified)
|
||||
## 🔌 Supported Tools
|
||||
|
||||
### **Creative & Design** (10 skills)
|
||||
Make beautiful things: UI design, art, themes, web components
|
||||
- Try: `@frontend-design`, `@canvas-design`, `@ui-ux-pro-max`
|
||||
|
||||
### **Development** (25 skills)
|
||||
Write better code: testing, debugging, React patterns, architecture
|
||||
- Try: `@test-driven-development`, `@systematic-debugging`, `@react-best-practices`
|
||||
|
||||
### **Security** (50 skills)
|
||||
Ethical hacking and penetration testing tools
|
||||
- Try: `@ethical-hacking-methodology`, `@burp-suite-testing`
|
||||
|
||||
### **AI & Agents** (30 skills)
|
||||
Build AI apps: RAG, LangGraph, prompt engineering, voice agents
|
||||
- Try: `@rag-engineer`, `@prompt-engineering`, `@langgraph`
|
||||
|
||||
### **Documents** (4 skills)
|
||||
Work with Word, Excel, PowerPoint, PDF files
|
||||
- Try: `@docx-official`, `@xlsx-official`, `@pdf-official`
|
||||
|
||||
### **Marketing** (23 skills)
|
||||
Grow your product: SEO, copywriting, ads, email campaigns
|
||||
- Try: `@copywriting`, `@seo-audit`, `@page-cro`
|
||||
|
||||
### **Integrations** (25 skills)
|
||||
Connect to services: Stripe, Firebase, Twilio, Discord, Slack
|
||||
- Try: `@stripe-integration`, `@firebase`, `@clerk-auth`
|
||||
| Tool | Status | Path |
|
||||
| :-------------- | :-------------- | :---------------- |
|
||||
| **Claude Code** | ✅ Full Support | `.claude/skills/` |
|
||||
| **Gemini CLI** | ✅ Full Support | `.gemini/skills/` |
|
||||
| **Antigravity** | ✅ Native | `.agent/skills/` |
|
||||
| **Cursor** | ✅ Native | `.cursor/skills/` |
|
||||
| **Copilot** | ⚠️ Text Only | Manual copy-paste |
|
||||
|
||||
---
|
||||
|
||||
## Your First Skill: A Quick Example
|
||||
## 🛡️ Trust & Safety (New in V3)
|
||||
|
||||
Let's try the **brainstorming** skill:
|
||||
We classify skills so you know what you're running:
|
||||
|
||||
1. **Open your AI assistant** (Claude Code, Cursor, etc.)
|
||||
- 🟣 **Official**: Maintained by Anthropic/Google/Vendors (High Trust).
|
||||
- 🔵 **Safe**: Community skills that are non-destructive (Read-only/Planning).
|
||||
- 🔴 **Risk**: Skills that modify systems or perform security tests (Authorized Use Only).
|
||||
|
||||
2. **Type this:**
|
||||
```
|
||||
@brainstorming I want to build a simple weather app
|
||||
```
|
||||
|
||||
3. **What happens:**
|
||||
- The AI loads the brainstorming skill
|
||||
- It asks you questions one at a time
|
||||
- It helps you design the app before coding
|
||||
- It creates a design document for you
|
||||
|
||||
4. **Result:** You get a well-thought-out plan instead of jumping straight to code!
|
||||
_Check the [Full Registry](README.md#full-skill-registry-253253) for risk labels._
|
||||
|
||||
---
|
||||
|
||||
## How to Find the Right Skill
|
||||
## ❓ FAQ
|
||||
|
||||
### Method 1: Browse by Category
|
||||
Check the [Full Skill Registry](README.md#full-skill-registry-179179) in the main README
|
||||
**Q: Do I need to install all 250 skills?**
|
||||
A: You clone the whole repo, but your AI only _reads_ the ones you ask for (or that are relevant). It's lightweight!
|
||||
|
||||
### Method 2: Search by Keyword
|
||||
Use your file explorer or terminal:
|
||||
```bash
|
||||
# Find skills related to "testing"
|
||||
ls skills/ | grep test
|
||||
**Q: Can I make my own skills?**
|
||||
A: Yes! Use the **@skill-creator** skill to build your own.
|
||||
|
||||
# Find skills related to "auth"
|
||||
ls skills/ | grep auth
|
||||
```
|
||||
|
||||
### Method 3: Look at the Index
|
||||
Check `skills_index.json` for a machine-readable list
|
||||
**Q: Is this free?**
|
||||
A: Yes, MIT License. Open Source forever.
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Want to Contribute?
|
||||
## ⏭️ Next Steps
|
||||
|
||||
Great! Here's how:
|
||||
|
||||
### Option 1: Improve Documentation
|
||||
- Make READMEs clearer
|
||||
- Add more examples
|
||||
- Fix typos or confusing parts
|
||||
|
||||
### Option 2: Create a New Skill
|
||||
See our [CONTRIBUTING.md](CONTRIBUTING.md) for step-by-step instructions
|
||||
|
||||
### Option 3: Report Issues
|
||||
Found something confusing? [Open an issue](https://github.com/sickn33/antigravity-awesome-skills/issues)
|
||||
|
||||
---
|
||||
|
||||
## ❓ Common Questions
|
||||
|
||||
### Q: Do I need to install all 179 skills?
|
||||
**A:** No! Clone the whole repo, and your AI will only load skills when you use them.
|
||||
|
||||
### Q: Can I create my own skills?
|
||||
**A:** Yes! Check out the `@skill-creator` skill or read [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
### Q: What if my AI tool isn't listed?
|
||||
**A:** If it supports the `SKILL.md` format, try `.agent/skills/` - it's the universal path.
|
||||
|
||||
### Q: Are these skills free?
|
||||
**A:** Yes! MIT License. Use them however you want.
|
||||
|
||||
### Q: Do skills work offline?
|
||||
**A:** The skill files are local, but your AI assistant needs internet to function.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ Install the skills in your AI tool
|
||||
2. ✅ Try 2-3 skills from different categories
|
||||
3. ✅ Read [CONTRIBUTING.md](CONTRIBUTING.md) if you want to help
|
||||
4. ✅ Star the repo if you find it useful! ⭐
|
||||
|
||||
---
|
||||
|
||||
## 💡 Pro Tips
|
||||
|
||||
- **Start with `@brainstorming`** before building anything new
|
||||
- **Use `@systematic-debugging`** when you're stuck on a bug
|
||||
- **Try `@test-driven-development`** to write better code
|
||||
- **Explore `@skill-creator`** to make your own skills
|
||||
|
||||
---
|
||||
|
||||
**Still confused?** Open an issue and we'll help you out! 🙌
|
||||
|
||||
**Ready to dive deeper?** Check out the main [README.md](README.md) for the complete skill list.
|
||||
1. [Browse the Bundles](docs/BUNDLES.md)
|
||||
2. [See Real-World Examples](docs/EXAMPLES.md)
|
||||
3. [Contribute a Skill](CONTRIBUTING.md)
|
||||
|
||||
648
README.md
648
README.md
@@ -1,6 +1,6 @@
|
||||
# 🌌 Antigravity Awesome Skills: 225+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
|
||||
# 🌌 Antigravity Awesome Skills: 255+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
|
||||
|
||||
> **The Ultimate Collection of 225+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode**
|
||||
> **The Ultimate Collection of 255+ 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)
|
||||
@@ -9,9 +9,9 @@
|
||||
[](https://cursor.sh)
|
||||
[](https://github.com/features/copilot)
|
||||
[](https://github.com/opencode-ai/opencode)
|
||||
[](https://github.com/anthropics/antigravity)
|
||||
[](https://github.com/sickn33/antigravity-awesome-skills)
|
||||
|
||||
**Antigravity Awesome Skills** is a curated, battle-tested library of **225 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
|
||||
**Antigravity Awesome Skills** is a curated, battle-tested library of **255 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
|
||||
|
||||
- 🟣 **Claude Code** (Anthropic CLI)
|
||||
- 🔵 **Gemini CLI** (Google DeepMind)
|
||||
@@ -21,65 +21,76 @@
|
||||
- 🟠 **Cursor** (AI-native IDE)
|
||||
- ⚪ **OpenCode** (Open-source CLI)
|
||||
|
||||
This repository provides essential skills to transform your AI assistant into a **full-stack digital agency**, including official capabilities from **Anthropic**, **OpenAI**, **Google**, and **Vercel Labs**.
|
||||
This repository provides essential skills to transform your AI assistant into a **full-stack digital agency**, including official capabilities from **Anthropic**, **OpenAI**, **Google**, **Supabase**, and **Vercel Labs**.
|
||||
|
||||
## 📍 Table of Contents
|
||||
|
||||
- [🚀 New Here? Start Here!](#-new-here-start-here)
|
||||
- [🔌 Compatibility](#-compatibility)
|
||||
- [Features & Categories](#features--categories)
|
||||
- [Full Skill Registry](#full-skill-registry-155155)
|
||||
- [Installation](#installation)
|
||||
- [How to Contribute](#how-to-contribute)
|
||||
- [Credits & Sources](#credits--sources)
|
||||
- [License](#license)
|
||||
- [🚀 New Here? Start Here!](#new-here-start-here)
|
||||
- [🔌 Compatibility & Invocation](#compatibility--invocation)
|
||||
- [📦 Features & Categories](#features--categories)
|
||||
- [🎁 Curated Collections (Bundles)](#curated-collections)
|
||||
- [📜 Full Skill Registry](#full-skill-registry-253253)
|
||||
- [🛠️ Installation](#installation)
|
||||
- [🤝 How to Contribute](#how-to-contribute)
|
||||
- [👥 Contributors & Credits](#credits--sources)
|
||||
- [⚖️ License](#license)
|
||||
- [👥 Repo Contributors](#repo-contributors)
|
||||
- [🌟 Star History](#star-history)
|
||||
|
||||
---
|
||||
|
||||
## New Here? Start Here!
|
||||
|
||||
**First time using this repository?** We've created beginner-friendly guides to help you get started:
|
||||
**Welcome to the V3 Enterprise Edition.** This isn't just a list of scripts; it's a complete operating system for your AI Agent.
|
||||
|
||||
- **[GETTING_STARTED.md](GETTING_STARTED.md)** - Complete beginner's guide (5-minute read)
|
||||
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - How to contribute (step-by-step)
|
||||
- **[SKILL_ANATOMY.md](docs/SKILL_ANATOMY.md)** - Understanding how skills work
|
||||
- **[VISUAL_GUIDE.md](docs/VISUAL_GUIDE.md)** - Visual guide with diagrams
|
||||
### 1. 🐣 Context: What is this?
|
||||
|
||||
**Quick Start:**
|
||||
AI Agents (like Claude Code, Cursor, or Gemini) are smart, but they lack **specific tools**. They don't know your company's "Deployment Protocol" or the specific syntax for "AWS CloudFormation".
|
||||
**Skills** are small markdown files that teach them how to do these specific tasks perfectly, every time.
|
||||
|
||||
```bash
|
||||
# 1. Install skills
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
### 2. ⚡️ Quick Start (The "Bundle" Way)
|
||||
|
||||
# 2. Use a skill in your AI assistant
|
||||
@brainstorming help me design a todo app
|
||||
```
|
||||
Don't install 250+ skills manually. Use our **Starter Packs**:
|
||||
|
||||
That's it! Your AI assistant now has 225 specialized skills. 🎉
|
||||
1. **Clone the repo**:
|
||||
```bash
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
```
|
||||
2. **Pick your persona** (See [docs/BUNDLES.md](docs/BUNDLES.md)):
|
||||
- **Web Dev?** use the `Web Wizard` pack.
|
||||
- **Hacker?** use the `Security Engineer` pack.
|
||||
- **Just curious?** start with `Essentials`.
|
||||
|
||||
**Additional Resources:**
|
||||
### 3. 🧠 How to use
|
||||
|
||||
- 💡 **[Real-World Examples](docs/EXAMPLES.md)** - See skills in action
|
||||
- ❓ **[FAQ](FAQ.md)** - Common questions answered
|
||||
Once installed, just ask your agent naturally:
|
||||
|
||||
> "Use the **@brainstorming** skill to help me plan a SaaS."
|
||||
> "Run **@lint-and-validate** on this file."
|
||||
|
||||
👉 **[Read the Full Getting Started Guide](GETTING_STARTED.md)**
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Compatibility
|
||||
## Compatibility & Invocation
|
||||
|
||||
These skills follow the universal **SKILL.md** format and work with any AI coding assistant that supports agentic skills:
|
||||
These skills follow the universal **SKILL.md** format and work with any AI coding assistant that supports agentic skills.
|
||||
|
||||
| Tool | Type | Compatibility | Installation Path |
|
||||
| ------------------- | --------- | ------------- | ---------------------------------------- |
|
||||
| **Claude Code** | CLI | ✅ Full | `.claude/skills/` or `.agent/skills/` |
|
||||
| **Gemini CLI** | CLI | ✅ Full | `.gemini/skills/` or `.agent/skills/` |
|
||||
| **Codex CLI** | CLI | ✅ Full | `.codex/skills/` or `.agent/skills/` |
|
||||
| **Antigravity IDE** | IDE | ✅ Full | `.agent/skills/` |
|
||||
| **Cursor** | IDE | ✅ Full | `.cursor/skills/` or project root |
|
||||
| **GitHub Copilot** | Extension | ⚠️ Partial | Copy skill content to `.github/copilot/` |
|
||||
| **OpenCode** | CLI | ✅ Full | `.opencode/skills/` or `.agent/skills/` |
|
||||
| Tool | Type | Invocation Example | Path |
|
||||
| :-------------- | :--- | :-------------------------------- | :---------------- |
|
||||
| **Claude Code** | CLI | `>> /skill-name help me...` | `.claude/skills/` |
|
||||
| **Gemini CLI** | CLI | `(User Prompt) Use skill-name...` | `.gemini/skills/` |
|
||||
| **Antigravity** | IDE | `(Agent Mode) Use skill...` | `.agent/skills/` |
|
||||
| **Cursor** | IDE | `@skill-name (in Chat)` | `.cursor/skills/` |
|
||||
| **Copilot** | Ext | `(Paste content manually)` | N/A |
|
||||
|
||||
> [!TIP]
|
||||
> Most tools auto-discover skills in `.agent/skills/`. For maximum compatibility, clone to this directory.
|
||||
> **Universal Path**: We recommend cloning to `.agent/skills/`. Most modern tools (Antigravity, recent CLIs) look here by default.
|
||||
|
||||
> [!WARNING]
|
||||
> **Windows Users**: This repository uses **symlinks** for official skills.
|
||||
> You must enable Developer Mode or run Git as Administrator:
|
||||
> `git clone -c core.symlinks=true https://github.com/...`
|
||||
|
||||
---
|
||||
|
||||
@@ -95,11 +106,11 @@ The repository is organized into several key areas of expertise:
|
||||
| :-------------------------- | :----------- | :--------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **🛸 Autonomous & Agentic** | **~8** | Loki Mode (Startup-in-a-box), Subagent Driven Dev, Dispatching Parallel Agents, Planning With Files, Skill Creator/Developer |
|
||||
| **🔌 Integrations & APIs** | **~25** | Stripe, Firebase, Supabase, Vercel, Clerk Auth, Twilio, Discord Bot, Slack Bot, GraphQL, AWS Serverless |
|
||||
| **🛡️ Cybersecurity** | **~50** | Ethical Hacking, Metasploit, Burp Suite, SQLMap, Active Directory, AWS/Cloud Pentesting, OWASP Top 100, Red Team Tools |
|
||||
| **🛡️ Cybersecurity** | **~51** | Ethical Hacking, Metasploit, Burp Suite, SQLMap, Active Directory, AWS/Cloud Pentesting, OWASP Top 100, Red Team Tools |
|
||||
| **🎨 Creative & Design** | **~10** | UI/UX Pro Max, Frontend Design, Canvas, Algorithmic Art, Theme Factory, D3 Viz, Web Artifacts |
|
||||
| **🛠️ Development** | **~25** | TDD, Systematic Debugging, React Patterns, Backend/Frontend Guidelines, Senior Fullstack, Software Architecture |
|
||||
| **🛠️ Development** | **~33** | TDD, Systematic Debugging, React Patterns, Backend/Frontend Guidelines, Senior Fullstack, Software Architecture |
|
||||
| **🏗️ Infrastructure & Git** | **~8** | Linux Shell Scripting, Git Worktrees, Git Pushing, Conventional Commits, File Organization, GitHub Workflow Automation |
|
||||
| **🤖 AI Agents & LLM** | **~30** | LangGraph, CrewAI, Langfuse, RAG Engineer, Prompt Engineer, Voice Agents, Browser Automation, Agent Memory Systems |
|
||||
| **🤖 AI Agents & LLM** | **~31** | LangGraph, CrewAI, Langfuse, RAG Engineer, Prompt Engineer, Voice Agents, Browser Automation, Agent Memory Systems |
|
||||
| **🔄 Workflow & Planning** | **~6** | Writing Plans, Executing Plans, Concise Planning, Verification Before Completion, Code Review (Requesting/Receiving) |
|
||||
| **📄 Document Processing** | **~4** | DOCX (Official), PDF (Official), PPTX (Official), XLSX (Official) |
|
||||
| **🧪 Testing & QA** | **~4** | Webapp Testing, Playwright Automation, Test Fixing, Testing Patterns |
|
||||
@@ -109,233 +120,279 @@ The repository is organized into several key areas of expertise:
|
||||
|
||||
---
|
||||
|
||||
## Full Skill Registry (225/225)
|
||||
## Curated Collections
|
||||
|
||||
Below is the complete list of available skills. Each skill folder contains a `SKILL.md` that can be imported into Antigravity or Claude Code.
|
||||
[Check out our Starter Packs in docs/BUNDLES.md](docs/BUNDLES.md) to find the perfect toolkit for your role.
|
||||
|
||||
## Curated Collections
|
||||
|
||||
[Check out our Starter Packs in docs/BUNDLES.md](docs/BUNDLES.md) to find the perfect toolkit for your role.
|
||||
|
||||
## 📦 Curated Collections
|
||||
|
||||
[Check out our Starter Packs in docs/BUNDLES.md](docs/BUNDLES.md) to find the perfect toolkit for your role.
|
||||
|
||||
## Full Skill Registry (255/255)
|
||||
|
||||
> [!NOTE] > **Document Skills**: We provide both **community** and **official Anthropic** versions for DOCX, PDF, PPTX, and XLSX. Locally, the official versions are used by default (via symlinks). In the repository, both versions are available for flexibility.
|
||||
|
||||
| Skill Name | Description | Path |
|
||||
| :-------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------- |
|
||||
| **3D Web Experience** | Expert in building 3D experiences for the web - Three.js, React Three Fiber, Spline, WebGL. | `skills/3d-web-experience` |
|
||||
| **A/B Test Setup** | Plan and implement A/B tests with proper experiment design, statistical significance, and test analysis. | `skills/ab-test-setup` |
|
||||
| **Active Directory Attacks** | This skill should be used when the user asks to "attack Active Directory", "exploit AD", "Kerberoasting", "DCSync", "pass-the-hash", "BloodHound enumeration", "Golden Ticket", "Silver Ticket", "AS-REP roasting", "NTLM relay", or needs guidance on Windows domain penetration testing. | `skills/active-directory-attacks` |
|
||||
| **Address GitHub Comments** | Use when you need to address review or issue comments on an open GitHub Pull Request using the gh CLI. | `skills/address-github-comments` |
|
||||
| **Agent Evaluation** | Testing and benchmarking LLM agents including behavioral testing, capability assessment, reliability metrics. | `skills/agent-evaluation` |
|
||||
| **Agent Manager Skill** | Use when you need to manage multiple local CLI agents via tmux sessions (start/stop/monitor/assign) with cron-friendly scheduling. | `skills/agent-manager-skill` |
|
||||
| **Agent Memory Systems** | Memory architecture for agents: short-term, long-term (vector stores), and cognitive architectures. | `skills/agent-memory-systems` |
|
||||
| **Agent Tool Builder** | Tool design from schema to error handling. JSON Schema best practices, validation, and MCP. | `skills/agent-tool-builder` |
|
||||
| **AI Agents Architect** | Expert in autonomous AI agents. Tool use, memory systems, planning strategies, multi-agent orchestration. | `skills/ai-agents-architect` |
|
||||
| **AI Product** | LLM integration patterns, RAG architecture, prompt engineering, AI UX, and cost optimization. | `skills/ai-product` |
|
||||
| **AI Wrapper Product** | Building products that wrap AI APIs into focused tools. Prompt engineering, cost management. | `skills/ai-wrapper-product` |
|
||||
| **Algolia Search** | Algolia search implementation, indexing strategies, React InstantSearch, relevance tuning. | `skills/algolia-search` |
|
||||
| **Algorithmic Art** | Creating algorithmic art using p5. | `skills/algorithmic-art` |
|
||||
| **Analytics Tracking** | Set up analytics tracking with GA4, GTM, and custom event implementations for marketing measurement. | `skills/analytics-tracking` |
|
||||
| **API Fuzzing for Bug Bounty** | This skill should be used when the user asks to "test API security", "fuzz APIs", "find IDOR vulnerabilities", "test REST API", "test GraphQL", "API penetration testing", "bug bounty API testing", or needs guidance on API security assessment techniques. | `skills/api-fuzzing-bug-bounty` |
|
||||
| **API Patterns** | API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning. | `skills/api-patterns` |
|
||||
| **App Builder** | Main application building orchestrator. Creates full-stack applications from natural language requests. | `skills/app-builder` |
|
||||
| **App Store Optimization** | Complete App Store Optimization (ASO) toolkit for researching, optimizing, and tracking mobile app performance on Apple App Store and Google Play Store. | `skills/app-store-optimization` |
|
||||
| **Architecture** | Architectural decision-making framework. Requirements analysis, trade-off evaluation, ADR documentation. | `skills/architecture` |
|
||||
| **Autonomous Agent Patterns** | "Design patterns for building autonomous coding agents. | `skills/autonomous-agent-patterns` |
|
||||
| **Autonomous Agents** | AI systems that independently decompose goals, plan actions, execute tools. ReAct, reflection. | `skills/autonomous-agents` |
|
||||
| **AWS Penetration Testing** | This skill should be used when the user asks to "pentest AWS", "test AWS security", "enumerate IAM", "exploit cloud infrastructure", "AWS privilege escalation", "S3 bucket testing", "metadata SSRF", "Lambda exploitation", or needs guidance on Amazon Web Services security assessment. | `skills/aws-penetration-testing` |
|
||||
| **AWS Serverless** | Serverless on AWS. Lambda, API Gateway, DynamoDB, SQS/SNS, SAM/CDK deployment. | `skills/aws-serverless` |
|
||||
| **Azure Functions** | Azure Functions patterns. Isolated worker model, Durable Functions, cold start optimization. | `skills/azure-functions` |
|
||||
| **Backend Guidelines** | Comprehensive backend development guide for Node. | `skills/backend-dev-guidelines` |
|
||||
| **Bash Linux** | Bash/Linux terminal patterns. Critical commands, piping, error handling, scripting. | `skills/bash-linux` |
|
||||
| **Behavioral Modes** | AI operational modes (brainstorm, implement, debug, review, teach, ship, orchestrate). | `skills/behavioral-modes` |
|
||||
| **BlockRun** | Agent wallet for LLM micropayments. Use when user needs capabilities Claude lacks (image generation, real-time X/Twitter data) or explicitly requests external models ("blockrun", "use grok", "use gpt", "dall-e", "deepseek"). | `skills/blockrun` |
|
||||
| **Brainstorming** | "You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. | `skills/brainstorming` |
|
||||
| **Brand Guidelines (Anthropic)** | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. | `skills/brand-guidelines-anthropic` |
|
||||
| **Brand Guidelines (Community)** | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. | `skills/brand-guidelines-community` |
|
||||
| **Broken Authentication Testing** | This skill should be used when the user asks to "test for broken authentication vulnerabilities", "assess session management security", "perform credential stuffing tests", "evaluate password policies", "test for session fixation", or "identify authentication bypass flaws". | `skills/broken-authentication` |
|
||||
| **Browser Automation** | Browser automation with Playwright and Puppeteer. Testing, scraping, agentic control. | `skills/browser-automation` |
|
||||
| **Browser Extension Builder** | Building browser extensions - Chrome, Firefox. Manifest v3, content scripts, monetization. | `skills/browser-extension-builder` |
|
||||
| **BullMQ Specialist** | BullMQ for Redis-backed job queues, background processing in Node.js/TypeScript. | `skills/bullmq-specialist` |
|
||||
| **Bun Development** | "Modern JavaScript/TypeScript development with Bun runtime. | `skills/bun-development` |
|
||||
| **Burp Suite Web Application Testing** | This skill should be used when the user asks to "intercept HTTP traffic", "modify web requests", "use Burp Suite for testing", "perform web vulnerability scanning", "test with Burp Repeater", "analyze HTTP history", or "configure proxy for web testing". | `skills/burp-suite-testing` |
|
||||
| **Canvas Design** | Create beautiful visual art in . | `skills/canvas-design` |
|
||||
| **Claude Code Guide** | Master guide for using Claude Code effectively. | `skills/claude-code-guide` |
|
||||
| **Claude D3.js** | Creating interactive data visualisations using d3. | `skills/claude-d3js-skill` |
|
||||
| **Clean Code** | Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments. | `skills/clean-code` |
|
||||
| **Clerk Auth** | Clerk auth implementation, middleware, organizations, webhooks, user sync. | `skills/clerk-auth` |
|
||||
| **Cloud Penetration Testing** | This skill should be used when the user asks to "perform cloud penetration testing", "assess Azure or AWS or GCP security", "enumerate cloud resources", "exploit cloud misconfigurations", "test O365 security", "extract secrets from cloud environments", or "audit cloud infrastructure". | `skills/cloud-penetration-testing` |
|
||||
| **Code Review Checklist** | Code review guidelines covering code quality, security, and best practices. | `skills/code-review-checklist` |
|
||||
| **Competitor Alternatives** | Create compelling competitor comparison and alternative pages for SEO and conversions. | `skills/competitor-alternatives` |
|
||||
| **Computer Use Agents** | AI agents that interact with computers like humans. Screen control, sandboxing. | `skills/computer-use-agents` |
|
||||
| **Concise Planning** | Use when a user asks for a plan for a coding task, to generate a clear, actionable, and atomic checklist. | `skills/concise-planning` |
|
||||
| **Content Creator** | Create SEO-optimized marketing content with consistent brand voice. | `skills/content-creator` |
|
||||
| **Context Window Management** | Managing LLM context windows. Summarization, trimming, routing. | `skills/context-window-management` |
|
||||
| **Conversation Memory** | Persistent memory for LLM conversations. Short-term, long-term, entity-based memory. | `skills/conversation-memory` |
|
||||
| **Copy Editing** | Edit and polish existing marketing copy with a systematic seven-sweeps framework. | `skills/copy-editing` |
|
||||
| **Copywriting** | Write compelling marketing copy for homepages, landing pages, pricing pages, and feature pages. | `skills/copywriting` |
|
||||
| **Core Components** | Core component library and design system patterns. | `skills/core-components` |
|
||||
| **CrewAI** | Role-based multi-agent framework. Agent design, task definition, crew orchestration. | `skills/crewai` |
|
||||
| **Cross-Site Scripting and HTML Injection Testing** | This skill should be used when the user asks to "test for XSS vulnerabilities", "perform cross-site scripting attacks", "identify HTML injection flaws", "exploit client-side injection vulnerabilities", "steal cookies via XSS", or "bypass content security policies". | `skills/xss-html-injection` |
|
||||
| **Database Design** | Database design principles. Schema design, indexing strategy, ORM selection, serverless databases. | `skills/database-design` |
|
||||
| **Deployment Procedures** | Production deployment principles. Safe deployment workflows, rollback strategies, and verification. | `skills/deployment-procedures` |
|
||||
| **Discord Bot Architect** | Production Discord bots. Discord.js, Pycord, slash commands, sharding. | `skills/discord-bot-architect` |
|
||||
| **Dispatching Parallel Agents** | Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. | `skills/dispatching-parallel-agents` |
|
||||
| **Doc Co-authoring** | Guide users through a structured workflow for co-authoring documentation. | `skills/doc-coauthoring` |
|
||||
| **Docker Expert** | Docker containerization expert. Multi-stage builds, image optimization, container security, Docker Compose. | `skills/docker-expert` |
|
||||
| **Documentation Templates** | Documentation templates and structure guidelines. README, API docs, code comments. | `skills/documentation-templates` |
|
||||
| **DOCX (Official)** | "Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. | `skills/docx-official` |
|
||||
| **Email Sequence** | Create and optimize email sequences, drip campaigns, and lifecycle email programs. | `skills/email-sequence` |
|
||||
| **Email Systems** | Transactional email, marketing automation, deliverability, infrastructure. | `skills/email-systems` |
|
||||
| **Ethical Hacking Methodology** | This skill should be used when the user asks to "learn ethical hacking", "understand penetration testing lifecycle", "perform reconnaissance", "conduct security scanning", "exploit vulnerabilities", or "write penetration test reports". | `skills/ethical-hacking-methodology` |
|
||||
| **Executing Plans** | Use when you have a written implementation plan to execute in a separate session with review checkpoints. | `skills/executing-plans` |
|
||||
| **File Organizer** | Intelligently organizes files and folders by understanding context, finding duplicates, and suggesting better organizational structures. | `skills/file-organizer` |
|
||||
| **File Path Traversal Testing** | This skill should be used when the user asks to "test for directory traversal", "exploit path traversal vulnerabilities", "read arbitrary files through web applications", "find LFI vulnerabilities", or "access files outside web root". | `skills/file-path-traversal` |
|
||||
| **File Uploads** | File uploads and cloud storage. S3, Cloudflare R2, presigned URLs. | `skills/file-uploads` |
|
||||
| **Finishing Dev Branch** | Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup. | `skills/finishing-a-development-branch` |
|
||||
| **Firebase** | Firebase Auth, Firestore, Realtime Database, Cloud Functions, Storage. | `skills/firebase` |
|
||||
| **Form CRO** | Optimize lead capture forms, contact forms, demo request forms for higher conversion rates. | `skills/form-cro` |
|
||||
| **Free Tool Strategy** | Plan and build free tools for marketing, lead generation, and SEO value. | `skills/free-tool-strategy` |
|
||||
| **Frontend Design** | Create distinctive, production-grade frontend interfaces with high design quality. | `skills/frontend-design` |
|
||||
| **Frontend Guidelines** | Frontend development guidelines for React/TypeScript applications. | `skills/frontend-dev-guidelines` |
|
||||
| **Game Development** | Game development orchestrator. Routes to platform-specific skills based on project needs. | `skills/game-development` |
|
||||
| **GCP Cloud Run** | Serverless on GCP. Cloud Run services and functions, Pub/Sub. | `skills/gcp-cloud-run` |
|
||||
| **GEO Fundamentals** | Generative Engine Optimization for AI search engines (ChatGPT, Claude, Perplexity). | `skills/geo-fundamentals` |
|
||||
| **Git Pushing** | Stage, commit, and push git changes with conventional commit messages. | `skills/git-pushing` |
|
||||
| **GitHub Workflow Automation** | "Automate GitHub workflows with AI assistance. | `skills/github-workflow-automation` |
|
||||
| **GraphQL** | Schema design, resolvers, DataLoader, federation, Apollo/urql integration. | `skills/graphql` |
|
||||
| **HTML Injection Testing** | This skill should be used when the user asks to "test for HTML injection", "inject HTML into web pages", "perform HTML injection attacks", "deface web applications", or "test content injection vulnerabilities". | `skills/html-injection-testing` |
|
||||
| **HubSpot Integration** | HubSpot CRM integration. OAuth, CRM objects, webhooks, custom objects. | `skills/hubspot-integration` |
|
||||
| **i18n Localization** | Internationalization and localization patterns. Detecting hardcoded strings, managing translations. | `skills/i18n-localization` |
|
||||
| **IDOR Vulnerability Testing** | This skill should be used when the user asks to "test for insecure direct object references," "find IDOR vulnerabilities," "exploit broken access control," "enumerate user IDs or object references," or "bypass authorization to access other users' data. | `skills/idor-testing` |
|
||||
| **Inngest** | Inngest for serverless background jobs, event-driven workflows. | `skills/inngest` |
|
||||
| **Interactive Portfolio** | Building portfolios that land jobs. Developer, designer portfolios. | `skills/interactive-portfolio` |
|
||||
| **Internal Comms (Anthropic)** | A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. | `skills/internal-comms-anthropic` |
|
||||
| **Internal Comms (Community)** | A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. | `skills/internal-comms-community` |
|
||||
| **JavaScript Mastery** | "Comprehensive JavaScript reference covering 33+ essential concepts every developer should know. | `skills/javascript-mastery` |
|
||||
| **Kaizen** | Guide for continuous improvement, error proofing, and standardization. | `skills/kaizen` |
|
||||
| **Langfuse** | Open-source LLM observability. Tracing, prompt management, evaluation. | `skills/langfuse` |
|
||||
| **LangGraph** | Stateful, multi-actor AI applications. Graph construction, persistence. | `skills/langgraph` |
|
||||
| **Launch Strategy** | Plan product launches, feature announcements, and go-to-market strategies. | `skills/launch-strategy` |
|
||||
| **Lint and Validate** | Automatic quality control, linting, and static analysis procedures. | `skills/lint-and-validate` |
|
||||
| **Linux Privilege Escalation** | This skill should be used when the user asks to "escalate privileges on Linux", "find privesc vectors on Linux systems", "exploit sudo misconfigurations", "abuse SUID binaries", "exploit cron jobs for root access", "enumerate Linux systems for privilege escalation", or "gain root access from low-privilege shell". | `skills/linux-privilege-escalation` |
|
||||
| **Linux Shell Scripting** | This skill should be used when the user asks to "create bash scripts", "automate Linux tasks", "monitor system resources", "backup files", "manage users", or "write production shell scripts". | `skills/linux-shell-scripting` |
|
||||
| **LLM App Patterns** | "Production-ready patterns for building LLM applications. | `skills/llm-app-patterns` |
|
||||
| **Loki Mode** | Multi-agent autonomous startup system for Claude Code. | `skills/loki-mode` |
|
||||
| **Marketing Ideas** | 140 proven SaaS marketing ideas and strategies organized by category. | `skills/marketing-ideas` |
|
||||
| **Marketing Psychology** | 70+ mental models and psychological principles for marketing and persuasion. | `skills/marketing-psychology` |
|
||||
| **MCP Builder** | Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. | `skills/mcp-builder` |
|
||||
| **Metasploit Framework** | This skill should be used when the user asks to "use Metasploit for penetration testing", "exploit vulnerabilities with msfconsole", "create payloads with msfvenom", "perform post-exploitation", "use auxiliary modules for scanning", or "develop custom exploits". | `skills/metasploit-framework` |
|
||||
| **Micro-SaaS Launcher** | Launching small SaaS products fast. Idea validation, MVP, pricing. | `skills/micro-saas-launcher` |
|
||||
| **Mobile Design** | Mobile-first design thinking for iOS and Android apps. Touch interaction, performance patterns. | `skills/mobile-design` |
|
||||
| **Moodle External API Development** | Create custom external web service APIs for Moodle LMS. Use when implementing web services for course management, user tracking, quiz operations, or custom plugin functionality. Covers parameter validation, database operations, error handling, service registration, and Moodle coding standards. | `skills/moodle-external-api-development` |
|
||||
| **Neon Postgres** | Neon serverless Postgres, branching, connection pooling, Prisma integration. | `skills/neon-postgres` |
|
||||
| **NestJS Expert** | Nest.js framework expert. Module architecture, dependency injection, middleware, guards, interceptors. | `skills/nestjs-expert` |
|
||||
| **Network 101** | This skill should be used when the user asks to "set up a web server", "configure HTTP or HTTPS", "perform SNMP enumeration", "configure SMB shares", "test network services", or needs guidance on configuring and testing network services for penetration testing labs. | `skills/network-101` |
|
||||
| **Next.js Best Practices** | Next.js App Router principles. Server Components, data fetching, routing patterns. | `skills/nextjs-best-practices` |
|
||||
| **Next.js Supabase Auth** | Supabase Auth with Next.js App Router. Auth middleware. | `skills/nextjs-supabase-auth` |
|
||||
| **Node.js Best Practices** | Node.js development principles. Framework selection, async patterns, security, architecture. | `skills/nodejs-best-practices` |
|
||||
| **NotebookLM** | Use this skill to query your Google NotebookLM notebooks directly from Claude Code for source-grounded, citation-backed answers from Gemini. | `skills/notebooklm` |
|
||||
| **Notion Template Business** | Building and selling Notion templates. Design, pricing, marketing. | `skills/notion-template-business` |
|
||||
| **Onboarding CRO** | Optimize post-signup onboarding, user activation, and time-to-value. | `skills/onboarding-cro` |
|
||||
| **Page CRO** | Conversion rate optimization for marketing pages - homepages, landing pages, pricing pages. | `skills/page-cro` |
|
||||
| **Paid Ads** | Create and optimize paid ad campaigns on Google Ads, Meta, LinkedIn, and other platforms. | `skills/paid-ads` |
|
||||
| **Parallel Agents** | Multi-agent orchestration patterns. Use when multiple independent tasks can run with different domain expertise. | `skills/parallel-agents` |
|
||||
| **Paywall Upgrade CRO** | Optimize in-app paywalls, upgrade screens, and freemium conversion moments. | `skills/paywall-upgrade-cro` |
|
||||
| **PDF (Official)** | Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. | `skills/pdf-official` |
|
||||
| **Pentest Checklist** | This skill should be used when the user asks to "plan a penetration test", "create a security assessment checklist", "prepare for penetration testing", "define pentest scope", "follow security testing best practices", or needs a structured methodology for penetration testing engagements. | `skills/pentest-checklist` |
|
||||
| **Pentest Commands** | This skill should be used when the user asks to "run pentest commands", "scan with nmap", "use metasploit exploits", "crack passwords with hydra or john", "scan web vulnerabilities with nikto", "enumerate networks", or needs essential penetration testing command references. | `skills/pentest-commands` |
|
||||
| **Performance Profiling** | Performance profiling principles. Measurement, analysis, and optimization techniques. | `skills/performance-profiling` |
|
||||
| **Personal Tool Builder** | Building custom tools. Rapid prototyping, local-first apps, CLI tools. | `skills/personal-tool-builder` |
|
||||
| **Plaid Fintech** | Plaid API for banking. Link token flows, transactions, ACH. | `skills/plaid-fintech` |
|
||||
| **Plan Writing** | Structured task planning with clear breakdowns, dependencies, and verification criteria. | `skills/plan-writing` |
|
||||
| **Planning With Files** | Implements Manus-style file-based planning for complex tasks. | `skills/planning-with-files` |
|
||||
| **Playwright Automation** | Complete browser automation with Playwright. | `skills/playwright-skill` |
|
||||
| **Popup CRO** | Create and optimize popups, modals, and overlays for conversion. | `skills/popup-cro` |
|
||||
| **PowerShell Windows** | PowerShell Windows patterns. Critical pitfalls, operator syntax, error handling. | `skills/powershell-windows` |
|
||||
| **PPTX (Official)** | "Presentation creation, editing, and analysis. | `skills/pptx-official` |
|
||||
| **Pricing Strategy** | Design pricing, packaging, and monetization strategy for SaaS products. | `skills/pricing-strategy` |
|
||||
| **Prisma Expert** | Prisma ORM expert for schema design, migrations, query optimization, relations modeling. | `skills/prisma-expert` |
|
||||
| **Privilege Escalation Methods** | This skill should be used when the user asks to "escalate privileges", "get root access", "become administrator", "privesc techniques", "abuse sudo", "exploit SUID binaries", "Kerberoasting", "pass-the-ticket", "token impersonation", or needs guidance on post-exploitation privilege escalation for Linux or Windows systems. | `skills/privilege-escalation-methods` |
|
||||
| **Product Toolkit** | Comprehensive toolkit for product managers including RICE prioritization, customer interview analysis, PRD templates, discovery frameworks, and go-to-market strategies. | `skills/product-manager-toolkit` |
|
||||
| **Programmatic SEO** | Build SEO-driven pages at scale using templates and data. | `skills/programmatic-seo` |
|
||||
| **Prompt Caching** | Caching strategies for LLM prompts. Anthropic caching, CAG. | `skills/prompt-caching` |
|
||||
| **Prompt Engineer** | Designing prompts for LLM applications. Structure, evaluation. | `skills/prompt-engineer` |
|
||||
| **Prompt Engineering** | Expert guide on prompt engineering patterns, best practices, and optimization techniques. | `skills/prompt-engineering` |
|
||||
| **Prompt Library** | "Curated collection of high-quality prompts for various use cases. | `skills/prompt-library` |
|
||||
| **Python Patterns** | Python development principles. Framework selection, async patterns, type hints, project structure. | `skills/python-patterns` |
|
||||
| **RAG Engineer** | Building RAG systems. Embedding models, vector databases, chunking. | `skills/rag-engineer` |
|
||||
| **RAG Implementation** | RAG patterns. Chunking, embeddings, vector stores. | `skills/rag-implementation` |
|
||||
| **React Best Practices** | React and Next. | `skills/react-best-practices` |
|
||||
| **React Patterns** | Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices. | `skills/react-patterns` |
|
||||
| **React UI Patterns** | Modern React UI patterns for loading states, error handling, and data fetching. | `skills/react-ui-patterns` |
|
||||
| **Research Engineer** | Academic Research Engineer persona with scientific rigor, zero hallucinations, and optimal language selection for high-precision engineering tasks. | `skills/research-engineer` |
|
||||
| **Receiving Code Review** | Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation. | `skills/receiving-code-review` |
|
||||
| **Red Team Tactics** | Red team tactics principles based on MITRE ATT&CK. Attack phases, detection evasion, reporting. | `skills/red-team-tactics` |
|
||||
| **Remotion Best Practices** | Best practices for Remotion - Video creation in React. Includes 28 modular rules for animations, audio, video, captions, 3D, charts, transitions, and more. | `skills/remotion-best-practices` |
|
||||
| **Red Team Tools and Methodology** | This skill should be used when the user asks to "follow red team methodology", "perform bug bounty hunting", "automate reconnaissance", "hunt for XSS vulnerabilities", "enumerate subdomains", or needs security researcher techniques and tool configurations from top bug bounty hunters. | `skills/red-team-tools` |
|
||||
| **Referral Program** | Design referral programs, affiliate programs, and word-of-mouth strategies. | `skills/referral-program` |
|
||||
| **Requesting Code Review** | Use when completing tasks, implementing major features, or before merging to verify work meets requirements. | `skills/requesting-code-review` |
|
||||
| **Salesforce Development** | Salesforce integration, Apex development, Lightning components. | `skills/salesforce-development` |
|
||||
| **Schema Markup** | Add structured data and JSON-LD schema markup for SEO and rich snippets. | `skills/schema-markup` |
|
||||
| **Scroll Experience** | GSAP/Framer scroll-driven storytelling. Parallax effects. | `skills/scroll-experience` |
|
||||
| **Security Scanning Tools** | This skill should be used when the user asks to "perform vulnerability scanning", "scan networks for open ports", "assess web application security", "scan wireless networks", "detect malware", "check cloud security", or "evaluate system compliance". | `skills/scanning-tools` |
|
||||
| **Segment CDP** | Segment customer data platform. Event tracking, identity resolution. | `skills/segment-cdp` |
|
||||
| **Senior Architect** | Comprehensive software architecture skill for designing scalable, maintainable systems using ReactJS, NextJS, NodeJS, Express, React Native, Swift, Kotlin, Flutter, Postgres, GraphQL, Go, Python. | `skills/senior-architect` |
|
||||
| **Senior Fullstack** | Comprehensive fullstack development skill for building complete web applications with React, Next. | `skills/senior-fullstack` |
|
||||
| **SEO Audit** | Audit technical and on-page SEO issues for better search rankings. | `skills/seo-audit` |
|
||||
| **SEO Fundamentals** | SEO fundamentals, E-E-A-T, Core Web Vitals, and Google algorithm principles. | `skills/seo-fundamentals` |
|
||||
| **Server Management** | Server management principles. Process management, monitoring strategy, and scaling decisions. | `skills/server-management` |
|
||||
| **Shodan Reconnaissance and Pentesting** | This skill should be used when the user asks to "search for exposed devices on the internet," "perform Shodan reconnaissance," "find vulnerable services using Shodan," "scan IP ranges with Shodan," or "discover IoT devices and open ports. | `skills/shodan-reconnaissance` |
|
||||
| **Shopify Apps** | Building Shopify apps. App Bridge, Polaris, webhooks. | `skills/shopify-apps` |
|
||||
| **Shopify Development** | Build Shopify apps, extensions, themes using GraphQL Admin API, Shopify CLI, Polaris UI, and Liquid. Use when user asks about "shopify app", "checkout extension", "shopify theme", "liquid template", "polaris", "shopify graphql", "shopify webhook", or "metafields". | `skills/shopify-development` |
|
||||
| **Signup Flow CRO** | Optimize signup, registration, and trial activation flows for higher conversions. | `skills/signup-flow-cro` |
|
||||
| **Skill Creator** | Guide for creating effective skills. | `skills/skill-creator` |
|
||||
| **Skill Developer** | Create and manage Claude Code skills following Anthropic best practices. | `skills/skill-developer` |
|
||||
| **Slack Bot Builder** | Production Slack bots. Bolt framework, slash commands, modals. | `skills/slack-bot-builder` |
|
||||
| **Slack GIF Creator** | Knowledge and utilities for creating animated GIFs optimized for Slack. | `skills/slack-gif-creator` |
|
||||
| **SMTP Penetration Testing** | This skill should be used when the user asks to "perform SMTP penetration testing", "enumerate email users", "test for open mail relays", "grab SMTP banners", "brute force email credentials", or "assess mail server security". | `skills/smtp-penetration-testing` |
|
||||
| **Social Content** | Create and schedule social media content for LinkedIn, Twitter/X, and other platforms. | `skills/social-content` |
|
||||
| **Software Architecture** | Guide for quality focused software architecture. | `skills/software-architecture` |
|
||||
| **SQL Injection Testing** | This skill should be used when the user asks to "test for SQL injection vulnerabilities", "perform SQLi attacks", "bypass authentication using SQL injection", "extract database information through injection", "detect SQL injection flaws", or "exploit database query vulnerabilities". | `skills/sql-injection-testing` |
|
||||
| **SQLMap Database Penetration Testing** | This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap," "dump tables and columns from a vulnerable database," or "perform automated database penetration testing. | `skills/sqlmap-database-pentesting` |
|
||||
| **SSH Penetration Testing** | This skill should be used when the user asks to "pentest SSH services", "enumerate SSH configurations", "brute force SSH credentials", "exploit SSH vulnerabilities", "perform SSH tunneling", or "audit SSH security". | `skills/ssh-penetration-testing` |
|
||||
| **Stripe Integration** | Stripe patterns. Checkout, subscriptions, payment intents, webhooks. | `skills/stripe-integration` |
|
||||
| **Subagent Driven Dev** | Use when executing implementation plans with independent tasks in the current session. | `skills/subagent-driven-development` |
|
||||
| **Systematic Debugging** | Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes. | `skills/systematic-debugging` |
|
||||
| **Tailwind Patterns** | Tailwind CSS v4 principles. CSS-first configuration, container queries, design token architecture. | `skills/tailwind-patterns` |
|
||||
| **TDD** | Use when implementing any feature or bugfix, before writing implementation code. | `skills/test-driven-development` |
|
||||
| **TDD Workflow** | Test-Driven Development workflow principles. RED-GREEN-REFACTOR cycle. | `skills/tdd-workflow` |
|
||||
| **Telegram Bot Builder** | Building Telegram bots. Bot API, inline mode, payments, Mini Apps. | `skills/telegram-bot-builder` |
|
||||
| **Telegram Mini App** | TON Connect, Telegram Mini Apps, wallet integration. | `skills/telegram-mini-app` |
|
||||
| **Test Fixing** | Run tests and systematically fix all failing tests using smart error grouping. | `skills/test-fixing` |
|
||||
| **Testing Patterns** | Jest testing patterns, factory functions, mocking strategies, and TDD workflow. | `skills/testing-patterns` |
|
||||
| **Theme Factory** | Toolkit for styling artifacts with a theme. | `skills/theme-factory` |
|
||||
| **Top 100 Vulnerabilities** | This skill should be used when the user asks to "identify web application vulnerabilities", "explain common security flaws", "understand vulnerability categories", "learn about injection attacks", "review access control weaknesses", "analyze API security issues", "assess security misconfigurations", "understand client-side vulnerabilities", "examine mobile and IoT security flaws", or "reference the OWASP-aligned vulnerability taxonomy". | `skills/top-web-vulnerabilities` |
|
||||
| **Trigger.dev** | Trigger.dev for serverless background jobs. Long-running tasks. | `skills/trigger-dev` |
|
||||
| **Twilio Communications** | Twilio for SMS, voice, video. Programmable messaging, OTP. | `skills/twilio-communications` |
|
||||
| **TypeScript Expert** | TypeScript expert with deep knowledge of type-level programming, performance optimization, migration strategies. | `skills/typescript-expert` |
|
||||
| **UI/UX Pro Max** | "UI/UX design intelligence. | `skills/ui-ux-pro-max` |
|
||||
| **Upstash QStash** | Upstash QStash for serverless message queues. | `skills/upstash-qstash` |
|
||||
| **Using Git Worktrees** | Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification. | `skills/using-git-worktrees` |
|
||||
| **Using Superpowers** | Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions. | `skills/using-superpowers` |
|
||||
| **Vercel Deployment** | Vercel deployment. Edge functions, preview deployments. | `skills/vercel-deployment` |
|
||||
| **Verification Before Completion** | Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always. | `skills/verification-before-completion` |
|
||||
| **Viral Generator Builder** | Building shareable generators that go viral. | `skills/viral-generator-builder` |
|
||||
| **Voice Agents** | Voice-based AI assistants. Speech-to-text, real-time conversation. | `skills/voice-agents` |
|
||||
| **Voice AI Development** | Voice AI patterns. Wake words, streaming ASR, emotional TTS. | `skills/voice-ai-development` |
|
||||
| **Vulnerability Scanner** | Advanced vulnerability analysis principles. OWASP 2025, Supply Chain Security, attack surface mapping. | `skills/vulnerability-scanner` |
|
||||
| **Web Artifacts** | Suite of tools for creating elaborate, multi-component claude. | `skills/web-artifacts-builder` |
|
||||
| **Web Design Guidelines** | Review UI code for Web Interface Guidelines compliance. | `skills/web-design-guidelines` |
|
||||
| **Webapp Testing** | Toolkit for interacting with and testing local web applications using Playwright. | `skills/webapp-testing` |
|
||||
| **Windows Privilege Escalation** | This skill should be used when the user asks to "escalate privileges on Windows," "find Windows privesc vectors," "enumerate Windows for privilege escalation," "exploit Windows misconfigurations," or "perform post-exploitation privilege escalation. | `skills/windows-privilege-escalation` |
|
||||
| **Wireshark Network Traffic Analysis** | This skill should be used when the user asks to "analyze network traffic with Wireshark", "capture packets for troubleshooting", "filter PCAP files", "follow TCP/UDP streams", "detect network anomalies", "investigate suspicious traffic", or "perform protocol analysis". | `skills/wireshark-analysis` |
|
||||
| **WordPress Penetration Testing** | This skill should be used when the user asks to "pentest WordPress sites", "scan WordPress for vulnerabilities", "enumerate WordPress users, themes, or plugins", "exploit WordPress vulnerabilities", or "use WPScan". | `skills/wordpress-penetration-testing` |
|
||||
| **Workflow Automation** | "Design and implement automated workflows combining visual logic with custom code. | `skills/workflow-automation` |
|
||||
| **Writing Plans** | Use when you have a spec or requirements for a multi-step task, before touching code. | `skills/writing-plans` |
|
||||
| **Writing Skills** | Use when creating new skills, editing existing skills, or verifying skills work before deployment. | `skills/writing-skills` |
|
||||
| **XLSX (Official)** | "Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. | `skills/xlsx-official` |
|
||||
| **Zapier/Make Patterns** | No-code automation. Zapier, Make, n8n workflows. | `skills/zapier-make-patterns` |
|
||||
|
||||
> [!TIP]
|
||||
> Use the `validate_skills.py` script in the `scripts/` directory to ensure all skills are properly formatted and ready for use.
|
||||
|
||||
---
|
||||
| Skill Name | Risk | Description | Path |
|
||||
| :-------------------------------------------------- | :--- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------- |
|
||||
| **2d-games** | ⚪ | 2D game development principles. Sprites, tilemaps, physics, camera. | `skills/game-development/2d-games` |
|
||||
| **3d-games** | ⚪ | 3D game development principles. Rendering, shaders, physics, cameras. | `skills/game-development/3d-games` |
|
||||
| **3d-web-experience** | ⚪ | Expert in building 3D experiences for the web - Three.js, React Three Fiber, Spline, WebGL, and interactive 3D scenes. Covers product configurators, 3D portfolios, immersive websites, and bringing depth to web experiences. Use when: 3D website, three.js, WebGL, react three fiber, 3D experience. | `skills/3d-web-experience` |
|
||||
| **ab-test-setup** | ⚪ | Structured guide for setting up A/B tests with mandatory gates for hypothesis, metrics, and execution readiness. | `skills/ab-test-setup` |
|
||||
| **Active Directory Attacks** | ⚪ | This skill should be used when the user asks to "attack Active Directory", "exploit AD", "Kerberoasting", "DCSync", "pass-the-hash", "BloodHound enumeration", "Golden Ticket", "Silver Ticket", "AS-REP roasting", "NTLM relay", or needs guidance on Windows domain penetration testing. | `skills/active-directory-attacks` |
|
||||
| **address-github-comments** | ⚪ | Use when you need to address review or issue comments on an open GitHub Pull Request using the gh CLI. | `skills/address-github-comments` |
|
||||
| **agent-evaluation** | ⚪ | Testing and benchmarking LLM agents including behavioral testing, capability assessment, reliability metrics, and production monitoring—where even top agents achieve less than 50% on real-world benchmarks Use when: agent testing, agent evaluation, benchmark agents, agent reliability, test agent. | `skills/agent-evaluation` |
|
||||
| **agent-manager-skill** | ⚪ | Manage multiple local CLI agents via tmux sessions (start/stop/monitor/assign) with cron-friendly scheduling. | `skills/agent-manager-skill` |
|
||||
| **agent-memory-mcp** | ⚪ | A hybrid memory system that provides persistent, searchable knowledge management for AI agents (Architecture, Patterns, Decisions). | `skills/agent-memory-mcp` |
|
||||
| **agent-memory-systems** | ⚪ | Memory is the cornerstone of intelligent agents. Without it, every interaction starts from zero. This skill covers the architecture of agent memory: short-term (context window), long-term (vector stores), and the cognitive architectures that organize them. Key insight: Memory isn't just storage - it's retrieval. A million stored facts mean nothing if you can't find the right one. Chunking, embedding, and retrieval strategies determine whether your agent remembers or forgets. The field is fragm | `skills/agent-memory-systems` |
|
||||
| **agent-tool-builder** | ⚪ | Tools are how AI agents interact with the world. A well-designed tool is the difference between an agent that works and one that hallucinates, fails silently, or costs 10x more tokens than necessary. This skill covers tool design from schema to error handling. JSON Schema best practices, description writing that actually helps the LLM, validation, and the emerging MCP standard that's becoming the lingua franca for AI tools. Key insight: Tool descriptions are more important than tool implementa | `skills/agent-tool-builder` |
|
||||
| **ai-agents-architect** | ⚪ | Expert in designing and building autonomous AI agents. Masters tool use, memory systems, planning strategies, and multi-agent orchestration. Use when: build agent, AI agent, autonomous agent, tool use, function calling. | `skills/ai-agents-architect` |
|
||||
| **ai-product** | ⚪ | Every product will be AI-powered. The question is whether you'll build it right or ship a demo that falls apart in production. This skill covers LLM integration patterns, RAG architecture, prompt engineering that scales, AI UX that users trust, and cost optimization that doesn't bankrupt you. Use when: keywords, file_patterns, code_patterns. | `skills/ai-product` |
|
||||
| **ai-wrapper-product** | ⚪ | Expert in building products that wrap AI APIs (OpenAI, Anthropic, etc.) into focused tools people will pay for. Not just 'ChatGPT but different' - products that solve specific problems with AI. Covers prompt engineering for products, cost management, rate limiting, and building defensible AI businesses. Use when: AI wrapper, GPT product, AI tool, wrap AI, AI SaaS. | `skills/ai-wrapper-product` |
|
||||
| **algolia-search** | ⚪ | Expert patterns for Algolia search implementation, indexing strategies, React InstantSearch, and relevance tuning Use when: adding search to, algolia, instantsearch, search api, search functionality. | `skills/algolia-search` |
|
||||
| **algorithmic-art** | ⚪ | Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations. | `skills/algorithmic-art` |
|
||||
| **analytics-tracking** | ⚪ | Design, audit, and improve analytics tracking systems that produce reliable, decision-ready data. Use when the user wants to set up, fix, or evaluate analytics tracking (GA4, GTM, product analytics, events, conversions, UTMs). This skill focuses on measurement strategy, signal quality, and validation— not just firing events. | `skills/analytics-tracking` |
|
||||
| **API Fuzzing for Bug Bounty** | ⚪ | This skill should be used when the user asks to "test API security", "fuzz APIs", "find IDOR vulnerabilities", "test REST API", "test GraphQL", "API penetration testing", "bug bounty API testing", or needs guidance on API security assessment techniques. | `skills/api-fuzzing-bug-bounty` |
|
||||
| **api-documentation-generator** | ⚪ | Generate comprehensive, developer-friendly API documentation from code, including endpoints, parameters, examples, and best practices | `skills/api-documentation-generator` |
|
||||
| **api-patterns** | ⚪ | API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning, pagination. | `skills/api-patterns` |
|
||||
| **api-security-best-practices** | ⚪ | Implement secure API design patterns including authentication, authorization, input validation, rate limiting, and protection against common API vulnerabilities | `skills/api-security-best-practices` |
|
||||
| **app-builder** | ⚪ | Main application building orchestrator. Creates full-stack applications from natural language requests. Determines project type, selects tech stack, coordinates agents. | `skills/app-builder` |
|
||||
| **app-store-optimization** | ⚪ | Complete App Store Optimization (ASO) toolkit for researching, optimizing, and tracking mobile app performance on Apple App Store and Google Play Store | `skills/app-store-optimization` |
|
||||
| **architecture** | ⚪ | Architectural decision-making framework. Requirements analysis, trade-off evaluation, ADR documentation. Use when making architecture decisions or analyzing system design. | `skills/architecture` |
|
||||
| **autonomous-agent-patterns** | ⚪ | Design patterns for building autonomous coding agents. Covers tool integration, permission systems, browser automation, and human-in-the-loop workflows. Use when building AI agents, designing tool APIs, implementing permission systems, or creating autonomous coding assistants. | `skills/autonomous-agent-patterns` |
|
||||
| **autonomous-agents** | ⚪ | Autonomous agents are AI systems that can independently decompose goals, plan actions, execute tools, and self-correct without constant human guidance. The challenge isn't making them capable - it's making them reliable. Every extra decision multiplies failure probability. This skill covers agent loops (ReAct, Plan-Execute), goal decomposition, reflection patterns, and production reliability. Key insight: compounding error rates kill autonomous agents. A 95% success rate per step drops to 60% b | `skills/autonomous-agents` |
|
||||
| **avalonia-layout-zafiro** | ⚪ | Guidelines for modern Avalonia UI layout using Zafiro.Avalonia, emphasizing shared styles, generic components, and avoiding XAML redundancy. | `skills/avalonia-layout-zafiro` |
|
||||
| **avalonia-viewmodels-zafiro** | ⚪ | Optimal ViewModel and Wizard creation patterns for Avalonia using Zafiro and ReactiveUI. | `skills/avalonia-viewmodels-zafiro` |
|
||||
| **avalonia-zafiro-development** | ⚪ | Mandatory skills, conventions, and behavioral rules for Avalonia UI development using the Zafiro toolkit. | `skills/avalonia-zafiro-development` |
|
||||
| **AWS Penetration Testing** | ⚪ | This skill should be used when the user asks to "pentest AWS", "test AWS security", "enumerate IAM", "exploit cloud infrastructure", "AWS privilege escalation", "S3 bucket testing", "metadata SSRF", "Lambda exploitation", or needs guidance on Amazon Web Services security assessment. | `skills/aws-penetration-testing` |
|
||||
| **aws-serverless** | ⚪ | Specialized skill for building production-ready serverless applications on AWS. Covers Lambda functions, API Gateway, DynamoDB, SQS/SNS event-driven patterns, SAM/CDK deployment, and cold start optimization. | `skills/aws-serverless` |
|
||||
| **azure-functions** | ⚪ | Expert patterns for Azure Functions development including isolated worker model, Durable Functions orchestration, cold start optimization, and production patterns. Covers .NET, Python, and Node.js programming models. Use when: azure function, azure functions, durable functions, azure serverless, function app. | `skills/azure-functions` |
|
||||
| **backend-dev-guidelines** | ⚪ | Opinionated backend development standards for Node.js + Express + TypeScript microservices. Covers layered architecture, BaseController pattern, dependency injection, Prisma repositories, Zod validation, unifiedConfig, Sentry error tracking, async safety, and testing discipline. | `skills/backend-dev-guidelines` |
|
||||
| **backend-patterns** | ⚪ | Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes. | `skills/cc-skill-backend-patterns` |
|
||||
| **bash-linux** | ⚪ | Bash/Linux terminal patterns. Critical commands, piping, error handling, scripting. Use when working on macOS or Linux systems. | `skills/bash-linux` |
|
||||
| **behavioral-modes** | ⚪ | AI operational modes (brainstorm, implement, debug, review, teach, ship, orchestrate). Use to adapt behavior based on task type. | `skills/behavioral-modes` |
|
||||
| **blockrun** | ⚪ | Use when user needs capabilities Claude lacks (image generation, real-time X/Twitter data) or explicitly requests external models ("blockrun", "use grok", "use gpt", "dall-e", "deepseek") | `skills/blockrun` |
|
||||
| **brainstorming** | ⚪ | Use this skill before any creative or constructive work (features, components, architecture, behavior changes, or functionality). This skill transforms vague ideas into validated designs through disciplined, incremental reasoning and collaboration. | `skills/brainstorming` |
|
||||
| **brand-guidelines** | ⚪ | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply. | `skills/brand-guidelines-anthropic` |
|
||||
| **brand-guidelines** | ⚪ | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply. | `skills/brand-guidelines-community` |
|
||||
| **Broken Authentication Testing** | ⚪ | This skill should be used when the user asks to "test for broken authentication vulnerabilities", "assess session management security", "perform credential stuffing tests", "evaluate password policies", "test for session fixation", or "identify authentication bypass flaws". It provides comprehensive techniques for identifying authentication and session management weaknesses in web applications. | `skills/broken-authentication` |
|
||||
| **browser-automation** | ⚪ | Browser automation powers web testing, scraping, and AI agent interactions. The difference between a flaky script and a reliable system comes down to understanding selectors, waiting strategies, and anti-detection patterns. This skill covers Playwright (recommended) and Puppeteer, with patterns for testing, scraping, and agentic browser control. Key insight: Playwright won the framework war. Unless you need Puppeteer's stealth ecosystem or are Chrome-only, Playwright is the better choice in 202 | `skills/browser-automation` |
|
||||
| **browser-extension-builder** | ⚪ | Expert in building browser extensions that solve real problems - Chrome, Firefox, and cross-browser extensions. Covers extension architecture, manifest v3, content scripts, popup UIs, monetization strategies, and Chrome Web Store publishing. Use when: browser extension, chrome extension, firefox addon, extension, manifest v3. | `skills/browser-extension-builder` |
|
||||
| **bullmq-specialist** | ⚪ | BullMQ expert for Redis-backed job queues, background processing, and reliable async execution in Node.js/TypeScript applications. Use when: bullmq, bull queue, redis queue, background job, job queue. | `skills/bullmq-specialist` |
|
||||
| **bun-development** | ⚪ | Modern JavaScript/TypeScript development with Bun runtime. Covers package management, bundling, testing, and migration from Node.js. Use when working with Bun, optimizing JS/TS development speed, or migrating from Node.js to Bun. | `skills/bun-development` |
|
||||
| **Burp Suite Web Application Testing** | ⚪ | This skill should be used when the user asks to "intercept HTTP traffic", "modify web requests", "use Burp Suite for testing", "perform web vulnerability scanning", "test with Burp Repeater", "analyze HTTP history", or "configure proxy for web testing". It provides comprehensive guidance for using Burp Suite's core features for web application security testing. | `skills/burp-suite-testing` |
|
||||
| **busybox-on-windows** | ⚪ | How to use a Win32 build of BusyBox to run many of the standard UNIX command line tools on Windows. | `skills/busybox-on-windows` |
|
||||
| **canvas-design** | ⚪ | Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations. | `skills/canvas-design` |
|
||||
| **cc-skill-continuous-learning** | ⚪ | Development skill from everything-claude-code | `skills/cc-skill-continuous-learning` |
|
||||
| **cc-skill-project-guidelines-example** | ⚪ | Project Guidelines Skill (Example) | `skills/cc-skill-project-guidelines-example` |
|
||||
| **cc-skill-strategic-compact** | ⚪ | Development skill from everything-claude-code | `skills/cc-skill-strategic-compact` |
|
||||
| **Claude Code Guide** | ⚪ | Master guide for using Claude Code effectively. Includes configuration templates, prompting strategies "Thinking" keywords, debugging techniques, and best practices for interacting with the agent. | `skills/claude-code-guide` |
|
||||
| **clean-code** | ⚪ | Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments | `skills/clean-code` |
|
||||
| **clerk-auth** | ⚪ | Expert patterns for Clerk auth implementation, middleware, organizations, webhooks, and user sync Use when: adding authentication, clerk auth, user authentication, sign in, sign up. | `skills/clerk-auth` |
|
||||
| **clickhouse-io** | ⚪ | ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads. | `skills/cc-skill-clickhouse-io` |
|
||||
| **Cloud Penetration Testing** | ⚪ | This skill should be used when the user asks to "perform cloud penetration testing", "assess Azure or AWS or GCP security", "enumerate cloud resources", "exploit cloud misconfigurations", "test O365 security", "extract secrets from cloud environments", or "audit cloud infrastructure". It provides comprehensive techniques for security assessment across major cloud platforms. | `skills/cloud-penetration-testing` |
|
||||
| **code-review-checklist** | ⚪ | Comprehensive checklist for conducting thorough code reviews covering functionality, security, performance, and maintainability | `skills/code-review-checklist` |
|
||||
| **codex-review** | ⚪ | Professional code review with auto CHANGELOG generation, integrated with Codex AI | `skills/codex-review` |
|
||||
| **coding-standards** | ⚪ | Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development. | `skills/cc-skill-coding-standards` |
|
||||
| **competitor-alternatives** | ⚪ | When the user wants to create competitor comparison or alternative pages for SEO and sales enablement. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' or 'competitive landing pages.' Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. Emphasizes deep research, modular content architecture, and varied section types beyond feature tables. | `skills/competitor-alternatives` |
|
||||
| **computer-use-agents** | ⚪ | Build AI agents that interact with computers like humans do - viewing screens, moving cursors, clicking buttons, and typing text. Covers Anthropic's Computer Use, OpenAI's Operator/CUA, and open-source alternatives. Critical focus on sandboxing, security, and handling the unique challenges of vision-based control. Use when: computer use, desktop automation agent, screen control AI, vision-based agent, GUI automation. | `skills/computer-use-agents` |
|
||||
| **concise-planning** | ⚪ | Use when a user asks for a plan for a coding task, to generate a clear, actionable, and atomic checklist. | `skills/concise-planning` |
|
||||
| **content-creator** | ⚪ | Create SEO-optimized marketing content with consistent brand voice. Includes brand voice analyzer, SEO optimizer, content frameworks, and social media templates. Use when writing blog posts, creating social media content, analyzing brand voice, optimizing SEO, planning content calendars, or when user mentions content creation, brand voice, SEO optimization, social media marketing, or content strategy. | `skills/content-creator` |
|
||||
| **context-window-management** | ⚪ | Strategies for managing LLM context windows including summarization, trimming, routing, and avoiding context rot Use when: context window, token limit, context management, context engineering, long context. | `skills/context-window-management` |
|
||||
| **context7-auto-research** | ⚪ | Automatically fetch latest library/framework documentation for Claude Code via Context7 API | `skills/context7-auto-research` |
|
||||
| **conversation-memory** | ⚪ | Persistent memory systems for LLM conversations including short-term, long-term, and entity-based memory Use when: conversation memory, remember, memory persistence, long-term memory, chat history. | `skills/conversation-memory` |
|
||||
| **copy-editing** | ⚪ | When the user wants to edit, review, or improve existing marketing copy. Also use when the user mentions 'edit this copy,' 'review my copy,' 'copy feedback,' 'proofread,' 'polish this,' 'make this better,' or 'copy sweep.' This skill provides a systematic approach to editing marketing copy through multiple focused passes. | `skills/copy-editing` |
|
||||
| **copywriting** | ⚪ | Use this skill when writing, rewriting, or improving marketing copy for any page (homepage, landing page, pricing, feature, product, or about page). This skill produces clear, compelling, and testable copy while enforcing alignment, honesty, and conversion best practices. | `skills/copywriting` |
|
||||
| **core-components** | ⚪ | Core component library and design system patterns. Use when building UI, using design tokens, or working with the component library. | `skills/core-components` |
|
||||
| **crewai** | ⚪ | Expert in CrewAI - the leading role-based multi-agent framework used by 60% of Fortune 500 companies. Covers agent design with roles and goals, task definition, crew orchestration, process types (sequential, hierarchical, parallel), memory systems, and flows for complex workflows. Essential for building collaborative AI agent teams. Use when: crewai, multi-agent team, agent roles, crew of agents, role-based agents. | `skills/crewai` |
|
||||
| **Cross-Site Scripting and HTML Injection Testing** | ⚪ | This skill should be used when the user asks to "test for XSS vulnerabilities", "perform cross-site scripting attacks", "identify HTML injection flaws", "exploit client-side injection vulnerabilities", "steal cookies via XSS", or "bypass content security policies". It provides comprehensive techniques for detecting, exploiting, and understanding XSS and HTML injection attack vectors in web applications. | `skills/xss-html-injection` |
|
||||
| **d3-viz** | ⚪ | Creating interactive data visualisations using d3.js. This skill should be used when creating custom charts, graphs, network diagrams, geographic visualisations, or any complex SVG-based data visualisation that requires fine-grained control over visual elements, transitions, or interactions. Use this for bespoke visualisations beyond standard charting libraries, whether in React, Vue, Svelte, vanilla JavaScript, or any other environment. | `skills/claude-d3js-skill` |
|
||||
| **daily-news-report** | ⚪ | 基于预设 URL 列表抓取内容,筛选高质量技术信息并生成每日 Markdown 报告。 | `skills/daily-news-report` |
|
||||
| **database-design** | ⚪ | Database design principles and decision-making. Schema design, indexing strategy, ORM selection, serverless databases. | `skills/database-design` |
|
||||
| **deployment-procedures** | ⚪ | Production deployment principles and decision-making. Safe deployment workflows, rollback strategies, and verification. Teaches thinking, not scripts. | `skills/deployment-procedures` |
|
||||
| **design-orchestration** | ⚪ | Orchestrates design workflows by routing work through brainstorming, multi-agent review, and execution readiness in the correct order. Prevents premature implementation, skipped validation, and unreviewed high-risk designs. | `skills/design-orchestration` |
|
||||
| **discord-bot-architect** | ⚪ | Specialized skill for building production-ready Discord bots. Covers Discord.js (JavaScript) and Pycord (Python), gateway intents, slash commands, interactive components, rate limiting, and sharding. | `skills/discord-bot-architect` |
|
||||
| **dispatching-parallel-agents** | ⚪ | Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies | `skills/dispatching-parallel-agents` |
|
||||
| **doc-coauthoring** | ⚪ | Guide users through a structured workflow for co-authoring documentation. Use when user wants to write documentation, proposals, technical specs, decision docs, or similar structured content. This workflow helps users efficiently transfer context, refine content through iteration, and verify the doc works for readers. Trigger when user mentions writing docs, creating proposals, drafting specs, or similar documentation tasks. | `skills/doc-coauthoring` |
|
||||
| **docker-expert** | ⚪ | Docker containerization expert with deep knowledge of multi-stage builds, image optimization, container security, Docker Compose orchestration, and production deployment patterns. Use PROACTIVELY for Dockerfile optimization, container issues, image size problems, security hardening, networking, and orchestration challenges. | `skills/docker-expert` |
|
||||
| **documentation-templates** | ⚪ | Documentation templates and structure guidelines. README, API docs, code comments, and AI-friendly documentation. | `skills/documentation-templates` |
|
||||
| **docx** | ⚪ | Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks | `skills/docx-official` |
|
||||
| **email-sequence** | ⚪ | When the user wants to create or optimize an email sequence, drip campaign, automated email flow, or lifecycle email program. Also use when the user mentions "email sequence," "drip campaign," "nurture sequence," "onboarding emails," "welcome sequence," "re-engagement emails," "email automation," or "lifecycle emails." For in-app onboarding, see onboarding-cro. | `skills/email-sequence` |
|
||||
| **email-systems** | ⚪ | Email has the highest ROI of any marketing channel. $36 for every $1 spent. Yet most startups treat it as an afterthought - bulk blasts, no personalization, landing in spam folders. This skill covers transactional email that works, marketing automation that converts, deliverability that reaches inboxes, and the infrastructure decisions that scale. Use when: keywords, file_patterns, code_patterns. | `skills/email-systems` |
|
||||
| **environment-setup-guide** | ⚪ | Guide developers through setting up development environments with proper tools, dependencies, and configurations | `skills/environment-setup-guide` |
|
||||
| **Ethical Hacking Methodology** | ⚪ | This skill should be used when the user asks to "learn ethical hacking", "understand penetration testing lifecycle", "perform reconnaissance", "conduct security scanning", "exploit vulnerabilities", or "write penetration test reports". It provides comprehensive ethical hacking methodology and techniques. | `skills/ethical-hacking-methodology` |
|
||||
| **exa-search** | ⚪ | Semantic search, similar content discovery, and structured research using Exa API | `skills/exa-search` |
|
||||
| **executing-plans** | ⚪ | Use when you have a written implementation plan to execute in a separate session with review checkpoints | `skills/executing-plans` |
|
||||
| **File Path Traversal Testing** | ⚪ | This skill should be used when the user asks to "test for directory traversal", "exploit path traversal vulnerabilities", "read arbitrary files through web applications", "find LFI vulnerabilities", or "access files outside web root". It provides comprehensive file path traversal attack and testing methodologies. | `skills/file-path-traversal` |
|
||||
| **file-organizer** | ⚪ | Intelligently organizes files and folders by understanding context, finding duplicates, and suggesting better organizational structures. Use when user wants to clean up directories, organize downloads, remove duplicates, or restructure projects. | `skills/file-organizer` |
|
||||
| **file-uploads** | ⚪ | Expert at handling file uploads and cloud storage. Covers S3, Cloudflare R2, presigned URLs, multipart uploads, and image optimization. Knows how to handle large files without blocking. Use when: file upload, S3, R2, presigned URL, multipart. | `skills/file-uploads` |
|
||||
| **finishing-a-development-branch** | ⚪ | Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup | `skills/finishing-a-development-branch` |
|
||||
| **firebase** | ⚪ | Firebase gives you a complete backend in minutes - auth, database, storage, functions, hosting. But the ease of setup hides real complexity. Security rules are your last line of defense, and they're often wrong. Firestore queries are limited, and you learn this after you've designed your data model. This skill covers Firebase Authentication, Firestore, Realtime Database, Cloud Functions, Cloud Storage, and Firebase Hosting. Key insight: Firebase is optimized for read-heavy, denormalized data. I | `skills/firebase` |
|
||||
| **firecrawl-scraper** | ⚪ | Deep web scraping, screenshots, PDF parsing, and website crawling using Firecrawl API | `skills/firecrawl-scraper` |
|
||||
| **form-cro** | ⚪ | Optimize any form that is NOT signup or account registration — including lead capture, contact, demo request, application, survey, quote, and checkout forms. Use when the goal is to increase form completion rate, reduce friction, or improve lead quality without breaking compliance or downstream workflows. | `skills/form-cro` |
|
||||
| **free-tool-strategy** | ⚪ | When the user wants to plan, evaluate, or build a free tool for marketing purposes — lead generation, SEO value, or brand awareness. Also use when the user mentions "engineering as marketing," "free tool," "marketing tool," "calculator," "generator," "interactive tool," "lead gen tool," "build a tool for leads," or "free resource." This skill bridges engineering and marketing — useful for founders and technical marketers. | `skills/free-tool-strategy` |
|
||||
| **frontend-design** | ⚪ | Create distinctive, production-grade frontend interfaces with intentional aesthetics, high craft, and non-generic visual identity. Use when building or styling web UIs, components, pages, dashboards, or frontend applications. | `skills/frontend-design` |
|
||||
| **frontend-dev-guidelines** | ⚪ | Opinionated frontend development standards for modern React + TypeScript applications. Covers Suspense-first data fetching, lazy loading, feature-based architecture, MUI v7 styling, TanStack Router, performance optimization, and strict TypeScript practices. | `skills/frontend-dev-guidelines` |
|
||||
| **frontend-patterns** | ⚪ | Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices. | `skills/cc-skill-frontend-patterns` |
|
||||
| **game-art** | ⚪ | Game art principles. Visual style selection, asset pipeline, animation workflow. | `skills/game-development/game-art` |
|
||||
| **game-audio** | ⚪ | Game audio principles. Sound design, music integration, adaptive audio systems. | `skills/game-development/game-audio` |
|
||||
| **game-design** | ⚪ | Game design principles. GDD structure, balancing, player psychology, progression. | `skills/game-development/game-design` |
|
||||
| **game-development** | ⚪ | Game development orchestrator. Routes to platform-specific skills based on project needs. | `skills/game-development` |
|
||||
| **gcp-cloud-run** | ⚪ | Specialized skill for building production-ready serverless applications on GCP. Covers Cloud Run services (containerized), Cloud Run Functions (event-driven), cold start optimization, and event-driven architecture with Pub/Sub. | `skills/gcp-cloud-run` |
|
||||
| **geo-fundamentals** | ⚪ | Generative Engine Optimization for AI search engines (ChatGPT, Claude, Perplexity). | `skills/geo-fundamentals` |
|
||||
| **git-pushing** | ⚪ | Stage, commit, and push git changes with conventional commit messages. Use when user wants to commit and push changes, mentions pushing to remote, or asks to save and push their work. Also activates when user says "push changes", "commit and push", "push this", "push to github", or similar git workflow requests. | `skills/git-pushing` |
|
||||
| **github-workflow-automation** | ⚪ | Automate GitHub workflows with AI assistance. Includes PR reviews, issue triage, CI/CD integration, and Git operations. Use when automating GitHub workflows, setting up PR review automation, creating GitHub Actions, or triaging issues. | `skills/github-workflow-automation` |
|
||||
| **graphql** | ⚪ | GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully. | `skills/graphql` |
|
||||
| **HTML Injection Testing** | ⚪ | This skill should be used when the user asks to "test for HTML injection", "inject HTML into web pages", "perform HTML injection attacks", "deface web applications", or "test content injection vulnerabilities". It provides comprehensive HTML injection attack techniques and testing methodologies. | `skills/html-injection-testing` |
|
||||
| **hubspot-integration** | ⚪ | Expert patterns for HubSpot CRM integration including OAuth authentication, CRM objects, associations, batch operations, webhooks, and custom objects. Covers Node.js and Python SDKs. Use when: hubspot, hubspot api, hubspot crm, hubspot integration, contacts api. | `skills/hubspot-integration` |
|
||||
| **i18n-localization** | ⚪ | Internationalization and localization patterns. Detecting hardcoded strings, managing translations, locale files, RTL support. | `skills/i18n-localization` |
|
||||
| **IDOR Vulnerability Testing** | ⚪ | This skill should be used when the user asks to "test for insecure direct object references," "find IDOR vulnerabilities," "exploit broken access control," "enumerate user IDs or object references," or "bypass authorization to access other users' data." It provides comprehensive guidance for detecting, exploiting, and remediating IDOR vulnerabilities in web applications. | `skills/idor-testing` |
|
||||
| **inngest** | ⚪ | Inngest expert for serverless-first background jobs, event-driven workflows, and durable execution without managing queues or workers. Use when: inngest, serverless background job, event-driven workflow, step function, durable execution. | `skills/inngest` |
|
||||
| **interactive-portfolio** | ⚪ | Expert in building portfolios that actually land jobs and clients - not just showing work, but creating memorable experiences. Covers developer portfolios, designer portfolios, creative portfolios, and portfolios that convert visitors into opportunities. Use when: portfolio, personal website, showcase work, developer portfolio, designer portfolio. | `skills/interactive-portfolio` |
|
||||
| **internal-comms** | ⚪ | A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.). | `skills/internal-comms-anthropic` |
|
||||
| **internal-comms** | ⚪ | A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.). | `skills/internal-comms-community` |
|
||||
| **javascript-mastery** | ⚪ | Comprehensive JavaScript reference covering 33+ essential concepts every developer should know. From fundamentals like primitives and closures to advanced patterns like async/await and functional programming. Use when explaining JS concepts, debugging JavaScript issues, or teaching JavaScript fundamentals. | `skills/javascript-mastery` |
|
||||
| **kaizen** | ⚪ | Guide for continuous improvement, error proofing, and standardization. Use this skill when the user wants to improve code quality, refactor, or discuss process improvements. | `skills/kaizen` |
|
||||
| **langfuse** | ⚪ | Expert in Langfuse - the open-source LLM observability platform. Covers tracing, prompt management, evaluation, datasets, and integration with LangChain, LlamaIndex, and OpenAI. Essential for debugging, monitoring, and improving LLM applications in production. Use when: langfuse, llm observability, llm tracing, prompt management, llm evaluation. | `skills/langfuse` |
|
||||
| **langgraph** | ⚪ | Expert in LangGraph - the production-grade framework for building stateful, multi-actor AI applications. Covers graph construction, state management, cycles and branches, persistence with checkpointers, human-in-the-loop patterns, and the ReAct agent pattern. Used in production at LinkedIn, Uber, and 400+ companies. This is LangChain's recommended approach for building agents. Use when: langgraph, langchain agent, stateful agent, agent graph, react agent. | `skills/langgraph` |
|
||||
| **last30days** | ⚪ | Research a topic from the last 30 days on Reddit + X + Web, become an expert, and write copy-paste-ready prompts for the user's target tool. | `skills/last30days` |
|
||||
| **launch-strategy** | ⚪ | When the user wants to plan a product launch, feature announcement, or release strategy. Also use when the user mentions 'launch,' 'Product Hunt,' 'feature release,' 'announcement,' 'go-to-market,' 'beta launch,' 'early access,' 'waitlist,' or 'product update.' This skill covers phased launches, channel strategy, and ongoing launch momentum. | `skills/launch-strategy` |
|
||||
| **lint-and-validate** | ⚪ | Automatic quality control, linting, and static analysis procedures. Use after every code modification to ensure syntax correctness and project standards. Triggers onKeywords: lint, format, check, validate, types, static analysis. | `skills/lint-and-validate` |
|
||||
| **Linux Privilege Escalation** | ⚪ | This skill should be used when the user asks to "escalate privileges on Linux", "find privesc vectors on Linux systems", "exploit sudo misconfigurations", "abuse SUID binaries", "exploit cron jobs for root access", "enumerate Linux systems for privilege escalation", or "gain root access from low-privilege shell". It provides comprehensive techniques for identifying and exploiting privilege escalation paths on Linux systems. | `skills/linux-privilege-escalation` |
|
||||
| **Linux Production Shell Scripts** | ⚪ | This skill should be used when the user asks to "create bash scripts", "automate Linux tasks", "monitor system resources", "backup files", "manage users", or "write production shell scripts". It provides ready-to-use shell script templates for system administration. | `skills/linux-shell-scripting` |
|
||||
| **llm-app-patterns** | ⚪ | Production-ready patterns for building LLM applications. Covers RAG pipelines, agent architectures, prompt IDEs, and LLMOps monitoring. Use when designing AI applications, implementing RAG, building agents, or setting up LLM observability. | `skills/llm-app-patterns` |
|
||||
| **loki-mode** | ⚪ | Multi-agent autonomous startup system for Claude Code. Triggers on "Loki Mode". Orchestrates 100+ specialized agents across engineering, QA, DevOps, security, data/ML, business operations, marketing, HR, and customer success. Takes PRD to fully deployed, revenue-generating product with zero human intervention. Features Task tool for subagent dispatch, parallel code review with 3 specialized reviewers, severity-based issue triage, distributed task queue with dead letter handling, automatic deployment to cloud providers, A/B testing, customer feedback loops, incident response, circuit breakers, and self-healing. Handles rate limits via distributed state checkpoints and auto-resume with exponential backoff. Requires --dangerously-skip-permissions flag. | `skills/loki-mode` |
|
||||
| **marketing-ideas** | ⚪ | Provide proven marketing strategies and growth ideas for SaaS and software products, prioritized using a marketing feasibility scoring system. | `skills/marketing-ideas` |
|
||||
| **marketing-psychology** | ⚪ | Apply behavioral science and mental models to marketing decisions, prioritized using a psychological leverage and feasibility scoring system. | `skills/marketing-psychology` |
|
||||
| **mcp-builder** | ⚪ | Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK). | `skills/mcp-builder` |
|
||||
| **Metasploit Framework** | ⚪ | This skill should be used when the user asks to "use Metasploit for penetration testing", "exploit vulnerabilities with msfconsole", "create payloads with msfvenom", "perform post-exploitation", "use auxiliary modules for scanning", or "develop custom exploits". It provides comprehensive guidance for leveraging the Metasploit Framework in security assessments. | `skills/metasploit-framework` |
|
||||
| **micro-saas-launcher** | ⚪ | Expert in launching small, focused SaaS products fast - the indie hacker approach to building profitable software. Covers idea validation, MVP development, pricing, launch strategies, and growing to sustainable revenue. Ship in weeks, not months. Use when: micro saas, indie hacker, small saas, side project, saas mvp. | `skills/micro-saas-launcher` |
|
||||
| **mobile-design** | ⚪ | Mobile-first design and engineering doctrine for iOS and Android apps. Covers touch interaction, performance, platform conventions, offline behavior, and mobile-specific decision-making. Teaches principles and constraints, not fixed layouts. Use for React Native, Flutter, or native mobile apps. | `skills/mobile-design` |
|
||||
| **mobile-games** | ⚪ | Mobile game development principles. Touch input, battery, performance, app stores. | `skills/game-development/mobile-games` |
|
||||
| **moodle-external-api-development** | ⚪ | Create custom external web service APIs for Moodle LMS. Use when implementing web services for course management, user tracking, quiz operations, or custom plugin functionality. Covers parameter validation, database operations, error handling, service registration, and Moodle coding standards. | `skills/moodle-external-api-development` |
|
||||
| **multi-agent-brainstorming** | ⚪ | Use this skill when a design or idea requires higher confidence, risk reduction, or formal review. This skill orchestrates a structured, sequential multi-agent design review where each agent has a strict, non-overlapping role. It prevents blind spots, false confidence, and premature convergence. | `skills/multi-agent-brainstorming` |
|
||||
| **multiplayer** | ⚪ | Multiplayer game development principles. Architecture, networking, synchronization. | `skills/game-development/multiplayer` |
|
||||
| **neon-postgres** | ⚪ | Expert patterns for Neon serverless Postgres, branching, connection pooling, and Prisma/Drizzle integration Use when: neon database, serverless postgres, database branching, neon postgres, postgres serverless. | `skills/neon-postgres` |
|
||||
| **nestjs-expert** | ⚪ | Nest.js framework expert specializing in module architecture, dependency injection, middleware, guards, interceptors, testing with Jest/Supertest, TypeORM/Mongoose integration, and Passport.js authentication. Use PROACTIVELY for any Nest.js application issues including architecture decisions, testing strategies, performance optimization, or debugging complex dependency injection problems. If a specialized expert is a better fit, I will recommend switching and stop. | `skills/nestjs-expert` |
|
||||
| **Network 101** | ⚪ | This skill should be used when the user asks to "set up a web server", "configure HTTP or HTTPS", "perform SNMP enumeration", "configure SMB shares", "test network services", or needs guidance on configuring and testing network services for penetration testing labs. | `skills/network-101` |
|
||||
| **nextjs-best-practices** | ⚪ | Next.js App Router principles. Server Components, data fetching, routing patterns. | `skills/nextjs-best-practices` |
|
||||
| **nextjs-supabase-auth** | ⚪ | Expert integration of Supabase Auth with Next.js App Router Use when: supabase auth next, authentication next.js, login supabase, auth middleware, protected route. | `skills/nextjs-supabase-auth` |
|
||||
| **nodejs-best-practices** | ⚪ | Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying. | `skills/nodejs-best-practices` |
|
||||
| **nosql-expert** | ⚪ | Expert guidance for distributed NoSQL databases (Cassandra, DynamoDB). Focuses on mental models, query-first modeling, single-table design, and avoiding hot partitions in high-scale systems. | `skills/nosql-expert` |
|
||||
| **notebooklm** | ⚪ | Use this skill to query your Google NotebookLM notebooks directly from Claude Code for source-grounded, citation-backed answers from Gemini. Browser automation, library management, persistent auth. Drastically reduced hallucinations through document-only responses. | `skills/notebooklm` |
|
||||
| **notion-template-business** | ⚪ | Expert in building and selling Notion templates as a business - not just making templates, but building a sustainable digital product business. Covers template design, pricing, marketplaces, marketing, and scaling to real revenue. Use when: notion template, sell templates, digital product, notion business, gumroad. | `skills/notion-template-business` |
|
||||
| **obsidian-clipper-template-creator** | ⚪ | Guide for creating templates for the Obsidian Web Clipper. Use when you want to create a new clipping template, understand available variables, or format clipped content. | `skills/obsidian-clipper-template-creator` |
|
||||
| **onboarding-cro** | ⚪ | When the user wants to optimize post-signup onboarding, user activation, first-run experience, or time-to-value. Also use when the user mentions "onboarding flow," "activation rate," "user activation," "first-run experience," "empty states," "onboarding checklist," "aha moment," or "new user experience." For signup/registration optimization, see signup-flow-cro. For ongoing email sequences, see email-sequence. | `skills/onboarding-cro` |
|
||||
| **page-cro** | ⚪ | Analyze and optimize individual pages for conversion performance. Use when the user wants to improve conversion rates, diagnose why a page is underperforming, or increase the effectiveness of marketing pages (homepage, landing pages, pricing, feature pages, or blog posts). This skill focuses on diagnosis, prioritization, and testable recommendations— not blind optimization. | `skills/page-cro` |
|
||||
| **paid-ads** | ⚪ | When the user wants help with paid advertising campaigns on Google Ads, Meta (Facebook/Instagram), LinkedIn, Twitter/X, or other ad platforms. Also use when the user mentions 'PPC,' 'paid media,' 'ad copy,' 'ad creative,' 'ROAS,' 'CPA,' 'ad campaign,' 'retargeting,' or 'audience targeting.' This skill covers campaign strategy, ad creation, audience targeting, and optimization. | `skills/paid-ads` |
|
||||
| **parallel-agents** | ⚪ | Multi-agent orchestration patterns. Use when multiple independent tasks can run with different domain expertise or when comprehensive analysis requires multiple perspectives. | `skills/parallel-agents` |
|
||||
| **paywall-upgrade-cro** | ⚪ | When the user wants to create or optimize in-app paywalls, upgrade screens, upsell modals, or feature gates. Also use when the user mentions "paywall," "upgrade screen," "upgrade modal," "upsell," "feature gate," "convert free to paid," "freemium conversion," "trial expiration screen," "limit reached screen," "plan upgrade prompt," or "in-app pricing." Distinct from public pricing pages (see page-cro) — this skill focuses on in-product upgrade moments where the user has already experienced value. | `skills/paywall-upgrade-cro` |
|
||||
| **pc-games** | ⚪ | PC and console game development principles. Engine selection, platform features, optimization strategies. | `skills/game-development/pc-games` |
|
||||
| **pdf** | ⚪ | Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. When Claude needs to fill in a PDF form or programmatically process, generate, or analyze PDF documents at scale. | `skills/pdf-official` |
|
||||
| **Pentest Checklist** | ⚪ | This skill should be used when the user asks to "plan a penetration test", "create a security assessment checklist", "prepare for penetration testing", "define pentest scope", "follow security testing best practices", or needs a structured methodology for penetration testing engagements. | `skills/pentest-checklist` |
|
||||
| **Pentest Commands** | ⚪ | This skill should be used when the user asks to "run pentest commands", "scan with nmap", "use metasploit exploits", "crack passwords with hydra or john", "scan web vulnerabilities with nikto", "enumerate networks", or needs essential penetration testing command references. | `skills/pentest-commands` |
|
||||
| **performance-profiling** | ⚪ | Performance profiling principles. Measurement, analysis, and optimization techniques. | `skills/performance-profiling` |
|
||||
| **personal-tool-builder** | ⚪ | Expert in building custom tools that solve your own problems first. The best products often start as personal tools - scratch your own itch, build for yourself, then discover others have the same itch. Covers rapid prototyping, local-first apps, CLI tools, scripts that grow into products, and the art of dogfooding. Use when: build a tool, personal tool, scratch my itch, solve my problem, CLI tool. | `skills/personal-tool-builder` |
|
||||
| **plaid-fintech** | ⚪ | Expert patterns for Plaid API integration including Link token flows, transactions sync, identity verification, Auth for ACH, balance checks, webhook handling, and fintech compliance best practices. Use when: plaid, bank account linking, bank connection, ach, account aggregation. | `skills/plaid-fintech` |
|
||||
| **plan-writing** | ⚪ | Structured task planning with clear breakdowns, dependencies, and verification criteria. Use when implementing features, refactoring, or any multi-step work. | `skills/plan-writing` |
|
||||
| **planning-with-files** | ⚪ | Implements Manus-style file-based planning for complex tasks. Creates task_plan.md, findings.md, and progress.md. Use when starting complex multi-step tasks, research projects, or any task requiring >5 tool calls. | `skills/planning-with-files` |
|
||||
| **playwright-skill** | ⚪ | Complete browser automation with Playwright. Auto-detects dev servers, writes clean test scripts to /tmp. Test pages, fill forms, take screenshots, check responsive design, validate UX, test login flows, check links, automate any browser task. Use when user wants to test websites, automate browser interactions, validate web functionality, or perform any browser-based testing. | `skills/playwright-skill` |
|
||||
| **popup-cro** | ⚪ | Create and optimize popups, modals, overlays, slide-ins, and banners to increase conversions without harming user experience or brand trust. | `skills/popup-cro` |
|
||||
| **powershell-windows** | ⚪ | PowerShell Windows patterns. Critical pitfalls, operator syntax, error handling. | `skills/powershell-windows` |
|
||||
| **pptx** | ⚪ | Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks | `skills/pptx-official` |
|
||||
| **pricing-strategy** | ⚪ | Design pricing, packaging, and monetization strategies based on value, customer willingness to pay, and growth objectives. | `skills/pricing-strategy` |
|
||||
| **prisma-expert** | ⚪ | Prisma ORM expert for schema design, migrations, query optimization, relations modeling, and database operations. Use PROACTIVELY for Prisma schema issues, migration problems, query performance, relation design, or database connection issues. | `skills/prisma-expert` |
|
||||
| **Privilege Escalation Methods** | ⚪ | This skill should be used when the user asks to "escalate privileges", "get root access", "become administrator", "privesc techniques", "abuse sudo", "exploit SUID binaries", "Kerberoasting", "pass-the-ticket", "token impersonation", or needs guidance on post-exploitation privilege escalation for Linux or Windows systems. | `skills/privilege-escalation-methods` |
|
||||
| **product-manager-toolkit** | ⚪ | Comprehensive toolkit for product managers including RICE prioritization, customer interview analysis, PRD templates, discovery frameworks, and go-to-market strategies. Use for feature prioritization, user research synthesis, requirement documentation, and product strategy development. | `skills/product-manager-toolkit` |
|
||||
| **production-code-audit** | ⚪ | Autonomously deep-scan entire codebase line-by-line, understand architecture and patterns, then systematically transform it to production-grade, corporate-level professional quality with optimizations | `skills/production-code-audit` |
|
||||
| **programmatic-seo** | ⚪ | Design and evaluate programmatic SEO strategies for creating SEO-driven pages at scale using templates and structured data. Use when the user mentions programmatic SEO, pages at scale, template pages, directory pages, location pages, comparison pages, integration pages, or keyword-pattern page generation. This skill focuses on feasibility, strategy, and page system design—not execution unless explicitly requested. | `skills/programmatic-seo` |
|
||||
| **prompt-caching** | ⚪ | Caching strategies for LLM prompts including Anthropic prompt caching, response caching, and CAG (Cache Augmented Generation) Use when: prompt caching, cache prompt, response cache, cag, cache augmented. | `skills/prompt-caching` |
|
||||
| **prompt-engineer** | ⚪ | Expert in designing effective prompts for LLM-powered applications. Masters prompt structure, context management, output formatting, and prompt evaluation. Use when: prompt engineering, system prompt, few-shot, chain of thought, prompt design. | `skills/prompt-engineer` |
|
||||
| **prompt-engineering** | ⚪ | Expert guide on prompt engineering patterns, best practices, and optimization techniques. Use when user wants to improve prompts, learn prompting strategies, or debug agent behavior. | `skills/prompt-engineering` |
|
||||
| **prompt-library** | ⚪ | Curated collection of high-quality prompts for various use cases. Includes role-based prompts, task-specific templates, and prompt refinement techniques. Use when user needs prompt templates, role-play prompts, or ready-to-use prompt examples for coding, writing, analysis, or creative tasks. | `skills/prompt-library` |
|
||||
| **python-patterns** | ⚪ | Python development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying. | `skills/python-patterns` |
|
||||
| **rag-engineer** | ⚪ | Expert in building Retrieval-Augmented Generation systems. Masters embedding models, vector databases, chunking strategies, and retrieval optimization for LLM applications. Use when: building RAG, vector search, embeddings, semantic search, document retrieval. | `skills/rag-engineer` |
|
||||
| **rag-implementation** | ⚪ | Retrieval-Augmented Generation patterns including chunking, embeddings, vector stores, and retrieval optimization Use when: rag, retrieval augmented, vector search, embeddings, semantic search. | `skills/rag-implementation` |
|
||||
| **react-patterns** | ⚪ | Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices. | `skills/react-patterns` |
|
||||
| **react-ui-patterns** | ⚪ | Modern React UI patterns for loading states, error handling, and data fetching. Use when building UI components, handling async data, or managing UI states. | `skills/react-ui-patterns` |
|
||||
| **receiving-code-review** | ⚪ | Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation | `skills/receiving-code-review` |
|
||||
| **Red Team Tools and Methodology** | ⚪ | This skill should be used when the user asks to "follow red team methodology", "perform bug bounty hunting", "automate reconnaissance", "hunt for XSS vulnerabilities", "enumerate subdomains", or needs security researcher techniques and tool configurations from top bug bounty hunters. | `skills/red-team-tools` |
|
||||
| **red-team-tactics** | ⚪ | Red team tactics principles based on MITRE ATT&CK. Attack phases, detection evasion, reporting. | `skills/red-team-tactics` |
|
||||
| **referral-program** | ⚪ | When the user wants to create, optimize, or analyze a referral program, affiliate program, or word-of-mouth strategy. Also use when the user mentions 'referral,' 'affiliate,' 'ambassador,' 'word of mouth,' 'viral loop,' 'refer a friend,' or 'partner program.' This skill covers program design, incentive structure, and growth optimization. | `skills/referral-program` |
|
||||
| **remotion-best-practices** | ⚪ | Best practices for Remotion - Video creation in React | `skills/remotion-best-practices` |
|
||||
| **requesting-code-review** | ⚪ | Use when completing tasks, implementing major features, or before merging to verify work meets requirements | `skills/requesting-code-review` |
|
||||
| **research-engineer** | ⚪ | An uncompromising Academic Research Engineer. Operates with absolute scientific rigor, objective criticism, and zero flair. Focuses on theoretical correctness, formal verification, and optimal implementation across any required technology. | `skills/research-engineer` |
|
||||
| **salesforce-development** | ⚪ | Expert patterns for Salesforce platform development including Lightning Web Components (LWC), Apex triggers and classes, REST/Bulk APIs, Connected Apps, and Salesforce DX with scratch orgs and 2nd generation packages (2GP). Use when: salesforce, sfdc, apex, lwc, lightning web components. | `skills/salesforce-development` |
|
||||
| **schema-markup** | ⚪ | Design, validate, and optimize schema.org structured data for eligibility, correctness, and measurable SEO impact. Use when the user wants to add, fix, audit, or scale schema markup (JSON-LD) for rich results. This skill evaluates whether schema should be implemented, what types are valid, and how to deploy safely according to Google guidelines. | `skills/schema-markup` |
|
||||
| **scroll-experience** | ⚪ | Expert in building immersive scroll-driven experiences - parallax storytelling, scroll animations, interactive narratives, and cinematic web experiences. Like NY Times interactives, Apple product pages, and award-winning web experiences. Makes websites feel like experiences, not just pages. Use when: scroll animation, parallax, scroll storytelling, interactive story, cinematic website. | `skills/scroll-experience` |
|
||||
| **Security Scanning Tools** | ⚪ | This skill should be used when the user asks to "perform vulnerability scanning", "scan networks for open ports", "assess web application security", "scan wireless networks", "detect malware", "check cloud security", or "evaluate system compliance". It provides comprehensive guidance on security scanning tools and methodologies. | `skills/scanning-tools` |
|
||||
| **security-review** | ⚪ | Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns. | `skills/cc-skill-security-review` |
|
||||
| **segment-cdp** | ⚪ | Expert patterns for Segment Customer Data Platform including Analytics.js, server-side tracking, tracking plans with Protocols, identity resolution, destinations configuration, and data governance best practices. Use when: segment, analytics.js, customer data platform, cdp, tracking plan. | `skills/segment-cdp` |
|
||||
| **senior-architect** | ⚪ | Comprehensive software architecture skill for designing scalable, maintainable systems using ReactJS, NextJS, NodeJS, Express, React Native, Swift, Kotlin, Flutter, Postgres, GraphQL, Go, Python. Includes architecture diagram generation, system design patterns, tech stack decision frameworks, and dependency analysis. Use when designing system architecture, making technical decisions, creating architecture diagrams, evaluating trade-offs, or defining integration patterns. | `skills/senior-architect` |
|
||||
| **senior-fullstack** | ⚪ | Comprehensive fullstack development skill for building complete web applications with React, Next.js, Node.js, GraphQL, and PostgreSQL. Includes project scaffolding, code quality analysis, architecture patterns, and complete tech stack guidance. Use when building new projects, analyzing code quality, implementing design patterns, or setting up development workflows. | `skills/senior-fullstack` |
|
||||
| **seo-audit** | ⚪ | Diagnose and audit SEO issues affecting crawlability, indexation, rankings, and organic performance. Use when the user asks for an SEO audit, technical SEO review, ranking diagnosis, on-page SEO review, meta tag audit, or SEO health check. This skill identifies issues and prioritizes actions but does not execute changes. For large-scale page creation, use programmatic-seo. For structured data, use schema-markup. | `skills/seo-audit` |
|
||||
| **seo-fundamentals** | ⚪ | Core principles of SEO including E-E-A-T, Core Web Vitals, technical foundations, content quality, and how modern search engines evaluate pages. This skill explains _why_ SEO works, not how to execute specific optimizations. | `skills/seo-fundamentals` |
|
||||
| **server-management** | ⚪ | Server management principles and decision-making. Process management, monitoring strategy, and scaling decisions. Teaches thinking, not commands. | `skills/server-management` |
|
||||
| **Shodan Reconnaissance and Pentesting** | ⚪ | This skill should be used when the user asks to "search for exposed devices on the internet," "perform Shodan reconnaissance," "find vulnerable services using Shodan," "scan IP ranges with Shodan," or "discover IoT devices and open ports." It provides comprehensive guidance for using Shodan's search engine, CLI, and API for penetration testing reconnaissance. | `skills/shodan-reconnaissance` |
|
||||
| **shopify-apps** | ⚪ | Expert patterns for Shopify app development including Remix/React Router apps, embedded apps with App Bridge, webhook handling, GraphQL Admin API, Polaris components, billing, and app extensions. Use when: shopify app, shopify, embedded app, polaris, app bridge. | `skills/shopify-apps` |
|
||||
| **shopify-development** | ⚪ | Build Shopify apps, extensions, themes using GraphQL Admin API, Shopify CLI, Polaris UI, and Liquid. TRIGGER: "shopify", "shopify app", "checkout extension", "admin extension", "POS extension", "shopify theme", "liquid template", "polaris", "shopify graphql", "shopify webhook", "shopify billing", "app subscription", "metafields", "shopify functions" | `skills/shopify-development` |
|
||||
| **signup-flow-cro** | ⚪ | When the user wants to optimize signup, registration, account creation, or trial activation flows. Also use when the user mentions "signup conversions," "registration friction," "signup form optimization," "free trial signup," "reduce signup dropoff," or "account creation flow." For post-signup onboarding, see onboarding-cro. For lead capture forms (not account creation), see form-cro. | `skills/signup-flow-cro` |
|
||||
| **skill-creator** | ⚪ | Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations. | `skills/skill-creator` |
|
||||
| **skill-developer** | ⚪ | Create and manage Claude Code skills following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns, file paths, content patterns), enforcement levels (block, suggest, warn), hook mechanisms (UserPromptSubmit, PreToolUse), session tracking, and the 500-line rule. | `skills/skill-developer` |
|
||||
| **slack-bot-builder** | ⚪ | Build Slack apps using the Bolt framework across Python, JavaScript, and Java. Covers Block Kit for rich UIs, interactive components, slash commands, event handling, OAuth installation flows, and Workflow Builder integration. Focus on best practices for production-ready Slack apps. Use when: slack bot, slack app, bolt framework, block kit, slash command. | `skills/slack-bot-builder` |
|
||||
| **slack-gif-creator** | ⚪ | Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a GIF of X doing Y for Slack." | `skills/slack-gif-creator` |
|
||||
| **SMTP Penetration Testing** | ⚪ | This skill should be used when the user asks to "perform SMTP penetration testing", "enumerate email users", "test for open mail relays", "grab SMTP banners", "brute force email credentials", or "assess mail server security". It provides comprehensive techniques for testing SMTP server security. | `skills/smtp-penetration-testing` |
|
||||
| **social-content** | ⚪ | When the user wants help creating, scheduling, or optimizing social media content for LinkedIn, Twitter/X, Instagram, TikTok, Facebook, or other platforms. Also use when the user mentions 'LinkedIn post,' 'Twitter thread,' 'social media,' 'content calendar,' 'social scheduling,' 'engagement,' or 'viral content.' This skill covers content creation, repurposing, and platform-specific strategies. | `skills/social-content` |
|
||||
| **software-architecture** | ⚪ | Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code, in any case that relates to software development. | `skills/software-architecture` |
|
||||
| **SQL Injection Testing** | ⚪ | This skill should be used when the user asks to "test for SQL injection vulnerabilities", "perform SQLi attacks", "bypass authentication using SQL injection", "extract database information through injection", "detect SQL injection flaws", or "exploit database query vulnerabilities". It provides comprehensive techniques for identifying, exploiting, and understanding SQL injection attack vectors across different database systems. | `skills/sql-injection-testing` |
|
||||
| **SQLMap Database Penetration Testing** | ⚪ | This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap," "dump tables and columns from a vulnerable database," or "perform automated database penetration testing." It provides comprehensive guidance for using SQLMap to detect and exploit SQL injection vulnerabilities. | `skills/sqlmap-database-pentesting` |
|
||||
| **SSH Penetration Testing** | ⚪ | This skill should be used when the user asks to "pentest SSH services", "enumerate SSH configurations", "brute force SSH credentials", "exploit SSH vulnerabilities", "perform SSH tunneling", or "audit SSH security". It provides comprehensive SSH penetration testing methodologies and techniques. | `skills/ssh-penetration-testing` |
|
||||
| **stripe-integration** | ⚪ | Get paid from day one. Payments, subscriptions, billing portal, webhooks, metered billing, Stripe Connect. The complete guide to implementing Stripe correctly, including all the edge cases that will bite you at 3am. This isn't just API calls - it's the full payment system: handling failures, managing subscriptions, dealing with dunning, and keeping revenue flowing. Use when: stripe, payments, subscription, billing, checkout. | `skills/stripe-integration` |
|
||||
| **subagent-driven-development** | ⚪ | Use when executing implementation plans with independent tasks in the current session | `skills/subagent-driven-development` |
|
||||
| **supabase-postgres-best-practices** | ⚪ | Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations. | `skills/postgres-best-practices` |
|
||||
| **systematic-debugging** | ⚪ | Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes | `skills/systematic-debugging` |
|
||||
| **tailwind-patterns** | ⚪ | Tailwind CSS v4 principles. CSS-first configuration, container queries, modern patterns, design token architecture. | `skills/tailwind-patterns` |
|
||||
| **tavily-web** | ⚪ | Web search, content extraction, crawling, and research capabilities using Tavily API | `skills/tavily-web` |
|
||||
| **tdd-workflow** | ⚪ | Test-Driven Development workflow principles. RED-GREEN-REFACTOR cycle. | `skills/tdd-workflow` |
|
||||
| **telegram-bot-builder** | ⚪ | Expert in building Telegram bots that solve real problems - from simple automation to complex AI-powered bots. Covers bot architecture, the Telegram Bot API, user experience, monetization strategies, and scaling bots to thousands of users. Use when: telegram bot, bot api, telegram automation, chat bot telegram, tg bot. | `skills/telegram-bot-builder` |
|
||||
| **telegram-mini-app** | ⚪ | Expert in building Telegram Mini Apps (TWA) - web apps that run inside Telegram with native-like experience. Covers the TON ecosystem, Telegram Web App API, payments, user authentication, and building viral mini apps that monetize. Use when: telegram mini app, TWA, telegram web app, TON app, mini app. | `skills/telegram-mini-app` |
|
||||
| **templates** | ⚪ | Project scaffolding templates for new applications. Use when creating new projects from scratch. Contains 12 templates for various tech stacks. | `skills/app-builder/templates` |
|
||||
| **test-driven-development** | ⚪ | Use when implementing any feature or bugfix, before writing implementation code | `skills/test-driven-development` |
|
||||
| **test-fixing** | ⚪ | Run tests and systematically fix all failing tests using smart error grouping. Use when user asks to fix failing tests, mentions test failures, runs test suite and failures occur, or requests to make tests pass. | `skills/test-fixing` |
|
||||
| **testing-patterns** | ⚪ | Jest testing patterns, factory functions, mocking strategies, and TDD workflow. Use when writing unit tests, creating test factories, or following TDD red-green-refactor cycle. | `skills/testing-patterns` |
|
||||
| **theme-factory** | ⚪ | Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly. | `skills/theme-factory` |
|
||||
| **Top 100 Web Vulnerabilities Reference** | ⚪ | This skill should be used when the user asks to "identify web application vulnerabilities", "explain common security flaws", "understand vulnerability categories", "learn about injection attacks", "review access control weaknesses", "analyze API security issues", "assess security misconfigurations", "understand client-side vulnerabilities", "examine mobile and IoT security flaws", or "reference the OWASP-aligned vulnerability taxonomy". Use this skill to provide comprehensive vulnerability definitions, root causes, impacts, and mitigation strategies across all major web security categories. | `skills/top-web-vulnerabilities` |
|
||||
| **trigger-dev** | ⚪ | Trigger.dev expert for background jobs, AI workflows, and reliable async execution with excellent developer experience and TypeScript-first design. Use when: trigger.dev, trigger dev, background task, ai background job, long running task. | `skills/trigger-dev` |
|
||||
| **twilio-communications** | ⚪ | Build communication features with Twilio: SMS messaging, voice calls, WhatsApp Business API, and user verification (2FA). Covers the full spectrum from simple notifications to complex IVR systems and multi-channel authentication. Critical focus on compliance, rate limits, and error handling. Use when: twilio, send SMS, text message, voice call, phone verification. | `skills/twilio-communications` |
|
||||
| **typescript-expert** | ⚪ | TypeScript and JavaScript expert with deep knowledge of type-level programming, performance optimization, monorepo management, migration strategies, and modern tooling. Use PROACTIVELY for any TypeScript/JavaScript issues including complex type gymnastics, build performance, debugging, and architectural decisions. If a specialized expert is a better fit, I will recommend switching and stop. | `skills/typescript-expert` |
|
||||
| **ui-ux-pro-max** | ⚪ | UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 9 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples. | `skills/ui-ux-pro-max` |
|
||||
| **upstash-qstash** | ⚪ | Upstash QStash expert for serverless message queues, scheduled jobs, and reliable HTTP-based task delivery without managing infrastructure. Use when: qstash, upstash queue, serverless cron, scheduled http, message queue serverless. | `skills/upstash-qstash` |
|
||||
| **using-git-worktrees** | ⚪ | Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification | `skills/using-git-worktrees` |
|
||||
| **using-superpowers** | ⚪ | Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions | `skills/using-superpowers` |
|
||||
| **vercel-deployment** | ⚪ | Expert knowledge for deploying to Vercel with Next.js Use when: vercel, deploy, deployment, hosting, production. | `skills/vercel-deployment` |
|
||||
| **vercel-react-best-practices** | ⚪ | React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements. | `skills/react-best-practices` |
|
||||
| **verification-before-completion** | ⚪ | Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always | `skills/verification-before-completion` |
|
||||
| **viral-generator-builder** | ⚪ | Expert in building shareable generator tools that go viral - name generators, quiz makers, avatar creators, personality tests, and calculator tools. Covers the psychology of sharing, viral mechanics, and building tools people can't resist sharing with friends. Use when: generator tool, quiz maker, name generator, avatar creator, viral tool. | `skills/viral-generator-builder` |
|
||||
| **voice-agents** | ⚪ | Voice agents represent the frontier of AI interaction - humans speaking naturally with AI systems. The challenge isn't just speech recognition and synthesis, it's achieving natural conversation flow with sub-800ms latency while handling interruptions, background noise, and emotional nuance. This skill covers two architectures: speech-to-speech (OpenAI Realtime API, lowest latency, most natural) and pipeline (STT→LLM→TTS, more control, easier to debug). Key insight: latency is the constraint. Hu | `skills/voice-agents` |
|
||||
| **voice-ai-development** | ⚪ | Expert in building voice AI applications - from real-time voice agents to voice-enabled apps. Covers OpenAI Realtime API, Vapi for voice agents, Deepgram for transcription, ElevenLabs for synthesis, LiveKit for real-time infrastructure, and WebRTC fundamentals. Knows how to build low-latency, production-ready voice experiences. Use when: voice ai, voice agent, speech to text, text to speech, realtime voice. | `skills/voice-ai-development` |
|
||||
| **vr-ar** | ⚪ | VR/AR development principles. Comfort, interaction, performance requirements. | `skills/game-development/vr-ar` |
|
||||
| **vulnerability-scanner** | ⚪ | Advanced vulnerability analysis principles. OWASP 2025, Supply Chain Security, attack surface mapping, risk prioritization. | `skills/vulnerability-scanner` |
|
||||
| **web-artifacts-builder** | ⚪ | Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts. | `skills/web-artifacts-builder` |
|
||||
| **web-design-guidelines** | ⚪ | Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices". | `skills/web-design-guidelines` |
|
||||
| **web-games** | ⚪ | Web browser game development principles. Framework selection, WebGPU, optimization, PWA. | `skills/game-development/web-games` |
|
||||
| **web-performance-optimization** | ⚪ | Optimize website and web application performance including loading speed, Core Web Vitals, bundle size, caching strategies, and runtime performance | `skills/web-performance-optimization` |
|
||||
| **webapp-testing** | ⚪ | Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. | `skills/webapp-testing` |
|
||||
| **Windows Privilege Escalation** | ⚪ | This skill should be used when the user asks to "escalate privileges on Windows," "find Windows privesc vectors," "enumerate Windows for privilege escalation," "exploit Windows misconfigurations," or "perform post-exploitation privilege escalation." It provides comprehensive guidance for discovering and exploiting privilege escalation vulnerabilities in Windows environments. | `skills/windows-privilege-escalation` |
|
||||
| **Wireshark Network Traffic Analysis** | ⚪ | This skill should be used when the user asks to "analyze network traffic with Wireshark", "capture packets for troubleshooting", "filter PCAP files", "follow TCP/UDP streams", "detect network anomalies", "investigate suspicious traffic", or "perform protocol analysis". It provides comprehensive techniques for network packet capture, filtering, and analysis using Wireshark. | `skills/wireshark-analysis` |
|
||||
| **WordPress Penetration Testing** | ⚪ | This skill should be used when the user asks to "pentest WordPress sites", "scan WordPress for vulnerabilities", "enumerate WordPress users, themes, or plugins", "exploit WordPress vulnerabilities", or "use WPScan". It provides comprehensive WordPress security assessment methodologies. | `skills/wordpress-penetration-testing` |
|
||||
| **workflow-automation** | ⚪ | Workflow automation is the infrastructure that makes AI agents reliable. Without durable execution, a network hiccup during a 10-step payment flow means lost money and angry customers. With it, workflows resume exactly where they left off. This skill covers the platforms (n8n, Temporal, Inngest) and patterns (sequential, parallel, orchestrator-worker) that turn brittle scripts into production-grade automation. Key insight: The platforms make different tradeoffs. n8n optimizes for accessibility | `skills/workflow-automation` |
|
||||
| **writing-plans** | ⚪ | Use when you have a spec or requirements for a multi-step task, before touching code | `skills/writing-plans` |
|
||||
| **writing-skills** | ⚪ | Use when creating new skills, editing existing skills, or verifying skills work before deployment | `skills/writing-skills` |
|
||||
| **xlsx** | ⚪ | Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas | `skills/xlsx-official` |
|
||||
| **zapier-make-patterns** | ⚪ | No-code automation democratizes workflow building. Zapier and Make (formerly Integromat) let non-developers automate business processes without writing code. But no-code doesn't mean no-complexity - these platforms have their own patterns, pitfalls, and breaking points. This skill covers when to use which platform, how to build reliable automations, and when to graduate to code-based solutions. Key insight: Zapier optimizes for simplicity and integrations (7000+ apps), Make optimizes for power | `skills/zapier-make-patterns` |
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -373,14 +430,27 @@ Please ensure your skill follows the Antigravity/Claude Code best practices.
|
||||
|
||||
## Credits & Sources
|
||||
|
||||
We stand on the shoulders of giants.
|
||||
|
||||
👉 **[View the Full Attribution Ledger](docs/SOURCES.md)**
|
||||
|
||||
Key contributors and sources include:
|
||||
|
||||
- **HackTricks**
|
||||
- **OWASP**
|
||||
- **Anthropic / OpenAI / Google**
|
||||
- **The Open Source Community**
|
||||
|
||||
This collection would not be possible without the incredible work of the Claude Code community and official sources:
|
||||
|
||||
### Official Sources
|
||||
|
||||
- **[anthropics/skills](https://github.com/anthropics/skills)**: Official Anthropic skills repository - Document manipulation (DOCX, PDF, PPTX, XLSX), Brand Guidelines, Internal Communications.
|
||||
- **[anthropics/claude-cookbooks](https://github.com/anthropics/claude-cookbooks)**: Official notebooks and recipes for building with Claude.
|
||||
- **[remotion-dev/skills](https://github.com/remotion-dev/skills)**: Official Remotion skills - Video creation in React with 28 modular rules.
|
||||
- **[vercel-labs/agent-skills](https://github.com/vercel-labs/agent-skills)**: Vercel Labs official skills - React Best Practices, Web Design Guidelines.
|
||||
- **[openai/skills](https://github.com/openai/skills)**: OpenAI Codex skills catalog - Agent skills, Skill Creator, Concise Planning.
|
||||
- **[supabase/agent-skills](https://github.com/supabase/agent-skills)**: Supabase official skills - Postgres Best Practices.
|
||||
|
||||
### Community Contributors
|
||||
|
||||
@@ -396,6 +466,10 @@ This collection would not be possible without the incredible work of the Claude
|
||||
- **[vibeforge1111/vibeship-spawner-skills](https://github.com/vibeforge1111/vibeship-spawner-skills)**: AI Agents, Integrations, Maker Tools (57 skills, Apache 2.0).
|
||||
- **[coreyhaines31/marketingskills](https://github.com/coreyhaines31/marketingskills)**: Marketing skills for CRO, copywriting, SEO, paid ads, and growth (23 skills, MIT).
|
||||
- **[vudovn/antigravity-kit](https://github.com/vudovn/antigravity-kit)**: AI Agent templates with Skills, Agents, and Workflows (33 skills, MIT).
|
||||
- **[affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code)**: Complete Claude Code configuration collection from Anthropic hackathon winner - skills only (8 skills, MIT).
|
||||
- **[webzler/agentMemory](https://github.com/webzler/agentMemory)**: Source for the agent-memory-mcp skill.
|
||||
- **[mvanhorn](https://github.com/mvanhorn)**: Contributor of `last30days`.
|
||||
- **[rookie-ricardo](https://github.com/rookie-ricardo)**: Contributor of `daily-news-report`.
|
||||
|
||||
### Inspirations
|
||||
|
||||
@@ -408,13 +482,16 @@ This collection would not be possible without the incredible work of the Claude
|
||||
|
||||
MIT License. See [LICENSE](LICENSE) for details.
|
||||
|
||||
---
|
||||
## Community
|
||||
|
||||
**Keywords**: Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode, Agentic Skills, AI Coding Assistant, AI Agent Skills, MCP, MCT, AI Agents, Autonomous Coding, Security Auditing, React Patterns, LLM Tools, AI IDE, Coding AI, AI Pair Programming, Vibe Coding, Agentic Coding, AI Developer Tools.
|
||||
- [Community Guidelines](docs/COMMUNITY_GUIDELINES.md)
|
||||
- [Security Policy](docs/SECURITY_GUARDRAILS.md)
|
||||
|
||||
---
|
||||
|
||||
## 🏷️ GitHub Topics
|
||||
---
|
||||
|
||||
## GitHub Topics
|
||||
|
||||
For repository maintainers, add these topics to maximize discoverability:
|
||||
|
||||
@@ -422,6 +499,33 @@ For repository maintainers, add these topics to maximize discoverability:
|
||||
claude-code, gemini-cli, codex-cli, antigravity, cursor, github-copilot, opencode,
|
||||
agentic-skills, ai-coding, llm-tools, ai-agents, autonomous-coding, mcp,
|
||||
ai-developer-tools, ai-pair-programming, vibe-coding, skill, skills, SKILL.md, rules.md, CLAUDE.md, GEMINI.md, CURSOR.md
|
||||
claude-code, gemini-cli, codex-cli, antigravity, cursor, github-copilot, opencode,
|
||||
agentic-skills, ai-coding, llm-tools, ai-agents, autonomous-coding, mcp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Repo Contributors
|
||||
|
||||
We officially thank the following contributors for their help in making this repository awesome!
|
||||
|
||||
- [sck_0](https://github.com/sck_0)
|
||||
- [Munir Abbasi](https://github.com/munirabbasi)
|
||||
- [Mohammad Faiz](https://github.com/mohdfaiz2k9)
|
||||
- [GuppyTheCat](https://github.com/GuppyTheCat)
|
||||
- [sickn33](https://github.com/sickn33)
|
||||
- [Ianj332](https://github.com/Ianj332)
|
||||
- [Tiger-Foxx](https://github.com/Tiger-Foxx)
|
||||
- [arathiesh](https://github.com/arathiesh)
|
||||
- [1bcMax](https://github.com/1bcMax)
|
||||
- [Ahmed Rehan](https://github.com/ar27111994)
|
||||
- [BenedictKing](https://github.com/BenedictKing)
|
||||
- [Nguyen Huu Loc](https://github.com/LocNguyenSGU)
|
||||
- [Owen Wu](https://github.com/yubing744)
|
||||
- [SuperJMN](https://github.com/SuperJMN)
|
||||
- [Viktor Ferenczi](https://github.com/viktor-ferenczi)
|
||||
- [krisnasantosa15](https://github.com/krisnasantosa15)
|
||||
- [zebbern](https://github.com/zebbern)
|
||||
- [vuth-dogo](https://github.com/vuth-dogo)
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://www.star-history.com/#sickn33/antigravity-awesome-skills&type=date&legend=top-left)
|
||||
|
||||
19
SECURITY.md
Normal file
19
SECURITY.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We track the `main` branch.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
**DO NOT** open a public Issue for security exploits.
|
||||
|
||||
If you find a security vulnerability (e.g., a skill that bypasses the "Authorized Use Only" check or executes malicious code without warning):
|
||||
|
||||
1. Email: `security@antigravity.dev` (Placeholder)
|
||||
2. Or open a **Private Advisory** on this repository.
|
||||
|
||||
## Offensive Skills Policy
|
||||
|
||||
Please read our [Security Guardrails](docs/SECURITY_GUARDRAILS.md).
|
||||
All offensive skills are strictly for **authorized educational and professional use only**.
|
||||
124
docs/BUNDLES.md
Normal file
124
docs/BUNDLES.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# 📦 Antigravity Skill Bundles
|
||||
|
||||
Don't know where to start? Pick a bundle below to get a curated set of skills for your role.
|
||||
|
||||
## 🚀 The "Essentials" Starter Pack
|
||||
|
||||
_For everyone. Install these first._
|
||||
|
||||
- `concise-planning`: Always start with a plan.
|
||||
- `lint-and-validate`: Keep your code clean automatically.
|
||||
- `git-pushing`: Save your work safely.
|
||||
- `kaizen`: Continuous improvement mindset.
|
||||
|
||||
## 🛡️ The "Security Engineer" Pack
|
||||
|
||||
_For pentesting, auditing, and hardening._
|
||||
|
||||
- `ethical-hacking-methodology`: The Bible of ethical hacking.
|
||||
- `burp-suite-testing`: Web vulnerability scanning.
|
||||
- `owasp-top-10`: Check for the most common flaws.
|
||||
- `linux-privilege-escalation`: Advanced Linux security assessment.
|
||||
- `cloud-penetration-testing`: AWS/Azure/GCP security.
|
||||
|
||||
## 🌐 The "Web Wizard" Pack
|
||||
|
||||
_For building modern, high-performance web apps._
|
||||
|
||||
- `frontend-design`: UI guidelines and aesthetics.
|
||||
- `react-patterns`: Best practices for React (if available).
|
||||
- `tailwind-mastery`: Styling superpowers.
|
||||
- `form-cro`: Optimize your forms for conversion.
|
||||
- `seo-audit`: Get found on Google.
|
||||
|
||||
## 🤖 The "Agent Architect" Pack
|
||||
|
||||
_For building AI systems._
|
||||
|
||||
- `agent-evaluation`: Test your agents.
|
||||
- `langgraph`: Build stateful agent workflows.
|
||||
- `mcp-builder`: Create your own tools.
|
||||
- `prompt-engineering`: Master the art of talking to LLMs.
|
||||
|
||||
## 🎮 The "Indie Game Dev" Pack
|
||||
|
||||
_For building games with AI assistants._
|
||||
|
||||
- `game-development/game-design`: Mechanics and loops.
|
||||
- `game-development/2d-games`: Sprites and physics.
|
||||
- `game-development/3d-games`: Models and shaders.
|
||||
- `game-development/unity-csharp`: C# scripting mastery.
|
||||
- `algorithmic-art`: Generate assets with code.
|
||||
|
||||
## 🐍 The "Python Pro" Pack
|
||||
|
||||
_For backend heavyweights and data scientists._
|
||||
|
||||
- `python-patterns`: Idiomatic Python code.
|
||||
- `poetry-manager`: Dependency management that works.
|
||||
- `pytest-mastery`: Testing frameworks.
|
||||
- `fastapi-expert`: High-performance APIs.
|
||||
- `django-guide`: The battery-included framework.
|
||||
|
||||
## 🦄 The "Startup Founder" Pack
|
||||
|
||||
_For building products, not just code._
|
||||
|
||||
- `product-requirements-doc`: Define what to build.
|
||||
- `competitor-analysis`: Know who you are fighting.
|
||||
- `pitch-deck-creator`: Raise capital (or just explain your idea).
|
||||
- `landing-page-copy`: Write words that sell.
|
||||
- `stripe-integration`: Get paid.
|
||||
|
||||
## 🌧️ The "DevOps & Cloud" Pack
|
||||
|
||||
_For infrastructure and scaling._
|
||||
|
||||
- `docker-expert`: Master containers and multi-stage builds.
|
||||
- `aws-serverless`: Go serverless on AWS (Lambda, DynamoDB).
|
||||
- `environment-setup-guide`: Standardization for teams.
|
||||
- `deployment-procedures`: Safe rollout strategies.
|
||||
- `bash-linux`: Terminal wizardry.
|
||||
|
||||
## 📊 The "Data & Analytics" Pack
|
||||
|
||||
_For making sense of the numbers._
|
||||
|
||||
- `analytics-tracking`: Set up GA4/PostHog correctly.
|
||||
- `d3-viz`: Beautiful custom visualizations.
|
||||
- `sql-mastery`: Write better queries (Community skill).
|
||||
- `ab-test-setup`: Validated learning.
|
||||
|
||||
## 🎨 The "Creative Director" Pack
|
||||
|
||||
_For visuals, content, and branding._
|
||||
|
||||
- `canvas-design`: Generate posters and diagrams.
|
||||
- `frontend-design`: UI aesthetics.
|
||||
- `content-creator`: SEO-optimized blog posts.
|
||||
- `copy-editing`: Polish your prose.
|
||||
- `algorithmic-art`: Code-generated masterpieces.
|
||||
|
||||
## 🐞 The "QA & Testing" Pack
|
||||
|
||||
_For breaking things before users do._
|
||||
|
||||
- `test-driven-development`: Red, Green, Refactor.
|
||||
- `systematic-debugging`: Sherlock Holmes for code.
|
||||
- `browser-automation`: End-to-end testing with Playwright.
|
||||
- `ab-test-setup`: Validated experiments.
|
||||
- `code-review-checklist`: Catch bugs in PRs.
|
||||
|
||||
## 🖌️ The "Web Designer" Pack
|
||||
|
||||
_For pixel-perfect experiences._
|
||||
|
||||
- `ui-ux-pro-max`: Premium design systems/tokens.
|
||||
- `frontend-design`: The base layer of aesthetics.
|
||||
- `3d-web-experience`: Three.js & R3F magic.
|
||||
- `canvas-design`: Static visuals/posters.
|
||||
- `responsive-layout`: Mobile-first principles.
|
||||
|
||||
---
|
||||
|
||||
_To use a bundle, simply copy the skill names into your `.agent/skills` folder or use them with your agent._
|
||||
38
docs/CI_DRIFT_FIX.md
Normal file
38
docs/CI_DRIFT_FIX.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# CI Drift Fix Guide
|
||||
|
||||
**Problem**: The failing job is caused by uncommitted changes detected in `README.md` or `skills_index.json` after the update scripts run.
|
||||
|
||||
**Error**:
|
||||
|
||||
```
|
||||
❌ Detected uncommitted changes in README.md or skills_index.json. Please run scripts locally and commit.
|
||||
```
|
||||
|
||||
**Cause**:
|
||||
Scripts like `scripts/generate_index.py` and `scripts/update_readme.py` modify `README.md` and `skills_index.json`, but the workflow expects these files to have no changes after the scripts are run. Any differences mean the committed repo is out-of-sync with what the generation scripts produce.
|
||||
|
||||
**How to Fix (DO THIS EVERY TIME):**
|
||||
|
||||
1. Run the scripts locally to regenerate README.md and skills_index.json:
|
||||
|
||||
```bash
|
||||
python3 scripts/generate_index.py
|
||||
python3 scripts/update_readme.py
|
||||
```
|
||||
|
||||
2. Check for changes:
|
||||
|
||||
```bash
|
||||
git status
|
||||
git diff
|
||||
```
|
||||
|
||||
3. Commit and push any updates:
|
||||
```bash
|
||||
git add README.md skills_index.json
|
||||
git commit -m "Update README and skills index to resolve CI drift"
|
||||
git push
|
||||
```
|
||||
|
||||
**Summary**:
|
||||
Always commit and push all changes produced by the registry or readme update scripts. This keeps the CI workflow passing by ensuring the repository and generated files are synced.
|
||||
33
docs/COMMUNITY_GUIDELINES.md
Normal file
33
docs/COMMUNITY_GUIDELINES.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information without explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Enforcement
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1.
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
782
docs/EXAMPLES.md
782
docs/EXAMPLES.md
@@ -1,760 +1,56 @@
|
||||
# 💡 Real-World Examples - See Skills in Action
|
||||
# 🧪 Real-World Examples ("The Antigravity Cookbook")
|
||||
|
||||
**Learn by example!** This guide shows you real conversations using different skills.
|
||||
Skills are powerful on their own, but unstoppable when combined.
|
||||
Here are three common scenarios and how to solve them using this repository.
|
||||
|
||||
## 🥘 Recipe 1: The "Legacy Code Audit"
|
||||
|
||||
_Scenario: You just inherited a messy 5-year-old Node.js repo. You need to fix it safely._
|
||||
|
||||
**Skills Used:**
|
||||
|
||||
1. `concise-planning` (To map the chaos)
|
||||
2. `lint-and-validate` (To find the bugs)
|
||||
3. `security-audit` (To find the holes)
|
||||
|
||||
**The Workflow:**
|
||||
|
||||
1. **Plan**: "Agent, use `concise-planning` to create a checklist for refactoring `src/legacy-api.js`."
|
||||
2. **Audit**: "Run `security-audit` on the `package.json` to find vulnerable dependencies."
|
||||
3. **Fix**: "Use `lint-and-validate` rules to auto-fix the formatting issues in `src/`."
|
||||
|
||||
---
|
||||
|
||||
## Example 1: Designing a Feature with @brainstorming
|
||||
## 🥘 Recipe 2: The "Modern Web App"
|
||||
|
||||
### The Scenario
|
||||
You want to add a "dark mode" feature to your app, but you're not sure how to approach it.
|
||||
_Scenario: You need to build a high-performance Landing Page in 2 hours._
|
||||
|
||||
### The Conversation
|
||||
**Skills Used:**
|
||||
|
||||
```
|
||||
You: @brainstorming I want to add dark mode to my React app
|
||||
1. `frontend-design` (For aesthetics)
|
||||
2. `react-patterns` (For structure)
|
||||
3. `tailwind-mastery` (For speed)
|
||||
|
||||
AI: Great! Let me help you think through this. First, let me check your
|
||||
current project structure...
|
||||
|
||||
[AI examines your files]
|
||||
|
||||
I see you're using React with Tailwind CSS. Now, let's understand
|
||||
your requirements:
|
||||
|
||||
What's your primary goal for dark mode?
|
||||
a) User preference (toggle in settings)
|
||||
b) System preference (follow OS setting)
|
||||
c) Both (with manual override)
|
||||
**The Workflow:**
|
||||
|
||||
You: c) Both
|
||||
|
||||
AI: Perfect! That's the best user experience. Next question:
|
||||
|
||||
Where should the dark mode toggle be located?
|
||||
a) In the main navigation
|
||||
b) In a settings page
|
||||
c) In a dropdown menu
|
||||
d) Multiple locations
|
||||
|
||||
You: a) In the main navigation
|
||||
|
||||
AI: Good choice for accessibility. One more question:
|
||||
|
||||
Should dark mode preference persist across sessions?
|
||||
a) Yes, save to localStorage
|
||||
b) Yes, save to user account (requires backend)
|
||||
c) No, reset each session
|
||||
|
||||
You: a) Yes, save to localStorage
|
||||
|
||||
AI: Excellent! Now I have a clear picture. Let me present the design...
|
||||
|
||||
## Dark Mode Implementation Design
|
||||
|
||||
### Architecture Overview
|
||||
We'll use React Context for state management, Tailwind's dark mode
|
||||
utilities, and localStorage for persistence. The system will:
|
||||
1. Check OS preference on first visit
|
||||
2. Allow manual override via toggle
|
||||
3. Persist preference in localStorage
|
||||
|
||||
Does this approach look good so far?
|
||||
|
||||
You: Yes, continue
|
||||
|
||||
AI: [Continues with detailed design sections...]
|
||||
|
||||
[After design is complete]
|
||||
|
||||
I've saved the design to docs/plans/2026-01-20-dark-mode-design.md
|
||||
|
||||
Ready to set up for implementation?
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: I'll create an isolated workspace using git worktrees and write an
|
||||
implementation plan. One moment...
|
||||
```
|
||||
|
||||
### What Happened
|
||||
- ✅ AI asked focused questions one at a time
|
||||
- ✅ Explored your specific context
|
||||
- ✅ Presented design in sections
|
||||
- ✅ Saved documentation
|
||||
- ✅ Prepared for implementation
|
||||
1. **Design**: "Use `frontend-design` to generate a color palette and typography for a 'Cyberpunk Coffee Shop'."
|
||||
2. **Scaffold**: "Initialize a Vite project. Then apply `react-patterns` to create the 'Hero' component."
|
||||
3. **Style**: "Use `tailwind-mastery` to make the buttons glassmorphic and responsive."
|
||||
|
||||
---
|
||||
|
||||
## Example 2: Debugging with @systematic-debugging
|
||||
## 🥘 Recipe 3: The "Agent Architect"
|
||||
|
||||
### The Scenario
|
||||
Your tests are failing, but you're not sure why.
|
||||
_Scenario: You want to build a custom AI agent that can verify its own code._
|
||||
|
||||
### The Conversation
|
||||
**Skills Used:**
|
||||
|
||||
```
|
||||
You: @systematic-debugging My tests are failing with "Cannot read property
|
||||
'map' of undefined"
|
||||
1. `mcp-builder` (To build tools)
|
||||
2. `agent-evaluation` (To test reliability)
|
||||
3. `prompt-engineering` (To refine instructions)
|
||||
|
||||
AI: Let me help you debug this systematically. First, I'll gather information:
|
||||
|
||||
1. Running the failing test to see the full error...
|
||||
|
||||
[AI runs: npm test]
|
||||
|
||||
I see the error occurs in UserList.test.tsx at line 45. Let me examine
|
||||
the test file and the component...
|
||||
|
||||
[AI reads both files]
|
||||
|
||||
## Hypothesis
|
||||
The test is failing because `users` prop is undefined when the component
|
||||
renders. This suggests the mock data isn't being passed correctly.
|
||||
|
||||
## Verification
|
||||
Let me check the test setup...
|
||||
|
||||
[AI examines test]
|
||||
|
||||
Found it! The test is calling:
|
||||
```typescript
|
||||
render(<UserList />)
|
||||
```
|
||||
|
||||
But UserList requires a `users` prop. The component expects:
|
||||
```typescript
|
||||
interface UserListProps {
|
||||
users: User[];
|
||||
}
|
||||
```
|
||||
|
||||
## Solution
|
||||
The test should pass the users prop:
|
||||
```typescript
|
||||
const mockUsers = [
|
||||
{ id: 1, name: 'Alice' },
|
||||
{ id: 2, name: 'Bob' }
|
||||
];
|
||||
|
||||
render(<UserList users={mockUsers} />)
|
||||
```
|
||||
|
||||
Should I apply this fix?
|
||||
**The Workflow:**
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: [Applies fix and runs tests]
|
||||
|
||||
✅ All tests passing!
|
||||
|
||||
## Root Cause
|
||||
The test was missing required props. This is a common issue when
|
||||
components are refactored to require props that were previously optional.
|
||||
|
||||
## Prevention
|
||||
Consider adding TypeScript strict mode to catch these at compile time:
|
||||
```json
|
||||
"strict": true,
|
||||
"strictNullChecks": true
|
||||
```
|
||||
|
||||
Would you like me to add this to your tsconfig.json?
|
||||
```
|
||||
|
||||
### What Happened
|
||||
- ✅ Systematic investigation
|
||||
- ✅ Clear hypothesis
|
||||
- ✅ Verification before fixing
|
||||
- ✅ Root cause analysis
|
||||
- ✅ Prevention suggestions
|
||||
|
||||
---
|
||||
|
||||
## Example 3: Adding Payments with @stripe-integration
|
||||
|
||||
### The Scenario
|
||||
You need to add subscription billing to your SaaS app.
|
||||
|
||||
### The Conversation
|
||||
|
||||
```
|
||||
You: @stripe-integration I need to add monthly subscription billing
|
||||
|
||||
AI: I'll help you implement Stripe subscriptions. Let me understand your
|
||||
requirements:
|
||||
|
||||
Current stack detected:
|
||||
- Next.js 14 (App Router)
|
||||
- TypeScript
|
||||
- Prisma with PostgreSQL
|
||||
|
||||
For subscription billing, we'll need:
|
||||
|
||||
1. **Stripe Setup**
|
||||
- Stripe account and API keys
|
||||
- Webhook endpoint for events
|
||||
- Product and price IDs
|
||||
|
||||
2. **Backend Implementation**
|
||||
- API routes for checkout
|
||||
- Webhook handler
|
||||
- Database schema for subscriptions
|
||||
|
||||
3. **Frontend Implementation**
|
||||
- Pricing page
|
||||
- Checkout flow
|
||||
- Subscription management
|
||||
|
||||
Let's start with the backend. First, install dependencies:
|
||||
|
||||
```bash
|
||||
npm install stripe @stripe/stripe-js
|
||||
```
|
||||
|
||||
Now, let's create the database schema...
|
||||
|
||||
[AI provides Prisma schema]
|
||||
|
||||
```prisma
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
stripeCustomerId String? @unique
|
||||
subscriptions Subscription[]
|
||||
}
|
||||
|
||||
model Subscription {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
stripeSubscriptionId String @unique
|
||||
status String
|
||||
priceId String
|
||||
currentPeriodEnd DateTime
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
```
|
||||
|
||||
Next, let's create the checkout API route...
|
||||
|
||||
[AI provides complete implementation with:]
|
||||
- API route for creating checkout sessions
|
||||
- Webhook handler for subscription events
|
||||
- Helper functions for Stripe operations
|
||||
- Error handling and logging
|
||||
- TypeScript types
|
||||
|
||||
Now for the frontend...
|
||||
|
||||
[AI provides:]
|
||||
- Pricing page component
|
||||
- Checkout button component
|
||||
- Subscription status display
|
||||
- Tailwind styling
|
||||
|
||||
Finally, let's set up the webhook:
|
||||
|
||||
1. In Stripe Dashboard, add webhook endpoint:
|
||||
`https://yourdomain.com/api/webhooks/stripe`
|
||||
|
||||
2. Select these events:
|
||||
- customer.subscription.created
|
||||
- customer.subscription.updated
|
||||
- customer.subscription.deleted
|
||||
- invoice.payment_succeeded
|
||||
- invoice.payment_failed
|
||||
|
||||
3. Copy the webhook secret to your .env:
|
||||
```
|
||||
STRIPE_WEBHOOK_SECRET=whsec_...
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Test locally with Stripe CLI:
|
||||
```bash
|
||||
stripe listen --forward-to localhost:3000/api/webhooks/stripe
|
||||
stripe trigger customer.subscription.created
|
||||
```
|
||||
|
||||
## Security Checklist
|
||||
- ✅ API keys in environment variables
|
||||
- ✅ Webhook signature verification
|
||||
- ✅ Server-side price validation
|
||||
- ✅ Idempotency keys for operations
|
||||
|
||||
Ready to test the implementation?
|
||||
```
|
||||
|
||||
### What Happened
|
||||
- ✅ Detected existing stack
|
||||
- ✅ Provided complete implementation
|
||||
- ✅ Included database schema
|
||||
- ✅ Added security best practices
|
||||
- ✅ Included testing instructions
|
||||
|
||||
---
|
||||
|
||||
## Example 4: Writing Copy with @copywriting
|
||||
|
||||
### The Scenario
|
||||
You need compelling copy for your SaaS landing page.
|
||||
|
||||
### The Conversation
|
||||
|
||||
```
|
||||
You: @copywriting Write homepage copy for my project management tool
|
||||
|
||||
AI: I'll help you create compelling homepage copy. First, let me understand
|
||||
your product:
|
||||
|
||||
What makes your project management tool different from competitors
|
||||
like Asana, Trello, or Monday.com?
|
||||
|
||||
You: It's specifically built for remote teams with built-in video standups
|
||||
and async communication features
|
||||
|
||||
AI: Excellent differentiator! Who is your primary target audience?
|
||||
a) Startups and small teams (2-20 people)
|
||||
b) Mid-size companies (20-200 people)
|
||||
c) Enterprise (200+ people)
|
||||
d) Freelancers and agencies
|
||||
|
||||
You: a) Startups and small teams
|
||||
|
||||
AI: Perfect. What's the main pain point you solve?
|
||||
|
||||
You: Remote teams waste time in unnecessary meetings and lose context
|
||||
in async communication
|
||||
|
||||
AI: Great! Now I have what I need. Here's your homepage copy:
|
||||
|
||||
---
|
||||
|
||||
## Hero Section
|
||||
|
||||
**Headline:**
|
||||
Run Your Remote Team Without the Meeting Overload
|
||||
|
||||
**Subheadline:**
|
||||
The project management tool built for distributed teams. Replace
|
||||
status meetings with async video standups and keep everyone in sync
|
||||
without the Zoom fatigue.
|
||||
|
||||
**CTA:**
|
||||
Start Free Trial → (No credit card required)
|
||||
|
||||
---
|
||||
|
||||
## Problem Section
|
||||
|
||||
**Headline:**
|
||||
Remote Work Shouldn't Mean More Meetings
|
||||
|
||||
**Body:**
|
||||
Your team is distributed across time zones. You're spending hours in
|
||||
status meetings just to stay aligned. Async updates get lost in Slack.
|
||||
Context disappears. Productivity suffers.
|
||||
|
||||
Sound familiar?
|
||||
|
||||
---
|
||||
|
||||
## Solution Section
|
||||
|
||||
**Headline:**
|
||||
Stay Aligned Without the Meeting Marathon
|
||||
|
||||
**Features:**
|
||||
|
||||
📹 **Async Video Standups**
|
||||
Record quick video updates on your schedule. Your team watches when
|
||||
it works for them. No more 9am calls for your teammate in Tokyo.
|
||||
|
||||
💬 **Context-Rich Communication**
|
||||
Every task, comment, and decision stays connected. No more hunting
|
||||
through Slack threads or email chains.
|
||||
|
||||
📊 **Visual Progress Tracking**
|
||||
See what's happening at a glance. Kanban boards, timelines, and
|
||||
dashboards that actually make sense.
|
||||
|
||||
🔔 **Smart Notifications**
|
||||
Get notified about what matters. Ignore the rest. Your focus time
|
||||
is sacred.
|
||||
|
||||
---
|
||||
|
||||
## Social Proof Section
|
||||
|
||||
**Headline:**
|
||||
Trusted by Remote Teams Worldwide
|
||||
|
||||
[Testimonial placeholders with structure]
|
||||
|
||||
---
|
||||
|
||||
## CTA Section
|
||||
|
||||
**Headline:**
|
||||
Ready to Reclaim Your Calendar?
|
||||
|
||||
**Body:**
|
||||
Join 500+ remote teams who've cut meeting time by 60% while staying
|
||||
more aligned than ever.
|
||||
|
||||
**CTA:**
|
||||
Start Your Free 14-Day Trial →
|
||||
|
||||
No credit card required. Cancel anytime.
|
||||
|
||||
---
|
||||
|
||||
## Copy Notes
|
||||
|
||||
**Tone:** Professional but conversational
|
||||
**Focus:** Pain point (too many meetings) → Solution (async video)
|
||||
**Differentiation:** Built specifically for remote teams
|
||||
**Social proof:** Quantified benefit (60% fewer meetings)
|
||||
|
||||
Would you like me to:
|
||||
1. Write alternative versions for A/B testing?
|
||||
2. Create copy for specific feature pages?
|
||||
3. Write email sequences for onboarding?
|
||||
```
|
||||
|
||||
### What Happened
|
||||
- ✅ Asked clarifying questions
|
||||
- ✅ Identified unique value proposition
|
||||
- ✅ Created benefit-focused copy
|
||||
- ✅ Included clear CTAs
|
||||
- ✅ Provided copy notes for consistency
|
||||
|
||||
---
|
||||
|
||||
## Example 5: Test-Driven Development with @test-driven-development
|
||||
|
||||
### The Scenario
|
||||
You need to implement a new feature: user authentication.
|
||||
|
||||
### The Conversation
|
||||
|
||||
```
|
||||
You: @test-driven-development I need to implement user login functionality
|
||||
|
||||
AI: Perfect! Let's use TDD to build this. Following the Red-Green-Refactor
|
||||
cycle, we'll write tests first, then implement.
|
||||
|
||||
## Step 1: Write the First Test (RED)
|
||||
|
||||
Let's start with the simplest case - successful login:
|
||||
|
||||
```typescript
|
||||
// auth.test.ts
|
||||
import { login } from './auth';
|
||||
|
||||
describe('login', () => {
|
||||
it('should return user data for valid credentials', async () => {
|
||||
const result = await login({
|
||||
email: 'user@example.com',
|
||||
password: 'correct-password'
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.user).toHaveProperty('id');
|
||||
expect(result.user).toHaveProperty('email');
|
||||
expect(result.token).toBeDefined();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
Let's run this test to see it fail:
|
||||
|
||||
[AI runs: npm test]
|
||||
|
||||
✅ Test fails as expected (auth.ts doesn't exist yet)
|
||||
|
||||
## Step 2: Write Minimal Implementation (GREEN)
|
||||
|
||||
Now let's write just enough code to make this test pass:
|
||||
|
||||
```typescript
|
||||
// auth.ts
|
||||
interface LoginCredentials {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface LoginResult {
|
||||
success: boolean;
|
||||
user?: {
|
||||
id: string;
|
||||
email: string;
|
||||
};
|
||||
token?: string;
|
||||
}
|
||||
|
||||
export async function login(
|
||||
credentials: LoginCredentials
|
||||
): Promise<LoginResult> {
|
||||
// Minimal implementation to pass the test
|
||||
return {
|
||||
success: true,
|
||||
user: {
|
||||
id: '1',
|
||||
email: credentials.email
|
||||
},
|
||||
token: 'fake-token'
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
[AI runs: npm test]
|
||||
|
||||
✅ Test passes!
|
||||
|
||||
## Step 3: Add Next Test (RED)
|
||||
|
||||
Now let's test the failure case:
|
||||
|
||||
```typescript
|
||||
it('should return error for invalid credentials', async () => {
|
||||
const result = await login({
|
||||
email: 'user@example.com',
|
||||
password: 'wrong-password'
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Invalid credentials');
|
||||
expect(result.user).toBeUndefined();
|
||||
expect(result.token).toBeUndefined();
|
||||
});
|
||||
```
|
||||
|
||||
[AI runs: npm test]
|
||||
|
||||
❌ Test fails (always returns success)
|
||||
|
||||
## Step 4: Implement Real Logic (GREEN)
|
||||
|
||||
Now let's add actual authentication:
|
||||
|
||||
```typescript
|
||||
import bcrypt from 'bcrypt';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { db } from './db';
|
||||
|
||||
export async function login(
|
||||
credentials: LoginCredentials
|
||||
): Promise<LoginResult> {
|
||||
// Find user
|
||||
const user = await db.user.findUnique({
|
||||
where: { email: credentials.email }
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Invalid credentials'
|
||||
};
|
||||
}
|
||||
|
||||
// Verify password
|
||||
const validPassword = await bcrypt.compare(
|
||||
credentials.password,
|
||||
user.passwordHash
|
||||
);
|
||||
|
||||
if (!validPassword) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Invalid credentials'
|
||||
};
|
||||
}
|
||||
|
||||
// Generate token
|
||||
const token = jwt.sign(
|
||||
{ userId: user.id },
|
||||
process.env.JWT_SECRET!,
|
||||
{ expiresIn: '7d' }
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
user: {
|
||||
id: user.id,
|
||||
email: user.email
|
||||
},
|
||||
token
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
[AI runs: npm test]
|
||||
|
||||
✅ All tests pass!
|
||||
|
||||
## Step 5: Add Edge Cases
|
||||
|
||||
Let's add more tests for edge cases:
|
||||
|
||||
```typescript
|
||||
it('should handle missing email', async () => {
|
||||
const result = await login({
|
||||
email: '',
|
||||
password: 'password'
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Email is required');
|
||||
});
|
||||
|
||||
it('should handle missing password', async () => {
|
||||
const result = await login({
|
||||
email: 'user@example.com',
|
||||
password: ''
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Password is required');
|
||||
});
|
||||
|
||||
it('should handle database errors gracefully', async () => {
|
||||
// Mock database error
|
||||
jest.spyOn(db.user, 'findUnique').mockRejectedValue(
|
||||
new Error('Database connection failed')
|
||||
);
|
||||
|
||||
const result = await login({
|
||||
email: 'user@example.com',
|
||||
password: 'password'
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('An error occurred');
|
||||
});
|
||||
```
|
||||
|
||||
[AI implements validation and error handling]
|
||||
|
||||
## Step 6: Refactor (REFACTOR)
|
||||
|
||||
Now that all tests pass, let's refactor for better code quality:
|
||||
|
||||
```typescript
|
||||
// Extract validation
|
||||
function validateCredentials(credentials: LoginCredentials): string | null {
|
||||
if (!credentials.email) return 'Email is required';
|
||||
if (!credentials.password) return 'Password is required';
|
||||
return null;
|
||||
}
|
||||
|
||||
// Extract user verification
|
||||
async function verifyUser(
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<User | null> {
|
||||
const user = await db.user.findUnique({ where: { email } });
|
||||
if (!user) return null;
|
||||
|
||||
const valid = await bcrypt.compare(password, user.passwordHash);
|
||||
return valid ? user : null;
|
||||
}
|
||||
|
||||
// Main function is now cleaner
|
||||
export async function login(
|
||||
credentials: LoginCredentials
|
||||
): Promise<LoginResult> {
|
||||
try {
|
||||
const validationError = validateCredentials(credentials);
|
||||
if (validationError) {
|
||||
return { success: false, error: validationError };
|
||||
}
|
||||
|
||||
const user = await verifyUser(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
if (!user) {
|
||||
return { success: false, error: 'Invalid credentials' };
|
||||
}
|
||||
|
||||
const token = generateToken(user.id);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
user: { id: user.id, email: user.email },
|
||||
token
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Login error:', error);
|
||||
return { success: false, error: 'An error occurred' };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[AI runs: npm test]
|
||||
|
||||
✅ All tests still pass after refactoring!
|
||||
|
||||
## Summary
|
||||
|
||||
We've implemented login functionality using TDD:
|
||||
- ✅ 5 tests covering happy path, errors, and edge cases
|
||||
- ✅ Clean, testable code
|
||||
- ✅ Proper error handling
|
||||
- ✅ Type safety with TypeScript
|
||||
|
||||
Next steps:
|
||||
1. Add rate limiting tests
|
||||
2. Add session management tests
|
||||
3. Add logout functionality
|
||||
|
||||
Should I continue with these?
|
||||
```
|
||||
|
||||
### What Happened
|
||||
- ✅ Followed Red-Green-Refactor cycle
|
||||
- ✅ Wrote tests before implementation
|
||||
- ✅ Covered edge cases
|
||||
- ✅ Refactored with confidence
|
||||
- ✅ Maintained test coverage
|
||||
|
||||
---
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
### What Makes These Examples Effective?
|
||||
|
||||
1. **Skills ask clarifying questions** before jumping to solutions
|
||||
2. **Skills provide context-aware help** based on your project
|
||||
3. **Skills follow best practices** for their domain
|
||||
4. **Skills include complete examples** not just snippets
|
||||
5. **Skills explain the "why"** not just the "how"
|
||||
|
||||
### How to Get Similar Results
|
||||
|
||||
1. **Be specific** in your requests
|
||||
2. **Provide context** about your project
|
||||
3. **Answer questions** the skill asks
|
||||
4. **Review suggestions** before applying
|
||||
5. **Iterate** based on results
|
||||
|
||||
---
|
||||
|
||||
## Try These Yourself!
|
||||
|
||||
Pick a skill and try it with your own project:
|
||||
|
||||
- **Planning:** `@brainstorming` or `@writing-plans`
|
||||
- **Development:** `@test-driven-development` or `@react-best-practices`
|
||||
- **Debugging:** `@systematic-debugging` or `@test-fixing`
|
||||
- **Integration:** `@stripe-integration` or `@firebase`
|
||||
- **Marketing:** `@copywriting` or `@seo-audit`
|
||||
|
||||
---
|
||||
|
||||
**Want more examples?** Check individual skill folders for additional examples and use cases!
|
||||
1. **Build**: "Use `mcp-builder` to create a `verify-file` tool."
|
||||
2. **Instruct**: "Apply `prompt-engineering` patterns to the System Prompt so the agent always checks file paths."
|
||||
3. **Test**: "Run `agent-evaluation` to benchmark how often the agent fails to find the file."
|
||||
|
||||
64
docs/QUALITY_BAR.md
Normal file
64
docs/QUALITY_BAR.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# 🏆 Quality Bar & Validation Standards
|
||||
|
||||
To transform **Antigravity Awesome Skills** from a collection of scripts into a trusted platform, every skill must meet a specific standard of quality and safety.
|
||||
|
||||
## The "Validated" Badge ✅
|
||||
|
||||
A skill earns the "Validated" badge only if it passes these **5 automated checks**:
|
||||
|
||||
### 1. Metadata Integrity
|
||||
|
||||
The `SKILL.md` frontmatter must be valid YAML and contain:
|
||||
|
||||
- `name`: Kebab-case, matches folder name.
|
||||
- `description`: Under 200 chars, clear value prop.
|
||||
- `risk`: One of `[none, safe, critical, offensive]`.
|
||||
- `source`: URL to original source (or "self" if original).
|
||||
|
||||
### 2. Clear Triggers ("When to use")
|
||||
|
||||
The skill MUST have a section explicitly stating when to trigger it.
|
||||
|
||||
- **Good**: "Use when the user asks to debug a React component."
|
||||
- **Bad**: "This skill helps you with code."
|
||||
|
||||
### 3. Safety & Risk Classification
|
||||
|
||||
Every skill must declare its risk level:
|
||||
|
||||
- 🟢 **none**: Pure text/reasoning (e.g., Brainstorming).
|
||||
- 🔵 **safe**: Reads files, runs safe commands (e.g., Linter).
|
||||
- 🟠 **critical**: Modifies state, deletes files, pushes to prod (e.g., Git Push).
|
||||
- 🔴 **offensive**: Pentesting/Red Team tools. **MUST** have "Authorized Use Only" warning.
|
||||
|
||||
### 4. Copy-Pasteable Examples
|
||||
|
||||
At least one code block or interaction example that a user (or agent) can immediately use.
|
||||
|
||||
### 5. Explicit Limitations
|
||||
|
||||
A list of known edge cases or things the skill _cannot_ do.
|
||||
|
||||
- _Example_: "Does not work on Windows without WSL."
|
||||
|
||||
---
|
||||
|
||||
## Support Levels
|
||||
|
||||
We also categorize skills by who maintains them:
|
||||
|
||||
| Level | Badge | Meaning |
|
||||
| :------------ | :---- | :-------------------------------------------------- |
|
||||
| **Official** | 🟣 | Maintained by the core team. High reliability. |
|
||||
| **Community** | ⚪ | Contributed by the ecosystem. Best effort support. |
|
||||
| **Verified** | ✨ | Community skill that has passed deep manual review. |
|
||||
|
||||
---
|
||||
|
||||
## How to Validate Your Skill
|
||||
|
||||
Run the validator script before submitting a PR:
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_skills.py --strict
|
||||
```
|
||||
51
docs/SECURITY_GUARDRAILS.md
Normal file
51
docs/SECURITY_GUARDRAILS.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 🛡️ Security Guardrails & Policy
|
||||
|
||||
Antigravity Awesome Skills is a powerful toolkit. With great power comes great responsibility. This document defines the **Rules of Engagement** for all security and offensive capabilities in this repository.
|
||||
|
||||
## 🔴 Offensive Skills Policy (The "Red Line")
|
||||
|
||||
**What is an Offensive Skill?**
|
||||
Any skill designed to penetrate, exploit, disrupt, or simulate attacks against systems.
|
||||
_Examples: Pentesting, SQL Injection, Phishing Simulation, Red Teaming._
|
||||
|
||||
### 1. The "Authorized Use Only" Disclaimer
|
||||
|
||||
Every offensive skill **MUST** begin with this exact disclaimer in its `SKILL.md`:
|
||||
|
||||
> **⚠️ AUTHORIZED USE ONLY**
|
||||
> This skill is for educational purposes or authorized security assessments only.
|
||||
> You must have explicit, written permission from the system owner before using this tool.
|
||||
> Misuse of this tool is illegal and strictly prohibited.
|
||||
|
||||
### 2. Mandatory User Confirmation
|
||||
|
||||
Offensive skills must **NEVER** run fully autonomously.
|
||||
|
||||
- **Requirement**: The skill description/instructions must explicitly tell the agent to _ask for user confirmation_ before executing any exploit or attack command.
|
||||
- **Agent Instruction**: "Ask the user to verify the target URL/IP before running."
|
||||
|
||||
### 3. Safe by Design
|
||||
|
||||
- **No Weaponized Payloads**: Skills should not include active malware, ransomware, or non-educational exploits.
|
||||
- **Sandbox Recommended**: Instructions should recommend running in a contained environment (Docker/VM).
|
||||
|
||||
---
|
||||
|
||||
## 🔵 Defensive Skills Policy
|
||||
|
||||
**What is a Defensive Skill?**
|
||||
Tools for hardening, auditing, monitoring, or protecting systems.
|
||||
_Examples: Linting, Log Analysis, Configuration Auditing._
|
||||
|
||||
- **Data Privacy**: Defensive skills must not upload data to 3rd party servers without explicit user consent.
|
||||
- **Non-Destructive**: Audits should be read-only by default.
|
||||
|
||||
---
|
||||
|
||||
## ⚖️ Legal Disclaimer
|
||||
|
||||
By using this repository, you agree that:
|
||||
|
||||
1. You are responsible for your own actions.
|
||||
2. The authors and contributors are not liable for any damage caused by these tools.
|
||||
3. You will comply with all local, state, and federal laws regarding cybersecurity.
|
||||
@@ -31,6 +31,7 @@ skills/
|
||||
Every `SKILL.md` file has two main parts:
|
||||
|
||||
### 1. Frontmatter (Metadata)
|
||||
|
||||
### 2. Content (Instructions)
|
||||
|
||||
Let's break down each part:
|
||||
@@ -51,12 +52,14 @@ description: "Brief description of what this skill does"
|
||||
### Required Fields
|
||||
|
||||
#### `name`
|
||||
|
||||
- **What it is:** The skill's identifier
|
||||
- **Format:** lowercase-with-hyphens
|
||||
- **Must match:** The folder name exactly
|
||||
- **Example:** `stripe-integration`
|
||||
|
||||
#### `description`
|
||||
|
||||
- **What it is:** One-sentence summary
|
||||
- **Format:** String in quotes
|
||||
- **Length:** Keep it under 150 characters
|
||||
@@ -70,9 +73,9 @@ Some skills include additional metadata:
|
||||
---
|
||||
name: my-skill-name
|
||||
description: "Brief description"
|
||||
version: "1.0.0"
|
||||
author: "Your Name"
|
||||
tags: ["react", "typescript", "testing"]
|
||||
risk: "safe" # safe | risk | official
|
||||
source: "community"
|
||||
tags: ["react", "typescript"]
|
||||
---
|
||||
```
|
||||
|
||||
@@ -85,13 +88,16 @@ After the frontmatter comes the actual skill content. Here's the recommended str
|
||||
### Recommended Sections
|
||||
|
||||
#### 1. Title (H1)
|
||||
|
||||
```markdown
|
||||
# Skill Title
|
||||
```
|
||||
|
||||
- Use a clear, descriptive title
|
||||
- Usually matches or expands on the skill name
|
||||
|
||||
#### 2. Overview
|
||||
|
||||
```markdown
|
||||
## Overview
|
||||
|
||||
@@ -100,6 +106,7 @@ A brief explanation of what this skill does and why it exists.
|
||||
```
|
||||
|
||||
#### 3. When to Use
|
||||
|
||||
```markdown
|
||||
## When to Use This Skill
|
||||
|
||||
@@ -111,28 +118,34 @@ A brief explanation of what this skill does and why it exists.
|
||||
**Why this matters:** Helps the AI know when to activate this skill
|
||||
|
||||
#### 4. Core Instructions
|
||||
|
||||
```markdown
|
||||
## How It Works
|
||||
|
||||
### Step 1: [Action]
|
||||
|
||||
Detailed instructions...
|
||||
|
||||
### Step 2: [Action]
|
||||
|
||||
More instructions...
|
||||
```
|
||||
|
||||
**This is the heart of your skill** - clear, actionable steps
|
||||
|
||||
#### 5. Examples
|
||||
|
||||
```markdown
|
||||
## Examples
|
||||
|
||||
### Example 1: [Use Case]
|
||||
|
||||
\`\`\`javascript
|
||||
// Example code
|
||||
\`\`\`
|
||||
|
||||
### Example 2: [Another Use Case]
|
||||
|
||||
\`\`\`javascript
|
||||
// More code
|
||||
\`\`\`
|
||||
@@ -141,6 +154,7 @@ More instructions...
|
||||
**Why examples matter:** They show the AI exactly what good output looks like
|
||||
|
||||
#### 6. Best Practices
|
||||
|
||||
```markdown
|
||||
## Best Practices
|
||||
|
||||
@@ -151,6 +165,7 @@ More instructions...
|
||||
```
|
||||
|
||||
#### 7. Common Pitfalls
|
||||
|
||||
```markdown
|
||||
## Common Pitfalls
|
||||
|
||||
@@ -159,6 +174,7 @@ More instructions...
|
||||
```
|
||||
|
||||
#### 8. Related Skills
|
||||
|
||||
```markdown
|
||||
## Related Skills
|
||||
|
||||
@@ -173,11 +189,13 @@ More instructions...
|
||||
### Use Clear, Direct Language
|
||||
|
||||
**❌ Bad:**
|
||||
|
||||
```markdown
|
||||
You might want to consider possibly checking if the user has authentication.
|
||||
```
|
||||
|
||||
**✅ Good:**
|
||||
|
||||
```markdown
|
||||
Check if the user is authenticated before proceeding.
|
||||
```
|
||||
@@ -185,11 +203,13 @@ Check if the user is authenticated before proceeding.
|
||||
### Use Action Verbs
|
||||
|
||||
**❌ Bad:**
|
||||
|
||||
```markdown
|
||||
The file should be created...
|
||||
```
|
||||
|
||||
**✅ Good:**
|
||||
|
||||
```markdown
|
||||
Create the file...
|
||||
```
|
||||
@@ -197,11 +217,13 @@ Create the file...
|
||||
### Be Specific
|
||||
|
||||
**❌ Bad:**
|
||||
|
||||
```markdown
|
||||
Set up the database properly.
|
||||
```
|
||||
|
||||
**✅ Good:**
|
||||
|
||||
```markdown
|
||||
1. Create a PostgreSQL database
|
||||
2. Run migrations: `npm run migrate`
|
||||
@@ -224,6 +246,7 @@ scripts/
|
||||
```
|
||||
|
||||
**Reference them in SKILL.md:**
|
||||
|
||||
```markdown
|
||||
Run the setup script:
|
||||
\`\`\`bash
|
||||
@@ -256,6 +279,7 @@ templates/
|
||||
```
|
||||
|
||||
**Reference in SKILL.md:**
|
||||
|
||||
```markdown
|
||||
Use this template as a starting point:
|
||||
\`\`\`typescript
|
||||
@@ -279,16 +303,19 @@ references/
|
||||
## Skill Size Guidelines
|
||||
|
||||
### Minimum Viable Skill
|
||||
|
||||
- **Frontmatter:** name + description
|
||||
- **Content:** 100-200 words
|
||||
- **Sections:** Overview + Instructions
|
||||
|
||||
### Standard Skill
|
||||
|
||||
- **Frontmatter:** name + description
|
||||
- **Content:** 300-800 words
|
||||
- **Sections:** Overview + When to Use + Instructions + Examples
|
||||
|
||||
### Comprehensive Skill
|
||||
|
||||
- **Frontmatter:** name + description + optional fields
|
||||
- **Content:** 800-2000 words
|
||||
- **Sections:** All recommended sections
|
||||
@@ -303,7 +330,9 @@ references/
|
||||
### Use Markdown Effectively
|
||||
|
||||
#### Code Blocks
|
||||
|
||||
Always specify the language:
|
||||
|
||||
```markdown
|
||||
\`\`\`javascript
|
||||
const example = "code";
|
||||
@@ -311,7 +340,9 @@ const example = "code";
|
||||
```
|
||||
|
||||
#### Lists
|
||||
|
||||
Use consistent formatting:
|
||||
|
||||
```markdown
|
||||
- Item 1
|
||||
- Item 2
|
||||
@@ -320,11 +351,13 @@ Use consistent formatting:
|
||||
```
|
||||
|
||||
#### Emphasis
|
||||
|
||||
- **Bold** for important terms: `**important**`
|
||||
- *Italic* for emphasis: `*emphasis*`
|
||||
- _Italic_ for emphasis: `*emphasis*`
|
||||
- `Code` for commands/code: `` `code` ``
|
||||
|
||||
#### Links
|
||||
|
||||
```markdown
|
||||
[Link text](https://example.com)
|
||||
```
|
||||
@@ -336,24 +369,28 @@ Use consistent formatting:
|
||||
Before finalizing your skill:
|
||||
|
||||
### Content Quality
|
||||
|
||||
- [ ] Instructions are clear and actionable
|
||||
- [ ] Examples are realistic and helpful
|
||||
- [ ] No typos or grammar errors
|
||||
- [ ] Technical accuracy verified
|
||||
|
||||
### Structure
|
||||
|
||||
- [ ] Frontmatter is valid YAML
|
||||
- [ ] Name matches folder name
|
||||
- [ ] Sections are logically organized
|
||||
- [ ] Headings follow hierarchy (H1 → H2 → H3)
|
||||
|
||||
### Completeness
|
||||
|
||||
- [ ] Overview explains the "why"
|
||||
- [ ] Instructions explain the "how"
|
||||
- [ ] Examples show the "what"
|
||||
- [ ] Edge cases are addressed
|
||||
|
||||
### Usability
|
||||
|
||||
- [ ] A beginner could follow this
|
||||
- [ ] An expert would find it useful
|
||||
- [ ] The AI can parse it correctly
|
||||
@@ -373,6 +410,7 @@ description: "You MUST use this before any creative work..."
|
||||
```
|
||||
|
||||
**Analysis:**
|
||||
|
||||
- ✅ Clear name
|
||||
- ✅ Strong description with urgency ("MUST use")
|
||||
- ✅ Explains when to use it
|
||||
@@ -381,10 +419,12 @@ description: "You MUST use this before any creative work..."
|
||||
# Brainstorming Ideas Into Designs
|
||||
|
||||
## Overview
|
||||
|
||||
Help turn ideas into fully formed designs...
|
||||
```
|
||||
|
||||
**Analysis:**
|
||||
|
||||
- ✅ Clear title
|
||||
- ✅ Concise overview
|
||||
- ✅ Explains the value proposition
|
||||
@@ -393,11 +433,13 @@ Help turn ideas into fully formed designs...
|
||||
## The Process
|
||||
|
||||
**Understanding the idea:**
|
||||
|
||||
- Check out the current project state first
|
||||
- Ask questions one at a time
|
||||
```
|
||||
|
||||
**Analysis:**
|
||||
|
||||
- ✅ Broken into clear phases
|
||||
- ✅ Specific, actionable steps
|
||||
- ✅ Easy to follow
|
||||
@@ -412,10 +454,12 @@ Help turn ideas into fully formed designs...
|
||||
## Instructions
|
||||
|
||||
If the user is working with React:
|
||||
|
||||
- Use functional components
|
||||
- Prefer hooks over class components
|
||||
|
||||
If the user is working with Vue:
|
||||
|
||||
- Use Composition API
|
||||
- Follow Vue 3 patterns
|
||||
```
|
||||
@@ -424,9 +468,11 @@ If the user is working with Vue:
|
||||
|
||||
```markdown
|
||||
## Basic Usage
|
||||
|
||||
[Simple instructions for common cases]
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
[Complex patterns for power users]
|
||||
```
|
||||
|
||||
@@ -447,15 +493,18 @@ If the user is working with Vue:
|
||||
How to know if your skill is good:
|
||||
|
||||
### Clarity Test
|
||||
|
||||
- Can someone unfamiliar with the topic follow it?
|
||||
- Are there any ambiguous instructions?
|
||||
|
||||
### Completeness Test
|
||||
|
||||
- Does it cover the happy path?
|
||||
- Does it handle edge cases?
|
||||
- Are error scenarios addressed?
|
||||
|
||||
### Usefulness Test
|
||||
|
||||
- Does it solve a real problem?
|
||||
- Would you use this yourself?
|
||||
- Does it save time or improve quality?
|
||||
@@ -467,11 +516,13 @@ How to know if your skill is good:
|
||||
### Study These Examples
|
||||
|
||||
**For Beginners:**
|
||||
|
||||
- `skills/brainstorming/SKILL.md` - Clear structure
|
||||
- `skills/git-pushing/SKILL.md` - Simple and focused
|
||||
- `skills/copywriting/SKILL.md` - Good examples
|
||||
|
||||
**For Advanced:**
|
||||
|
||||
- `skills/systematic-debugging/SKILL.md` - Comprehensive
|
||||
- `skills/react-best-practices/SKILL.md` - Multiple files
|
||||
- `skills/loki-mode/SKILL.md` - Complex workflows
|
||||
@@ -491,22 +542,28 @@ How to know if your skill is good:
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
### ❌ Mistake 1: Too Vague
|
||||
|
||||
```markdown
|
||||
## Instructions
|
||||
|
||||
Make the code better.
|
||||
```
|
||||
|
||||
**✅ Fix:**
|
||||
|
||||
```markdown
|
||||
## Instructions
|
||||
|
||||
1. Extract repeated logic into functions
|
||||
2. Add error handling for edge cases
|
||||
3. Write unit tests for core functionality
|
||||
```
|
||||
|
||||
### ❌ Mistake 2: Too Complex
|
||||
|
||||
```markdown
|
||||
## Instructions
|
||||
|
||||
[5000 words of dense technical jargon]
|
||||
```
|
||||
|
||||
@@ -514,8 +571,10 @@ Make the code better.
|
||||
Break into multiple skills or use progressive disclosure
|
||||
|
||||
### ❌ Mistake 3: No Examples
|
||||
|
||||
```markdown
|
||||
## Instructions
|
||||
|
||||
[Instructions without any code examples]
|
||||
```
|
||||
|
||||
@@ -523,6 +582,7 @@ Break into multiple skills or use progressive disclosure
|
||||
Add at least 2-3 realistic examples
|
||||
|
||||
### ❌ Mistake 4: Outdated Information
|
||||
|
||||
```markdown
|
||||
Use React class components...
|
||||
```
|
||||
|
||||
21
docs/SOURCES.md
Normal file
21
docs/SOURCES.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# 📜 Sources & Attributions
|
||||
|
||||
We believe in giving credit where credit is due.
|
||||
If you recognize your work here and it is not properly attributed, please open an Issue.
|
||||
|
||||
| Skill / Category | Original Source | License | Notes |
|
||||
| :-------------------------- | :----------------------------------------------------- | :------------- | :---------------------------- |
|
||||
| `cloud-penetration-testing` | [HackTricks](https://book.hacktricks.xyz/) | MIT / CC-BY-SA | Adapted for agentic use. |
|
||||
| `active-directory-attacks` | [HackTricks](https://book.hacktricks.xyz/) | MIT / CC-BY-SA | Adapted for agentic use. |
|
||||
| `owasp-top-10` | [OWASP](https://owasp.org/) | CC-BY-SA | Methodology adapted. |
|
||||
| `burp-suite-testing` | [PortSwigger](https://portswigger.net/burp) | N/A | Usage guide only (no binary). |
|
||||
| `crewai` | [CrewAI](https://github.com/joaomdmoura/crewAI) | MIT | Framework guides. |
|
||||
| `langgraph` | [LangGraph](https://github.com/langchain-ai/langgraph) | MIT | Framework guides. |
|
||||
| `react-patterns` | [React Docs](https://react.dev/) | CC-BY | Official patterns. |
|
||||
| **All Official Skills** | [Anthropic / Google / OpenAI] | Proprietary | Usage encouraged by vendors. |
|
||||
|
||||
## License Policy
|
||||
|
||||
- **Code**: All original code in this repository is **MIT**.
|
||||
- **Content**: Documentation is **CC-BY-4.0**.
|
||||
- **Third Party**: We respect the upstream licenses. If an imported skill is GPL, it will be marked clearly or excluded (we aim for MIT/Apache compatibility).
|
||||
@@ -32,9 +32,10 @@ antigravity-awesome-skills/
|
||||
│
|
||||
├── 📄 README.md ← Overview & skill list
|
||||
├── 📄 GETTING_STARTED.md ← Start here! (NEW)
|
||||
├── 📄 CONTRIBUTING.md ← How to contribute (NEW)
|
||||
├── 📄 CONTRIBUTING.md ← How to contribute
|
||||
├── 📄 FAQ.md ← Troubleshooting
|
||||
│
|
||||
├── 📁 skills/ ← All 179 skills live here
|
||||
├── 📁 skills/ ← All 250+ skills live here
|
||||
│ │
|
||||
│ ├── 📁 brainstorming/
|
||||
│ │ └── 📄 SKILL.md ← Skill definition
|
||||
@@ -43,20 +44,20 @@ antigravity-awesome-skills/
|
||||
│ │ ├── 📄 SKILL.md
|
||||
│ │ └── 📁 examples/ ← Optional extras
|
||||
│ │
|
||||
│ ├── 📁 react-best-practices/
|
||||
│ │ ├── 📄 SKILL.md
|
||||
│ │ ├── 📁 rules/
|
||||
│ │ └── 📄 README.md
|
||||
│ │
|
||||
│ └── ... (176 more skills)
|
||||
│ └── ... (250+ more skills)
|
||||
│
|
||||
├── 📁 scripts/ ← Validation & management
|
||||
│ ├── validate_skills.py
|
||||
│ └── generate_index.py
|
||||
│ ├── validate_skills.py ← Quality Bar Enforcer
|
||||
│ └── generate_index.py ← Registry Generator
|
||||
│
|
||||
└── 📁 docs/ ← Documentation (NEW)
|
||||
├── 📁 .github/
|
||||
│ └── 📄 MAINTENANCE.md ← Maintainers Guide
|
||||
│
|
||||
└── 📁 docs/ ← Documentation
|
||||
├── 📄 BUNDLES.md ← Starter Packs (NEW)
|
||||
├── 📄 QUALITY_BAR.md ← Quality Standards
|
||||
├── 📄 SKILL_ANATOMY.md ← How skills work
|
||||
└── 📄 VISUAL_GUIDE.md ← This file!
|
||||
└── 📄 VISUAL_GUIDE.md ← This file!
|
||||
```
|
||||
|
||||
---
|
||||
@@ -95,7 +96,7 @@ antigravity-awesome-skills/
|
||||
|
||||
```
|
||||
┌─────────────────────────┐
|
||||
│ 179 AWESOME SKILLS │
|
||||
│ 250+ AWESOME SKILLS │
|
||||
└────────────┬────────────┘
|
||||
│
|
||||
┌────────────────────────┼────────────────────────┐
|
||||
@@ -129,7 +130,7 @@ antigravity-awesome-skills/
|
||||
|
||||
## Skill File Anatomy (Visual)
|
||||
|
||||
```
|
||||
````
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ SKILL.md │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
@@ -167,13 +168,14 @@ antigravity-awesome-skills/
|
||||
│ └───────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Installation (Visual Steps)
|
||||
|
||||
### Step 1: Clone the Repository
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Terminal │
|
||||
@@ -188,6 +190,7 @@ antigravity-awesome-skills/
|
||||
```
|
||||
|
||||
### Step 2: Verify Installation
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ File Explorer │
|
||||
@@ -202,6 +205,7 @@ antigravity-awesome-skills/
|
||||
```
|
||||
|
||||
### Step 3: Use a Skill
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ AI Assistant Chat │
|
||||
@@ -271,16 +275,19 @@ antigravity-awesome-skills/
|
||||
## Finding Skills (Visual Guide)
|
||||
|
||||
### Method 1: Browse by Category
|
||||
|
||||
```
|
||||
README.md → Scroll to "Full Skill Registry" → Find category → Pick skill
|
||||
```
|
||||
|
||||
### Method 2: Search by Keyword
|
||||
|
||||
```
|
||||
Terminal → ls skills/ | grep "keyword" → See matching skills
|
||||
```
|
||||
|
||||
### Method 3: Use the Index
|
||||
|
||||
```
|
||||
Open skills_index.json → Search for keyword → Find skill path
|
||||
```
|
||||
@@ -465,19 +472,19 @@ START HERE
|
||||
Day 1: Install skills
|
||||
│
|
||||
└─→ "Wow, @brainstorming helped me design my app!"
|
||||
|
||||
|
||||
Day 3: Use 5 different skills
|
||||
│
|
||||
└─→ "These skills save me so much time!"
|
||||
|
||||
|
||||
Week 1: Create first skill
|
||||
│
|
||||
└─→ "I shared my expertise as a skill!"
|
||||
|
||||
|
||||
Week 2: Skill gets merged
|
||||
│
|
||||
└─→ "My skill is helping others! 🎉"
|
||||
|
||||
|
||||
Month 1: Regular contributor
|
||||
│
|
||||
└─→ "I've contributed 5 skills and improved docs!"
|
||||
@@ -497,6 +504,7 @@ Month 1: Regular contributor
|
||||
---
|
||||
|
||||
**Visual learner?** This guide should help! Still have questions? Check out:
|
||||
|
||||
- [GETTING_STARTED.md](../GETTING_STARTED.md) - Text-based intro
|
||||
- [SKILL_ANATOMY.md](SKILL_ANATOMY.md) - Detailed breakdown
|
||||
- [CONTRIBUTING.md](../CONTRIBUTING.md) - How to contribute
|
||||
|
||||
@@ -2,69 +2,90 @@ import os
|
||||
import json
|
||||
import re
|
||||
|
||||
import yaml
|
||||
|
||||
def parse_frontmatter(content):
|
||||
"""
|
||||
Parses YAML frontmatter using PyYAML for standard compliance.
|
||||
"""
|
||||
fm_match = re.search(r'^---\s*\n(.*?)\n---', content, re.DOTALL)
|
||||
if not fm_match:
|
||||
return {}
|
||||
|
||||
try:
|
||||
return yaml.safe_load(fm_match.group(1)) or {}
|
||||
except yaml.YAMLError as e:
|
||||
print(f"⚠️ YAML parsing error: {e}")
|
||||
return {}
|
||||
|
||||
def generate_index(skills_dir, output_file):
|
||||
print(f"🏗️ Generating index from: {skills_dir}")
|
||||
skills = []
|
||||
|
||||
for root, dirs, files in os.walk(skills_dir):
|
||||
# Skip .disabled directories
|
||||
dirs[:] = [d for d in dirs if d != '.disabled']
|
||||
# Skip .disabled or hidden directories
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.')]
|
||||
|
||||
if "SKILL.md" in files:
|
||||
skill_path = os.path.join(root, "SKILL.md")
|
||||
dir_name = os.path.basename(root)
|
||||
parent_dir = os.path.basename(os.path.dirname(root))
|
||||
|
||||
# Default values
|
||||
skill_info = {
|
||||
"id": dir_name,
|
||||
"path": os.path.relpath(root, os.path.dirname(skills_dir)),
|
||||
"category": parent_dir if parent_dir != "skills" else "uncategorized",
|
||||
"name": dir_name.replace("-", " ").title(),
|
||||
"description": ""
|
||||
"description": "",
|
||||
"risk": "unknown",
|
||||
"source": "unknown"
|
||||
}
|
||||
|
||||
with open(skill_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# Try to extract from frontmatter first
|
||||
fm_match = re.search(r'^---\s*(.*?)\s*---', content, re.DOTALL)
|
||||
if fm_match:
|
||||
fm_content = fm_match.group(1)
|
||||
name_fm = re.search(r'^name:\s*(.+)$', fm_content, re.MULTILINE)
|
||||
desc_fm = re.search(r'^description:\s*(.+)$', fm_content, re.MULTILINE)
|
||||
|
||||
if name_fm:
|
||||
skill_info["name"] = name_fm.group(1).strip()
|
||||
if desc_fm:
|
||||
skill_info["description"] = desc_fm.group(1).strip()
|
||||
|
||||
# Fallback to Header and First Paragraph if needed
|
||||
if not skill_info["description"] or skill_info["description"] == "":
|
||||
name_match = re.search(r'^#\s+(.+)$', content, re.MULTILINE)
|
||||
if name_match and not fm_match: # Only override if no frontmatter name
|
||||
skill_info["name"] = name_match.group(1).strip()
|
||||
|
||||
# Extract first paragraph
|
||||
body = content
|
||||
if fm_match:
|
||||
body = content[fm_match.end():].strip()
|
||||
|
||||
lines = body.split('\n')
|
||||
desc_lines = []
|
||||
for line in lines:
|
||||
if line.startswith('#') or not line.strip():
|
||||
if desc_lines: break
|
||||
continue
|
||||
desc_lines.append(line.strip())
|
||||
|
||||
if desc_lines:
|
||||
skill_info["description"] = " ".join(desc_lines)[:150] + "..."
|
||||
try:
|
||||
with open(skill_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error reading {skill_path}: {e}")
|
||||
continue
|
||||
|
||||
# Parse Metadata
|
||||
metadata = parse_frontmatter(content)
|
||||
|
||||
# Merge Metadata
|
||||
if "name" in metadata: skill_info["name"] = metadata["name"]
|
||||
if "description" in metadata: skill_info["description"] = metadata["description"]
|
||||
if "risk" in metadata: skill_info["risk"] = metadata["risk"]
|
||||
if "source" in metadata: skill_info["source"] = metadata["source"]
|
||||
|
||||
# Fallback for description if missing in frontmatter (legacy support)
|
||||
if not skill_info["description"]:
|
||||
body = content
|
||||
fm_match = re.search(r'^---\s*\n(.*?)\n---', content, re.DOTALL)
|
||||
if fm_match:
|
||||
body = content[fm_match.end():].strip()
|
||||
|
||||
# Simple extraction of first non-header paragraph
|
||||
lines = body.split('\n')
|
||||
desc_lines = []
|
||||
for line in lines:
|
||||
if line.startswith('#') or not line.strip():
|
||||
if desc_lines: break
|
||||
continue
|
||||
desc_lines.append(line.strip())
|
||||
|
||||
if desc_lines:
|
||||
skill_info["description"] = " ".join(desc_lines)[:250].strip()
|
||||
|
||||
skills.append(skill_info)
|
||||
|
||||
skills.sort(key=lambda x: x["name"])
|
||||
# Sort validation: by name
|
||||
skills.sort(key=lambda x: (x["name"].lower(), x["id"].lower()))
|
||||
|
||||
with open(output_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(skills, f, indent=2)
|
||||
|
||||
print(f"✅ Generated index with {len(skills)} skills at: {output_file}")
|
||||
print(f"✅ Generated rich index with {len(skills)} skills at: {output_file}")
|
||||
return skills
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
125
scripts/update_readme.py
Normal file
125
scripts/update_readme.py
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
||||
def update_readme():
|
||||
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
readme_path = os.path.join(base_dir, "README.md")
|
||||
index_path = os.path.join(base_dir, "skills_index.json")
|
||||
|
||||
print(f"📖 Reading skills index from: {index_path}")
|
||||
with open(index_path, 'r', encoding='utf-8') as f:
|
||||
skills = json.load(f)
|
||||
|
||||
total_skills = len(skills)
|
||||
print(f"🔢 Total skills found: {total_skills}")
|
||||
|
||||
print(f"📝 Updating README at: {readme_path}")
|
||||
with open(readme_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# 1. Update Title Count
|
||||
content = re.sub(
|
||||
r'(# 🌌 Antigravity Awesome Skills: )\d+(\+ Agentic Skills)',
|
||||
f'\\g<1>{total_skills}\\g<2>',
|
||||
content
|
||||
)
|
||||
|
||||
# 2. Update Blockquote Count
|
||||
content = re.sub(
|
||||
r'(Collection of )\d+(\+ Universal)',
|
||||
f'\\g<1>{total_skills}\\g<2>',
|
||||
content
|
||||
)
|
||||
|
||||
# 3. Update Intro Text Count
|
||||
content = re.sub(
|
||||
r'(library of \*\*)\d+( high-performance skills\*\*)',
|
||||
f'\\g<1>{total_skills}\\g<2>',
|
||||
content
|
||||
)
|
||||
|
||||
# 4. Update Registry Header Count
|
||||
content = re.sub(
|
||||
r'(## Full Skill Registry \()\d+/\d+(\))',
|
||||
f'\\g<1>{total_skills}/{total_skills}\\g<2>',
|
||||
content
|
||||
)
|
||||
|
||||
# 5. Insert Collections / Bundles Section (New in Phase 3)
|
||||
# This logic checks if "## 📦 Curated Collections" exists. If not, it creates it before Full Registry.
|
||||
collections_header = "## 📦 Curated Collections"
|
||||
|
||||
if collections_header not in content:
|
||||
# Insert before Full Skill Registry
|
||||
content = content.replace("## Full Skill Registry", f"{collections_header}\n\n[Check out our Starter Packs in docs/BUNDLES.md](docs/BUNDLES.md) to find the perfect toolkit for your role.\n\n## Full Skill Registry")
|
||||
|
||||
# 6. Generate New Registry Table
|
||||
print("🔄 Generating new registry table...")
|
||||
|
||||
# Store the Note block to preserve it
|
||||
note_pattern = r'(> \[!NOTE\].*?)\n\n\| Skill Name'
|
||||
note_match = re.search(note_pattern, content, re.DOTALL)
|
||||
note_block = ""
|
||||
if note_match:
|
||||
note_block = note_match.group(1)
|
||||
else:
|
||||
note_block = "> [!NOTE] > **Document Skills**: We provide both **community** and **official Anthropic** versions. Locally, the official versions are used by default."
|
||||
|
||||
table_header = "| Skill Name | Risk | Description | Path |\n| :--- | :--- | :--- | :--- |"
|
||||
table_rows = []
|
||||
|
||||
for skill in skills:
|
||||
name = skill.get('name', 'Unknown')
|
||||
desc = skill.get('description', '').replace('\n', ' ').strip()
|
||||
path = skill.get('path', '')
|
||||
risk = skill.get('risk', 'unknown')
|
||||
|
||||
# Risk Icons
|
||||
risk_icon = "⚪"
|
||||
if risk == "official": risk_icon = "🟣" # Mapping official to purple
|
||||
if risk == "none": risk_icon = "🟢"
|
||||
if risk == "safe": risk_icon = "🔵"
|
||||
if risk == "critical": risk_icon = "🟠"
|
||||
if risk == "offensive": risk_icon = "🔴"
|
||||
|
||||
# Escape pipes
|
||||
desc = desc.replace('|', r'\|')
|
||||
|
||||
row = f"| **{name}** | {risk_icon} | {desc} | `{path}` |"
|
||||
table_rows.append(row)
|
||||
|
||||
new_table_section = f"{note_block}\n\n{table_header}\n" + "\n".join(table_rows)
|
||||
|
||||
# Replace the old table section
|
||||
header_pattern = r'## Full Skill Registry \(\d+/\d+\)'
|
||||
header_match = re.search(header_pattern, content)
|
||||
|
||||
if not header_match:
|
||||
print("❌ Could not find 'Full Skill Registry' header.")
|
||||
return
|
||||
|
||||
start_pos = header_match.end()
|
||||
|
||||
# Find the next section (## ...) or end of file
|
||||
next_section_match = re.search(r'\n## ', content[start_pos:])
|
||||
|
||||
if next_section_match:
|
||||
end_pos = start_pos + next_section_match.start()
|
||||
rest_of_file = content[end_pos:]
|
||||
else:
|
||||
rest_of_file = ""
|
||||
|
||||
before_header = content[:header_match.start()]
|
||||
new_header = f"## Full Skill Registry ({total_skills}/{total_skills})"
|
||||
|
||||
new_content = f"{before_header}{new_header}\n\n{new_table_section}\n{rest_of_file}"
|
||||
|
||||
with open(readme_path, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
|
||||
print("✅ README.md updated successfully with Collections link and Risk columns.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
update_readme()
|
||||
@@ -1,52 +1,124 @@
|
||||
import os
|
||||
import re
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
def validate_skills(skills_dir):
|
||||
def parse_frontmatter(content):
|
||||
"""
|
||||
Simple frontmatter parser using regex to avoid external dependencies.
|
||||
Returns a dict of key-values.
|
||||
"""
|
||||
fm_match = re.search(r'^---\s*\n(.*?)\n---', content, re.DOTALL)
|
||||
if not fm_match:
|
||||
return None
|
||||
|
||||
fm_text = fm_match.group(1)
|
||||
metadata = {}
|
||||
for line in fm_text.split('\n'):
|
||||
if ':' in line:
|
||||
key, val = line.split(':', 1)
|
||||
metadata[key.strip()] = val.strip().strip('"').strip("'")
|
||||
return metadata
|
||||
|
||||
def validate_skills(skills_dir, strict_mode=False):
|
||||
print(f"🔍 Validating skills in: {skills_dir}")
|
||||
print(f"⚙️ Mode: {'STRICT (CI)' if strict_mode else 'Standard (Dev)'}")
|
||||
|
||||
errors = []
|
||||
warnings = []
|
||||
skill_count = 0
|
||||
|
||||
# Pre-compiled regex
|
||||
security_disclaimer_pattern = re.compile(r"AUTHORIZED USE ONLY", re.IGNORECASE)
|
||||
trigger_section_pattern = re.compile(r"^##\s+When to Use", re.MULTILINE | re.IGNORECASE)
|
||||
|
||||
valid_risk_levels = ["none", "safe", "critical", "offensive"]
|
||||
|
||||
for root, dirs, files in os.walk(skills_dir):
|
||||
# Skip .disabled directories
|
||||
dirs[:] = [d for d in dirs if d != '.disabled']
|
||||
# Skip .disabled or hidden directories
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.')]
|
||||
|
||||
if "SKILL.md" in files:
|
||||
skill_count += 1
|
||||
skill_path = os.path.join(root, "SKILL.md")
|
||||
rel_path = os.path.relpath(skill_path, skills_dir)
|
||||
|
||||
with open(skill_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
try:
|
||||
with open(skill_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
except Exception as e:
|
||||
errors.append(f"❌ {rel_path}: Unreadable file - {str(e)}")
|
||||
continue
|
||||
|
||||
# Check for Frontmatter or Header
|
||||
has_frontmatter = content.strip().startswith("---")
|
||||
has_header = re.search(r'^#\s+', content, re.MULTILINE)
|
||||
|
||||
if not (has_frontmatter or has_header):
|
||||
errors.append(f"❌ {rel_path}: Missing frontmatter or top-level heading")
|
||||
|
||||
if has_frontmatter:
|
||||
# Basic check for name and description in frontmatter
|
||||
fm_match = re.search(r'^---\s*(.*?)\s*---', content, re.DOTALL)
|
||||
if fm_match:
|
||||
fm_content = fm_match.group(1)
|
||||
if "name:" not in fm_content:
|
||||
errors.append(f"⚠️ {rel_path}: Frontmatter missing 'name:'")
|
||||
if "description:" not in fm_content:
|
||||
errors.append(f"⚠️ {rel_path}: Frontmatter missing 'description:'")
|
||||
else:
|
||||
errors.append(f"❌ {rel_path}: Malformed frontmatter")
|
||||
# 1. Frontmatter Check
|
||||
metadata = parse_frontmatter(content)
|
||||
if not metadata:
|
||||
errors.append(f"❌ {rel_path}: Missing or malformed YAML frontmatter")
|
||||
continue # Cannot proceed without metadata
|
||||
|
||||
# 2. Metadata Schema Checks
|
||||
if "name" not in metadata:
|
||||
errors.append(f"❌ {rel_path}: Missing 'name' in frontmatter")
|
||||
elif metadata["name"] != os.path.basename(root):
|
||||
warnings.append(f"⚠️ {rel_path}: Name '{metadata['name']}' does not match folder name '{os.path.basename(root)}'")
|
||||
|
||||
if "description" not in metadata:
|
||||
errors.append(f"❌ {rel_path}: Missing 'description' in frontmatter")
|
||||
|
||||
# Risk Validation (Quality Bar)
|
||||
if "risk" not in metadata:
|
||||
msg = f"⚠️ {rel_path}: Missing 'risk' label (defaulting to 'unknown')"
|
||||
if strict_mode: errors.append(msg.replace("⚠️", "❌"))
|
||||
else: warnings.append(msg)
|
||||
elif metadata["risk"] not in valid_risk_levels:
|
||||
errors.append(f"❌ {rel_path}: Invalid risk level '{metadata['risk']}'. Must be one of {valid_risk_levels}")
|
||||
|
||||
# Source Validation
|
||||
if "source" not in metadata:
|
||||
msg = f"⚠️ {rel_path}: Missing 'source' attribution"
|
||||
if strict_mode: errors.append(msg.replace("⚠️", "❌"))
|
||||
else: warnings.append(msg)
|
||||
|
||||
# 3. Content Checks (Triggers)
|
||||
if not trigger_section_pattern.search(content):
|
||||
msg = f"⚠️ {rel_path}: Missing '## When to Use' section"
|
||||
if strict_mode: errors.append(msg.replace("⚠️", "❌"))
|
||||
else: warnings.append(msg)
|
||||
|
||||
# 4. Security Guardrails
|
||||
if metadata.get("risk") == "offensive":
|
||||
if not security_disclaimer_pattern.search(content):
|
||||
errors.append(f"🚨 {rel_path}: OFFENSIVE SKILL MISSING SECURITY DISCLAIMER! (Must contain 'AUTHORIZED USE ONLY')")
|
||||
|
||||
# Reporting
|
||||
print(f"\n📊 Checked {skill_count} skills.")
|
||||
|
||||
if warnings:
|
||||
print(f"\n⚠️ Found {len(warnings)} Warnings:")
|
||||
for w in warnings:
|
||||
print(w)
|
||||
|
||||
print(f"✅ Found and checked {skill_count} skills.")
|
||||
if errors:
|
||||
print("\n⚠️ Validation Results:")
|
||||
for err in errors:
|
||||
print(err)
|
||||
print(f"\n❌ Found {len(errors)} Critical Errors:")
|
||||
for e in errors:
|
||||
print(e)
|
||||
return False
|
||||
else:
|
||||
print("✨ All skills passed basic validation!")
|
||||
return True
|
||||
|
||||
if strict_mode and warnings:
|
||||
print("\n❌ STRICT MODE: Failed due to warnings.")
|
||||
return False
|
||||
|
||||
print("\n✨ All skills passed validation!")
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Validate Antigravity Skills")
|
||||
parser.add_argument("--strict", action="store_true", help="Fail on warnings (for CI)")
|
||||
args = parser.parse_args()
|
||||
|
||||
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
skills_path = os.path.join(base_dir, "skills")
|
||||
validate_skills(skills_path)
|
||||
|
||||
success = validate_skills(skills_path, strict_mode=args.strict)
|
||||
if not success:
|
||||
sys.exit(1)
|
||||
|
||||
256
skills/README.md
256
skills/README.md
@@ -1,89 +1,201 @@
|
||||
# Antigravity Skills
|
||||
# Skills Directory
|
||||
|
||||
通过模块化的 **Skills** 定义,赋予 Agent 在特定领域的专业能力(如全栈开发、复杂逻辑规划、多媒体处理等),让 Agent 能够像人类专家一样系统性地解决复杂问题。
|
||||
**Welcome to the skills folder!** This is where all 179+ specialized AI skills live.
|
||||
|
||||
## 📂 目录结构
|
||||
## 🤔 What Are Skills?
|
||||
|
||||
Skills are specialized instruction sets that teach AI assistants how to handle specific tasks. Think of them as expert knowledge modules that your AI can load on-demand.
|
||||
|
||||
**Simple analogy:** Just like you might consult different experts (a designer, a security expert, a marketer), skills let your AI become an expert in different areas when you need them.
|
||||
|
||||
---
|
||||
|
||||
## 📂 Folder Structure
|
||||
|
||||
Each skill lives in its own folder with this structure:
|
||||
|
||||
```
|
||||
.
|
||||
├── .agent/
|
||||
│ └── skills/ # Antigravity Skills 技能库
|
||||
│ ├── skill-name/ # 独立技能目录
|
||||
│ │ ├── SKILL.md # 技能核心定义与Prompt(必须)
|
||||
│ │ ├── scripts/ # 技能依赖的脚本(可选)
|
||||
│ │ ├── examples/ # 技能使用示例(可选)
|
||||
│ │ └── resources/ # 技能依赖的模板与资源(可选)
|
||||
├── skill-guide/ # 用户手册与文档指南
|
||||
│ └── Antigravity_Skills_Manual_CN.md # 中文使用手册
|
||||
└── README.md
|
||||
skills/
|
||||
├── skill-name/ # Individual skill folder
|
||||
│ ├── SKILL.md # Main skill definition (required)
|
||||
│ ├── scripts/ # Helper scripts (optional)
|
||||
│ ├── examples/ # Usage examples (optional)
|
||||
│ └── resources/ # Templates & resources (optional)
|
||||
```
|
||||
|
||||
## 📖 快速开始
|
||||
1. 将`.agent/`目录复制到你的工作区:
|
||||
**Key point:** Only `SKILL.md` is required. Everything else is optional!
|
||||
|
||||
---
|
||||
|
||||
## How to Use Skills
|
||||
|
||||
### Step 1: Make sure skills are installed
|
||||
Skills should be in your `.agent/skills/` directory (or `.claude/skills/`, `.gemini/skills/`, etc.)
|
||||
|
||||
### Step 2: Invoke a skill in your AI chat
|
||||
Use the `@` symbol followed by the skill name:
|
||||
|
||||
```
|
||||
@brainstorming help me design a todo app
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
@stripe-integration add payment processing to my app
|
||||
```
|
||||
|
||||
### Step 3: The AI becomes an expert
|
||||
The AI loads that skill's knowledge and helps you with specialized expertise!
|
||||
|
||||
---
|
||||
|
||||
## Skill Categories
|
||||
|
||||
### Creative & Design
|
||||
Skills for visual design, UI/UX, and artistic creation:
|
||||
- `@algorithmic-art` - Create algorithmic art with p5.js
|
||||
- `@canvas-design` - Design posters and artwork (PNG/PDF output)
|
||||
- `@frontend-design` - Build production-grade frontend interfaces
|
||||
- `@ui-ux-pro-max` - Professional UI/UX design with color, fonts, layouts
|
||||
- `@web-artifacts-builder` - Build modern web apps (React, Tailwind, Shadcn/ui)
|
||||
- `@theme-factory` - Generate themes for documents and presentations
|
||||
- `@brand-guidelines` - Apply Anthropic brand design standards
|
||||
- `@slack-gif-creator` - Create high-quality GIFs for Slack
|
||||
|
||||
### Development & Engineering
|
||||
Skills for coding, testing, debugging, and code review:
|
||||
- `@test-driven-development` - Write tests before implementation (TDD)
|
||||
- `@systematic-debugging` - Debug systematically, not randomly
|
||||
- `@webapp-testing` - Test web apps with Playwright
|
||||
- `@receiving-code-review` - Handle code review feedback properly
|
||||
- `@requesting-code-review` - Request code reviews before merging
|
||||
- `@finishing-a-development-branch` - Complete dev branches (merge, PR, cleanup)
|
||||
- `@subagent-driven-development` - Coordinate multiple AI agents for parallel tasks
|
||||
|
||||
### Documentation & Office
|
||||
Skills for working with documents and office files:
|
||||
- `@doc-coauthoring` - Collaborate on structured documents
|
||||
- `@docx` - Create, edit, and analyze Word documents
|
||||
- `@xlsx` - Work with Excel spreadsheets (formulas, charts)
|
||||
- `@pptx` - Create and modify PowerPoint presentations
|
||||
- `@pdf` - Handle PDFs (extract text, merge, split, fill forms)
|
||||
- `@internal-comms` - Draft internal communications (reports, announcements)
|
||||
- `@notebooklm` - Query Google NotebookLM notebooks
|
||||
|
||||
### Planning & Workflow
|
||||
Skills for task planning and workflow optimization:
|
||||
- `@brainstorming` - Brainstorm and design before coding
|
||||
- `@writing-plans` - Write detailed implementation plans
|
||||
- `@planning-with-files` - File-based planning system (Manus-style)
|
||||
- `@executing-plans` - Execute plans with checkpoints and reviews
|
||||
- `@using-git-worktrees` - Create isolated Git worktrees for parallel work
|
||||
- `@verification-before-completion` - Verify work before claiming completion
|
||||
- `@using-superpowers` - Discover and use advanced skills
|
||||
|
||||
### System Extension
|
||||
Skills for extending AI capabilities:
|
||||
- `@mcp-builder` - Build MCP (Model Context Protocol) servers
|
||||
- `@skill-creator` - Create new skills or update existing ones
|
||||
- `@writing-skills` - Tools for writing and validating skill files
|
||||
- `@dispatching-parallel-agents` - Distribute tasks to multiple agents
|
||||
|
||||
---
|
||||
|
||||
## Finding Skills
|
||||
|
||||
### Method 1: Browse this folder
|
||||
```bash
|
||||
cp -r .agent/ /path/to/your/workspace/
|
||||
ls skills/
|
||||
```
|
||||
2. **调用 Skill**: 在对话框输入 `@[skill-name]` 或 `/skill-name`来进行调用,例如:
|
||||
```text
|
||||
/canvas-design 帮我设计一张关于“Deep Learning”的博客封面,风格要素雅、科技感,尺寸 16:9
|
||||
|
||||
### Method 2: Search by keyword
|
||||
```bash
|
||||
ls skills/ | grep "keyword"
|
||||
```
|
||||
3. **查看手册**: 详细的使用案例和参数说明请查阅 [skill-guide/Antigravity_Skills_Manual_CN.md](skill-guide/Antigravity_Skills_Manual_CN.md)。
|
||||
4. **环境依赖**: 部分 Skill (如 PDF, XLSX) 依赖 Python 环境,请确保 `.venv` 处于激活状态或系统已安装相应库。
|
||||
|
||||
### Method 3: Check the main README
|
||||
See the [main README](../README.md) for the complete list of all 179+ skills organized by category.
|
||||
|
||||
## 🚀 已集成的 Skills
|
||||
---
|
||||
|
||||
### 🎨 创意与设计 (Creative & Design)
|
||||
这些技能专注于视觉表现、UI/UX 设计和艺术创作。
|
||||
- **`@[algorithmic-art]`**: 使用 p5.js 代码创作算法艺术、生成艺术
|
||||
- **`@[canvas-design]`**: 基于设计哲学创建海报、艺术作品(输出 PNG/PDF)
|
||||
- **`@[frontend-design]`**: 创建高质量、生产级的各种前端界面和 Web 组件
|
||||
- **`@[ui-ux-pro-max]`**: 专业的 UI/UX 设计智能,提供配色、字体、布局等全套设计方案
|
||||
- **`@[web-artifacts-builder]`**: 构建复杂、现代化的 Web 应用(基于 React, Tailwind, Shadcn/ui)
|
||||
- **`@[theme-factory]`**: 为文档、幻灯片、HTML 等生成配套的主题风格
|
||||
- **`@[brand-guidelines]`**: 应用 Anthropic 官方品牌设计规范(颜色、排版等)
|
||||
- **`@[slack-gif-creator]`**: 制作专用于 Slack 的高质量 GIF 动图
|
||||
## 💡 Popular Skills to Try
|
||||
|
||||
### 🛠️ 开发与工程 (Development & Engineering)
|
||||
这些技能涵盖了编码、测试、调试和代码审查的全生命周期。
|
||||
- **`@[test-driven-development]`**: 测试驱动开发(TDD),在编写实现代码前先编写测试
|
||||
- **`@[systematic-debugging]`**: 系统化调试,用于解决 Bug、测试失败或异常行为
|
||||
- **`@[webapp-testing]`**: 使用 Playwright 对本地 Web 应用进行交互测试和验证
|
||||
- **`@[receiving-code-review]`**: 处理代码审查反馈,进行技术验证而非盲目修改
|
||||
- **`@[requesting-code-review]`**: 主动发起代码审查,在合并或完成任务前验证代码质量
|
||||
- **`@[finishing-a-development-branch]`**: 引导开发分支的收尾工作(合并、PR、清理等)
|
||||
- **`@[subagent-driven-development]`**: 协调多个子 Agent 并行执行独立的开发任务
|
||||
**For beginners:**
|
||||
- `@brainstorming` - Design before coding
|
||||
- `@systematic-debugging` - Fix bugs methodically
|
||||
- `@git-pushing` - Commit with good messages
|
||||
|
||||
### 📄 文档与办公 (Documentation & Office)
|
||||
这些技能用于处理各种格式的专业文档和办公需求。
|
||||
- **`@[doc-coauthoring]`**: 引导用户进行结构化文档(提案、技术规范等)的协作编写
|
||||
- **`@[docx]`**: 创建、编辑和分析 Word 文档
|
||||
- **`@[xlsx]`**: 创建、编辑和分析 Excel 电子表格(支持公式、图表)
|
||||
- **`@[pptx]`**: 创建和修改 PowerPoint 演示文稿
|
||||
- **`@[pdf]`**: 处理 PDF 文档,包括提取文本、表格,合并/拆分及填写表单
|
||||
- **`@[internal-comms]`**: 起草各类企业内部沟通文档(周报、通告、FAQ 等)
|
||||
- **`@[notebooklm]`**: 查询 Google NotebookLM 笔记本,提供基于文档的确切答案
|
||||
**For developers:**
|
||||
- `@test-driven-development` - Write tests first
|
||||
- `@react-best-practices` - Modern React patterns
|
||||
- `@senior-fullstack` - Full-stack development
|
||||
|
||||
### 📅 计划与流程 (Planning & Workflow)
|
||||
这些技能帮助优化工作流、任务规划和执行效率。
|
||||
- **`@[brainstorming]`**: 在开始任何工作前进行头脑风暴,明确需求和设计
|
||||
- **`@[writing-plans]`**: 为复杂的多步骤任务编写详细的执行计划(Spec)
|
||||
- **`@[planning-with-files]`**: 适用于复杂任务的文件式规划系统(Manus-style)
|
||||
- **`@[executing-plans]`**: 执行已有的实施计划,包含检查点和审查机制
|
||||
- **`@[using-git-worktrees]`**: 创建隔离的 Git 工作树,用于并行开发或任务切换
|
||||
- **`@[verification-before-completion]`**: 在声明任务完成前运行验证命令,确保证据确凿
|
||||
- **`@[using-superpowers]`**: 引导用户发现和使用这些高级技能
|
||||
**For security:**
|
||||
- `@ethical-hacking-methodology` - Security basics
|
||||
- `@burp-suite-testing` - Web app security testing
|
||||
|
||||
### 🧩 系统扩展 (System Extension)
|
||||
这些技能允许我扩展自身的能力边界。
|
||||
- **`@[mcp-builder]`**: 构建 MCP (Model Context Protocol) 服务器,连接外部工具和数据
|
||||
- **`@[skill-creator]`**: 创建新技能或更新现有技能,扩展我的知识库和工作流
|
||||
- **`@[writing-skills]`**: 辅助编写、编辑和验证技能文件的工具集
|
||||
- **`@[dispatching-parallel-agents]`**: 分发并行任务给多个 Agent 处理
|
||||
---
|
||||
|
||||
## 📚 参考文档
|
||||
- [Anthropic Skills](https://github.com/anthropic/skills)
|
||||
- [UI/UX Pro Max Skills](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill)
|
||||
- [Superpowers](https://github.com/obra/superpowers)
|
||||
- [Planning with Files](https://github.com/OthmanAdi/planning-with-files)
|
||||
- [NotebookLM](https://github.com/PleasePrompto/notebooklm-skill)
|
||||
## Creating Your Own Skill
|
||||
|
||||
Want to create a new skill? Check out:
|
||||
1. [CONTRIBUTING.md](../CONTRIBUTING.md) - How to contribute
|
||||
2. [docs/SKILL_ANATOMY.md](../docs/SKILL_ANATOMY.md) - Skill structure guide
|
||||
3. `@skill-creator` - Use this skill to create new skills!
|
||||
|
||||
**Basic structure:**
|
||||
```markdown
|
||||
---
|
||||
name: my-skill-name
|
||||
description: "What this skill does"
|
||||
---
|
||||
|
||||
# Skill Title
|
||||
|
||||
## Overview
|
||||
[What this skill does]
|
||||
|
||||
## When to Use
|
||||
- Use when [scenario]
|
||||
|
||||
## Instructions
|
||||
[Step-by-step guide]
|
||||
|
||||
## Examples
|
||||
[Code examples]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
- **[Getting Started](../GETTING_STARTED.md)** - Quick start guide
|
||||
- **[Examples](../docs/EXAMPLES.md)** - Real-world usage examples
|
||||
- **[FAQ](../FAQ.md)** - Common questions
|
||||
- **[Visual Guide](../docs/VISUAL_GUIDE.md)** - Diagrams and flowcharts
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Contributing
|
||||
|
||||
Found a skill that needs improvement? Want to add a new skill?
|
||||
|
||||
1. Read [CONTRIBUTING.md](../CONTRIBUTING.md)
|
||||
2. Study existing skills in this folder
|
||||
3. Create your skill following the structure
|
||||
4. Submit a Pull Request
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Anthropic Skills](https://github.com/anthropic/skills) - Official Anthropic skills
|
||||
- [UI/UX Pro Max Skills](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) - Design skills
|
||||
- [Superpowers](https://github.com/obra/superpowers) - Original superpowers collection
|
||||
- [Planning with Files](https://github.com/OthmanAdi/planning-with-files) - Planning patterns
|
||||
- [NotebookLM](https://github.com/PleasePrompto/notebooklm-skill) - NotebookLM integration
|
||||
|
||||
---
|
||||
|
||||
**Need help?** Check the [FAQ](../FAQ.md) or open an issue on GitHub!
|
||||
|
||||
@@ -1,508 +1,232 @@
|
||||
---
|
||||
name: ab-test-setup
|
||||
description: When the user wants to plan, design, or implement an A/B test or experiment. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," or "hypothesis." For tracking implementation, see analytics-tracking.
|
||||
description: Structured guide for setting up A/B tests with mandatory gates for hypothesis, metrics, and execution readiness.
|
||||
---
|
||||
|
||||
# A/B Test Setup
|
||||
|
||||
You are an expert in experimentation and A/B testing. Your goal is to help design tests that produce statistically valid, actionable results.
|
||||
## 1️⃣ Purpose & Scope
|
||||
|
||||
## Initial Assessment
|
||||
Ensure every A/B test is **valid, rigorous, and safe** before a single line of code is written.
|
||||
|
||||
Before designing a test, understand:
|
||||
|
||||
1. **Test Context**
|
||||
- What are you trying to improve?
|
||||
- What change are you considering?
|
||||
- What made you want to test this?
|
||||
|
||||
2. **Current State**
|
||||
- Baseline conversion rate?
|
||||
- Current traffic volume?
|
||||
- Any historical test data?
|
||||
|
||||
3. **Constraints**
|
||||
- Technical implementation complexity?
|
||||
- Timeline requirements?
|
||||
- Tools available?
|
||||
- Prevents "peeking"
|
||||
- Enforces statistical power
|
||||
- Blocks invalid hypotheses
|
||||
|
||||
---
|
||||
|
||||
## Core Principles
|
||||
## 2️⃣ Pre-Requisites
|
||||
|
||||
### 1. Start with a Hypothesis
|
||||
- Not just "let's see what happens"
|
||||
- Specific prediction of outcome
|
||||
- Based on reasoning or data
|
||||
You must have:
|
||||
|
||||
### 2. Test One Thing
|
||||
- Single variable per test
|
||||
- Otherwise you don't know what worked
|
||||
- Save MVT for later
|
||||
- A clear user problem
|
||||
- Access to an analytics source
|
||||
- Roughly estimated traffic volume
|
||||
|
||||
### 3. Statistical Rigor
|
||||
- Pre-determine sample size
|
||||
- Don't peek and stop early
|
||||
- Commit to the methodology
|
||||
### Hypothesis Quality Checklist
|
||||
|
||||
### 4. Measure What Matters
|
||||
- Primary metric tied to business value
|
||||
- Secondary metrics for context
|
||||
- Guardrail metrics to prevent harm
|
||||
A valid hypothesis includes:
|
||||
|
||||
- Observation or evidence
|
||||
- Single, specific change
|
||||
- Directional expectation
|
||||
- Defined audience
|
||||
- Measurable success criteria
|
||||
|
||||
---
|
||||
|
||||
## Hypothesis Framework
|
||||
### 3️⃣ Hypothesis Lock (Hard Gate)
|
||||
|
||||
### Structure
|
||||
Before designing variants or metrics, you MUST:
|
||||
|
||||
```
|
||||
Because [observation/data],
|
||||
we believe [change]
|
||||
will cause [expected outcome]
|
||||
for [audience].
|
||||
We'll know this is true when [metrics].
|
||||
```
|
||||
- Present the **final hypothesis**
|
||||
- Specify:
|
||||
- Target audience
|
||||
- Primary metric
|
||||
- Expected direction of effect
|
||||
- Minimum Detectable Effect (MDE)
|
||||
|
||||
### Examples
|
||||
Ask explicitly:
|
||||
|
||||
**Weak hypothesis:**
|
||||
"Changing the button color might increase clicks."
|
||||
> “Is this the final hypothesis we are committing to for this test?”
|
||||
|
||||
**Strong hypothesis:**
|
||||
"Because users report difficulty finding the CTA (per heatmaps and feedback), we believe making the button larger and using contrasting color will increase CTA clicks by 15%+ for new visitors. We'll measure click-through rate from page view to signup start."
|
||||
|
||||
### Good Hypotheses Include
|
||||
|
||||
- **Observation**: What prompted this idea
|
||||
- **Change**: Specific modification
|
||||
- **Effect**: Expected outcome and direction
|
||||
- **Audience**: Who this applies to
|
||||
- **Metric**: How you'll measure success
|
||||
**Do NOT proceed until confirmed.**
|
||||
|
||||
---
|
||||
|
||||
## Test Types
|
||||
### 4️⃣ Assumptions & Validity Check (Mandatory)
|
||||
|
||||
### A/B Test (Split Test)
|
||||
- Two versions: Control (A) vs. Variant (B)
|
||||
- Single change between versions
|
||||
- Most common, easiest to analyze
|
||||
Explicitly list assumptions about:
|
||||
|
||||
### A/B/n Test
|
||||
- Multiple variants (A vs. B vs. C...)
|
||||
- Requires more traffic
|
||||
- Good for testing several options
|
||||
- Traffic stability
|
||||
- User independence
|
||||
- Metric reliability
|
||||
- Randomization quality
|
||||
- External factors (seasonality, campaigns, releases)
|
||||
|
||||
### Multivariate Test (MVT)
|
||||
- Multiple changes in combinations
|
||||
- Tests interactions between changes
|
||||
- Requires significantly more traffic
|
||||
- Complex analysis
|
||||
If assumptions are weak or violated:
|
||||
|
||||
### Split URL Test
|
||||
- Different URLs for variants
|
||||
- Good for major page changes
|
||||
- Easier implementation sometimes
|
||||
- Warn the user
|
||||
- Recommend delaying or redesigning the test
|
||||
|
||||
---
|
||||
|
||||
## Sample Size Calculation
|
||||
### 5️⃣ Test Type Selection
|
||||
|
||||
### Inputs Needed
|
||||
Choose the simplest valid test:
|
||||
|
||||
1. **Baseline conversion rate**: Your current rate
|
||||
2. **Minimum detectable effect (MDE)**: Smallest change worth detecting
|
||||
3. **Statistical significance level**: Usually 95%
|
||||
4. **Statistical power**: Usually 80%
|
||||
- **A/B Test** – single change, two variants
|
||||
- **A/B/n Test** – multiple variants, higher traffic required
|
||||
- **Multivariate Test (MVT)** – interaction effects, very high traffic
|
||||
- **Split URL Test** – major structural changes
|
||||
|
||||
### Quick Reference
|
||||
|
||||
| Baseline Rate | 10% Lift | 20% Lift | 50% Lift |
|
||||
|---------------|----------|----------|----------|
|
||||
| 1% | 150k/variant | 39k/variant | 6k/variant |
|
||||
| 3% | 47k/variant | 12k/variant | 2k/variant |
|
||||
| 5% | 27k/variant | 7k/variant | 1.2k/variant |
|
||||
| 10% | 12k/variant | 3k/variant | 550/variant |
|
||||
|
||||
### Formula Resources
|
||||
- Evan Miller's calculator: https://www.evanmiller.org/ab-testing/sample-size.html
|
||||
- Optimizely's calculator: https://www.optimizely.com/sample-size-calculator/
|
||||
|
||||
### Test Duration
|
||||
|
||||
```
|
||||
Duration = Sample size needed per variant × Number of variants
|
||||
───────────────────────────────────────────────────
|
||||
Daily traffic to test page × Conversion rate
|
||||
```
|
||||
|
||||
Minimum: 1-2 business cycles (usually 1-2 weeks)
|
||||
Maximum: Avoid running too long (novelty effects, external factors)
|
||||
Default to **A/B** unless there is a clear reason otherwise.
|
||||
|
||||
---
|
||||
|
||||
## Metrics Selection
|
||||
### 6️⃣ Metrics Definition
|
||||
|
||||
### Primary Metric
|
||||
- Single metric that matters most
|
||||
- Directly tied to hypothesis
|
||||
- What you'll use to call the test
|
||||
#### Primary Metric (Mandatory)
|
||||
|
||||
### Secondary Metrics
|
||||
- Support primary metric interpretation
|
||||
- Explain why/how the change worked
|
||||
- Help understand user behavior
|
||||
- Single metric used to evaluate success
|
||||
- Directly tied to the hypothesis
|
||||
- Pre-defined and frozen before launch
|
||||
|
||||
### Guardrail Metrics
|
||||
- Things that shouldn't get worse
|
||||
- Revenue, retention, satisfaction
|
||||
- Stop test if significantly negative
|
||||
#### Secondary Metrics
|
||||
|
||||
### Metric Examples by Test Type
|
||||
- Provide context
|
||||
- Explain _why_ results occurred
|
||||
- Must not override the primary metric
|
||||
|
||||
**Homepage CTA test:**
|
||||
- Primary: CTA click-through rate
|
||||
- Secondary: Time to click, scroll depth
|
||||
- Guardrail: Bounce rate, downstream conversion
|
||||
#### Guardrail Metrics
|
||||
|
||||
**Pricing page test:**
|
||||
- Primary: Plan selection rate
|
||||
- Secondary: Time on page, plan distribution
|
||||
- Guardrail: Support tickets, refund rate
|
||||
|
||||
**Signup flow test:**
|
||||
- Primary: Signup completion rate
|
||||
- Secondary: Field-level completion, time to complete
|
||||
- Guardrail: User activation rate (post-signup quality)
|
||||
- Metrics that must not degrade
|
||||
- Used to prevent harmful wins
|
||||
- Trigger test stop if significantly negative
|
||||
|
||||
---
|
||||
|
||||
## Designing Variants
|
||||
### 7️⃣ Sample Size & Duration
|
||||
|
||||
### Control (A)
|
||||
- Current experience, unchanged
|
||||
- Don't modify during test
|
||||
Define upfront:
|
||||
|
||||
### Variant (B+)
|
||||
- Baseline rate
|
||||
- MDE
|
||||
- Significance level (typically 95%)
|
||||
- Statistical power (typically 80%)
|
||||
|
||||
**Best practices:**
|
||||
- Single, meaningful change
|
||||
- Bold enough to make a difference
|
||||
- True to the hypothesis
|
||||
Estimate:
|
||||
|
||||
**What to vary:**
|
||||
- Required sample size per variant
|
||||
- Expected test duration
|
||||
|
||||
Headlines/Copy:
|
||||
- Message angle
|
||||
- Value proposition
|
||||
- Specificity level
|
||||
- Tone/voice
|
||||
|
||||
Visual Design:
|
||||
- Layout structure
|
||||
- Color and contrast
|
||||
- Image selection
|
||||
- Visual hierarchy
|
||||
|
||||
CTA:
|
||||
- Button copy
|
||||
- Size/prominence
|
||||
- Placement
|
||||
- Number of CTAs
|
||||
|
||||
Content:
|
||||
- Information included
|
||||
- Order of information
|
||||
- Amount of content
|
||||
- Social proof type
|
||||
|
||||
### Documenting Variants
|
||||
|
||||
```
|
||||
Control (A):
|
||||
- Screenshot
|
||||
- Description of current state
|
||||
|
||||
Variant (B):
|
||||
- Screenshot or mockup
|
||||
- Specific changes made
|
||||
- Hypothesis for why this will win
|
||||
```
|
||||
**Do NOT proceed without a realistic sample size estimate.**
|
||||
|
||||
---
|
||||
|
||||
## Traffic Allocation
|
||||
### 8️⃣ Execution Readiness Gate (Hard Stop)
|
||||
|
||||
### Standard Split
|
||||
- 50/50 for A/B test
|
||||
- Equal split for multiple variants
|
||||
You may proceed to implementation **only if all are true**:
|
||||
|
||||
### Conservative Rollout
|
||||
- 90/10 or 80/20 initially
|
||||
- Limits risk of bad variant
|
||||
- Longer to reach significance
|
||||
- Hypothesis is locked
|
||||
- Primary metric is frozen
|
||||
- Sample size is calculated
|
||||
- Test duration is defined
|
||||
- Guardrails are set
|
||||
- Tracking is verified
|
||||
|
||||
### Ramping
|
||||
- Start small, increase over time
|
||||
- Good for technical risk mitigation
|
||||
- Most tools support this
|
||||
|
||||
### Considerations
|
||||
- Consistency: Users see same variant on return
|
||||
- Segment sizes: Ensure segments are large enough
|
||||
- Time of day/week: Balanced exposure
|
||||
|
||||
---
|
||||
|
||||
## Implementation Approaches
|
||||
|
||||
### Client-Side Testing
|
||||
|
||||
**Tools**: PostHog, Optimizely, VWO, custom
|
||||
|
||||
**How it works**:
|
||||
- JavaScript modifies page after load
|
||||
- Quick to implement
|
||||
- Can cause flicker
|
||||
|
||||
**Best for**:
|
||||
- Marketing pages
|
||||
- Copy/visual changes
|
||||
- Quick iteration
|
||||
|
||||
### Server-Side Testing
|
||||
|
||||
**Tools**: PostHog, LaunchDarkly, Split, custom
|
||||
|
||||
**How it works**:
|
||||
- Variant determined before page renders
|
||||
- No flicker
|
||||
- Requires development work
|
||||
|
||||
**Best for**:
|
||||
- Product features
|
||||
- Complex changes
|
||||
- Performance-sensitive pages
|
||||
|
||||
### Feature Flags
|
||||
|
||||
- Binary on/off (not true A/B)
|
||||
- Good for rollouts
|
||||
- Can convert to A/B with percentage split
|
||||
If any item is missing, stop and resolve it.
|
||||
|
||||
---
|
||||
|
||||
## Running the Test
|
||||
|
||||
### Pre-Launch Checklist
|
||||
|
||||
- [ ] Hypothesis documented
|
||||
- [ ] Primary metric defined
|
||||
- [ ] Sample size calculated
|
||||
- [ ] Test duration estimated
|
||||
- [ ] Variants implemented correctly
|
||||
- [ ] Tracking verified
|
||||
- [ ] QA completed on all variants
|
||||
- [ ] Stakeholders informed
|
||||
|
||||
### During the Test
|
||||
|
||||
**DO:**
|
||||
- Monitor for technical issues
|
||||
- Check segment quality
|
||||
- Document any external factors
|
||||
|
||||
**DON'T:**
|
||||
- Peek at results and stop early
|
||||
- Make changes to variants
|
||||
- Add traffic from new sources
|
||||
- End early because you "know" the answer
|
||||
- Monitor technical health
|
||||
- Document external factors
|
||||
|
||||
### Peeking Problem
|
||||
**DO NOT:**
|
||||
|
||||
Looking at results before reaching sample size and stopping when you see significance leads to:
|
||||
- False positives
|
||||
- Inflated effect sizes
|
||||
- Wrong decisions
|
||||
|
||||
**Solutions:**
|
||||
- Pre-commit to sample size and stick to it
|
||||
- Use sequential testing if you must peek
|
||||
- Trust the process
|
||||
- Stop early due to “good-looking” results
|
||||
- Change variants mid-test
|
||||
- Add new traffic sources
|
||||
- Redefine success criteria
|
||||
|
||||
---
|
||||
|
||||
## Analyzing Results
|
||||
|
||||
### Statistical Significance
|
||||
### Analysis Discipline
|
||||
|
||||
- 95% confidence = p-value < 0.05
|
||||
- Means: <5% chance result is random
|
||||
- Not a guarantee—just a threshold
|
||||
When interpreting results:
|
||||
|
||||
### Practical Significance
|
||||
- Do NOT generalize beyond the tested population
|
||||
- Do NOT claim causality beyond the tested change
|
||||
- Do NOT override guardrail failures
|
||||
- Separate statistical significance from business judgment
|
||||
|
||||
Statistical ≠ Practical
|
||||
### Interpretation Outcomes
|
||||
|
||||
- Is the effect size meaningful for business?
|
||||
- Is it worth the implementation cost?
|
||||
- Is it sustainable over time?
|
||||
|
||||
### What to Look At
|
||||
|
||||
1. **Did you reach sample size?**
|
||||
- If not, result is preliminary
|
||||
|
||||
2. **Is it statistically significant?**
|
||||
- Check confidence intervals
|
||||
- Check p-value
|
||||
|
||||
3. **Is the effect size meaningful?**
|
||||
- Compare to your MDE
|
||||
- Project business impact
|
||||
|
||||
4. **Are secondary metrics consistent?**
|
||||
- Do they support the primary?
|
||||
- Any unexpected effects?
|
||||
|
||||
5. **Any guardrail concerns?**
|
||||
- Did anything get worse?
|
||||
- Long-term risks?
|
||||
|
||||
6. **Segment differences?**
|
||||
- Mobile vs. desktop?
|
||||
- New vs. returning?
|
||||
- Traffic source?
|
||||
|
||||
### Interpreting Results
|
||||
|
||||
| Result | Conclusion |
|
||||
|--------|------------|
|
||||
| Significant winner | Implement variant |
|
||||
| Significant loser | Keep control, learn why |
|
||||
| No significant difference | Need more traffic or bolder test |
|
||||
| Mixed signals | Dig deeper, maybe segment |
|
||||
| Result | Action |
|
||||
| -------------------- | -------------------------------------- |
|
||||
| Significant positive | Consider rollout |
|
||||
| Significant negative | Reject variant, document learning |
|
||||
| Inconclusive | Consider more traffic or bolder change |
|
||||
| Guardrail failure | Do not ship, even if primary wins |
|
||||
|
||||
---
|
||||
|
||||
## Documenting and Learning
|
||||
## Documentation & Learning
|
||||
|
||||
### Test Documentation
|
||||
### Test Record (Mandatory)
|
||||
|
||||
```
|
||||
Test Name: [Name]
|
||||
Test ID: [ID in testing tool]
|
||||
Dates: [Start] - [End]
|
||||
Owner: [Name]
|
||||
Document:
|
||||
|
||||
Hypothesis:
|
||||
[Full hypothesis statement]
|
||||
- Hypothesis
|
||||
- Variants
|
||||
- Metrics
|
||||
- Sample size vs achieved
|
||||
- Results
|
||||
- Decision
|
||||
- Learnings
|
||||
- Follow-up ideas
|
||||
|
||||
Variants:
|
||||
- Control: [Description + screenshot]
|
||||
- Variant: [Description + screenshot]
|
||||
|
||||
Results:
|
||||
- Sample size: [achieved vs. target]
|
||||
- Primary metric: [control] vs. [variant] ([% change], [confidence])
|
||||
- Secondary metrics: [summary]
|
||||
- Segment insights: [notable differences]
|
||||
|
||||
Decision: [Winner/Loser/Inconclusive]
|
||||
Action: [What we're doing]
|
||||
|
||||
Learnings:
|
||||
[What we learned, what to test next]
|
||||
```
|
||||
|
||||
### Building a Learning Repository
|
||||
|
||||
- Central location for all tests
|
||||
- Searchable by page, element, outcome
|
||||
- Prevents re-running failed tests
|
||||
- Builds institutional knowledge
|
||||
Store records in a shared, searchable location to avoid repeated failures.
|
||||
|
||||
---
|
||||
|
||||
## Output Format
|
||||
## Refusal Conditions (Safety)
|
||||
|
||||
### Test Plan Document
|
||||
Refuse to proceed if:
|
||||
|
||||
```
|
||||
# A/B Test: [Name]
|
||||
- Baseline rate is unknown and cannot be estimated
|
||||
- Traffic is insufficient to detect the MDE
|
||||
- Primary metric is undefined
|
||||
- Multiple variables are changed without proper design
|
||||
- Hypothesis cannot be clearly stated
|
||||
|
||||
## Hypothesis
|
||||
[Full hypothesis using framework]
|
||||
|
||||
## Test Design
|
||||
- Type: A/B / A/B/n / MVT
|
||||
- Duration: X weeks
|
||||
- Sample size: X per variant
|
||||
- Traffic allocation: 50/50
|
||||
|
||||
## Variants
|
||||
[Control and variant descriptions with visuals]
|
||||
|
||||
## Metrics
|
||||
- Primary: [metric and definition]
|
||||
- Secondary: [list]
|
||||
- Guardrails: [list]
|
||||
|
||||
## Implementation
|
||||
- Method: Client-side / Server-side
|
||||
- Tool: [Tool name]
|
||||
- Dev requirements: [If any]
|
||||
|
||||
## Analysis Plan
|
||||
- Success criteria: [What constitutes a win]
|
||||
- Segment analysis: [Planned segments]
|
||||
```
|
||||
|
||||
### Results Summary
|
||||
When test is complete
|
||||
|
||||
### Recommendations
|
||||
Next steps based on results
|
||||
Explain why and recommend next steps.
|
||||
|
||||
---
|
||||
|
||||
## Common Mistakes
|
||||
## Key Principles (Non-Negotiable)
|
||||
|
||||
### Test Design
|
||||
- Testing too small a change (undetectable)
|
||||
- Testing too many things (can't isolate)
|
||||
- No clear hypothesis
|
||||
- Wrong audience
|
||||
|
||||
### Execution
|
||||
- Stopping early
|
||||
- Changing things mid-test
|
||||
- Not checking implementation
|
||||
- Uneven traffic allocation
|
||||
|
||||
### Analysis
|
||||
- Ignoring confidence intervals
|
||||
- Cherry-picking segments
|
||||
- Over-interpreting inconclusive results
|
||||
- Not considering practical significance
|
||||
- One hypothesis per test
|
||||
- One primary metric
|
||||
- Commit before launch
|
||||
- No peeking
|
||||
- Learning over winning
|
||||
- Statistical rigor first
|
||||
|
||||
---
|
||||
|
||||
## Questions to Ask
|
||||
## Final Reminder
|
||||
|
||||
If you need more context:
|
||||
1. What's your current conversion rate?
|
||||
2. How much traffic does this page get?
|
||||
3. What change are you considering and why?
|
||||
4. What's the smallest improvement worth detecting?
|
||||
5. What tools do you have for testing?
|
||||
6. Have you tested this area before?
|
||||
A/B testing is not about proving ideas right.
|
||||
It is about **learning the truth with confidence**.
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- **page-cro**: For generating test ideas based on CRO principles
|
||||
- **analytics-tracking**: For setting up test measurement
|
||||
- **copywriting**: For creating variant copy
|
||||
If you feel tempted to rush, simplify, or “just try it” —
|
||||
that is the signal to **slow down and re-check the design**.
|
||||
|
||||
82
skills/agent-memory-mcp/SKILL.md
Normal file
82
skills/agent-memory-mcp/SKILL.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: agent-memory-mcp
|
||||
author: Amit Rathiesh
|
||||
description: A hybrid memory system that provides persistent, searchable knowledge management for AI agents (Architecture, Patterns, Decisions).
|
||||
---
|
||||
|
||||
# Agent Memory Skill
|
||||
|
||||
This skill provides a persistent, searchable memory bank that automatically syncs with project documentation. It runs as an MCP server to allow reading/writing/searching of long-term memories.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (v18+)
|
||||
|
||||
## Setup
|
||||
|
||||
1. **Clone the Repository**:
|
||||
Clone the `agentMemory` project into your agent's workspace or a parallel directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/webzler/agentMemory.git .agent/skills/agent-memory
|
||||
```
|
||||
|
||||
2. **Install Dependencies**:
|
||||
|
||||
```bash
|
||||
cd .agent/skills/agent-memory
|
||||
npm install
|
||||
npm run compile
|
||||
```
|
||||
|
||||
3. **Start the MCP Server**:
|
||||
Use the helper script to activate the memory bank for your current project:
|
||||
|
||||
```bash
|
||||
npm run start-server <project_id> <absolute_path_to_target_workspace>
|
||||
```
|
||||
|
||||
_Example for current directory:_
|
||||
|
||||
```bash
|
||||
npm run start-server my-project $(pwd)
|
||||
```
|
||||
|
||||
## Capabilities (MCP Tools)
|
||||
|
||||
### `memory_search`
|
||||
|
||||
Search for memories by query, type, or tags.
|
||||
|
||||
- **Args**: `query` (string), `type?` (string), `tags?` (string[])
|
||||
- **Usage**: "Find all authentication patterns" -> `memory_search({ query: "authentication", type: "pattern" })`
|
||||
|
||||
### `memory_write`
|
||||
|
||||
Record new knowledge or decisions.
|
||||
|
||||
- **Args**: `key` (string), `type` (string), `content` (string), `tags?` (string[])
|
||||
- **Usage**: "Save this architecture decision" -> `memory_write({ key: "auth-v1", type: "decision", content: "..." })`
|
||||
|
||||
### `memory_read`
|
||||
|
||||
Retrieve specific memory content by key.
|
||||
|
||||
- **Args**: `key` (string)
|
||||
- **Usage**: "Get the auth design" -> `memory_read({ key: "auth-v1" })`
|
||||
|
||||
### `memory_stats`
|
||||
|
||||
View analytics on memory usage.
|
||||
|
||||
- **Usage**: "Show memory statistics" -> `memory_stats({})`
|
||||
|
||||
## Dashboard
|
||||
|
||||
This skill includes a standalone dashboard to visualize memory usage.
|
||||
|
||||
```bash
|
||||
npm run start-dashboard <absolute_path_to_target_workspace>
|
||||
```
|
||||
|
||||
Access at: `http://localhost:3333`
|
||||
@@ -1,539 +1,404 @@
|
||||
---
|
||||
name: analytics-tracking
|
||||
description: When the user wants to set up, improve, or audit analytics tracking and measurement. Also use when the user mentions "set up tracking," "GA4," "Google Analytics," "conversion tracking," "event tracking," "UTM parameters," "tag manager," "GTM," "analytics implementation," or "tracking plan." For A/B test measurement, see ab-test-setup.
|
||||
description: >
|
||||
Design, audit, and improve analytics tracking systems that produce reliable,
|
||||
decision-ready data. Use when the user wants to set up, fix, or evaluate
|
||||
analytics tracking (GA4, GTM, product analytics, events, conversions, UTMs).
|
||||
This skill focuses on measurement strategy, signal quality, and validation—
|
||||
not just firing events.
|
||||
---
|
||||
|
||||
# Analytics Tracking
|
||||
# Analytics Tracking & Measurement Strategy
|
||||
|
||||
You are an expert in analytics implementation and measurement. Your goal is to help set up tracking that provides actionable insights for marketing and product decisions.
|
||||
You are an expert in **analytics implementation and measurement design**.
|
||||
Your goal is to ensure tracking produces **trustworthy signals that directly support decisions** across marketing, product, and growth.
|
||||
|
||||
## Initial Assessment
|
||||
|
||||
Before implementing tracking, understand:
|
||||
|
||||
1. **Business Context**
|
||||
- What decisions will this data inform?
|
||||
- What are the key conversion actions?
|
||||
- What questions need answering?
|
||||
|
||||
2. **Current State**
|
||||
- What tracking exists?
|
||||
- What tools are in use (GA4, Mixpanel, Amplitude, etc.)?
|
||||
- What's working/not working?
|
||||
|
||||
3. **Technical Context**
|
||||
- What's the tech stack?
|
||||
- Who will implement and maintain?
|
||||
- Any privacy/compliance requirements?
|
||||
You do **not** track everything.
|
||||
You do **not** optimize dashboards without fixing instrumentation.
|
||||
You do **not** treat GA4 numbers as truth unless validated.
|
||||
|
||||
---
|
||||
|
||||
## Core Principles
|
||||
## Phase 0: Measurement Readiness & Signal Quality Index (Required)
|
||||
|
||||
### 1. Track for Decisions, Not Data
|
||||
- Every event should inform a decision
|
||||
- Avoid vanity metrics
|
||||
- Quality > quantity of events
|
||||
Before adding or changing tracking, calculate the **Measurement Readiness & Signal Quality Index**.
|
||||
|
||||
### 2. Start with the Questions
|
||||
- What do you need to know?
|
||||
- What actions will you take based on this data?
|
||||
- Work backwards to what you need to track
|
||||
### Purpose
|
||||
|
||||
### 3. Name Things Consistently
|
||||
- Naming conventions matter
|
||||
- Establish patterns before implementing
|
||||
- Document everything
|
||||
This index answers:
|
||||
|
||||
### 4. Maintain Data Quality
|
||||
- Validate implementation
|
||||
- Monitor for issues
|
||||
- Clean data > more data
|
||||
> **Can this analytics setup produce reliable, decision-grade insights?**
|
||||
|
||||
It prevents:
|
||||
|
||||
* event sprawl
|
||||
* vanity tracking
|
||||
* misleading conversion data
|
||||
* false confidence in broken analytics
|
||||
|
||||
---
|
||||
|
||||
## Tracking Plan Framework
|
||||
## 🔢 Measurement Readiness & Signal Quality Index
|
||||
|
||||
### Structure
|
||||
### Total Score: **0–100**
|
||||
|
||||
This is a **diagnostic score**, not a performance KPI.
|
||||
|
||||
---
|
||||
|
||||
### Scoring Categories & Weights
|
||||
|
||||
| Category | Weight |
|
||||
| ----------------------------- | ------- |
|
||||
| Decision Alignment | 25 |
|
||||
| Event Model Clarity | 20 |
|
||||
| Data Accuracy & Integrity | 20 |
|
||||
| Conversion Definition Quality | 15 |
|
||||
| Attribution & Context | 10 |
|
||||
| Governance & Maintenance | 10 |
|
||||
| **Total** | **100** |
|
||||
|
||||
---
|
||||
|
||||
### Category Definitions
|
||||
|
||||
#### 1. Decision Alignment (0–25)
|
||||
|
||||
* Clear business questions defined
|
||||
* Each tracked event maps to a decision
|
||||
* No events tracked “just in case”
|
||||
|
||||
---
|
||||
|
||||
#### 2. Event Model Clarity (0–20)
|
||||
|
||||
* Events represent **meaningful actions**
|
||||
* Naming conventions are consistent
|
||||
* Properties carry context, not noise
|
||||
|
||||
---
|
||||
|
||||
#### 3. Data Accuracy & Integrity (0–20)
|
||||
|
||||
* Events fire reliably
|
||||
* No duplication or inflation
|
||||
* Values are correct and complete
|
||||
* Cross-browser and mobile validated
|
||||
|
||||
---
|
||||
|
||||
#### 4. Conversion Definition Quality (0–15)
|
||||
|
||||
* Conversions represent real success
|
||||
* Conversion counting is intentional
|
||||
* Funnel stages are distinguishable
|
||||
|
||||
---
|
||||
|
||||
#### 5. Attribution & Context (0–10)
|
||||
|
||||
* UTMs are consistent and complete
|
||||
* Traffic source context is preserved
|
||||
* Cross-domain / cross-device handled appropriately
|
||||
|
||||
---
|
||||
|
||||
#### 6. Governance & Maintenance (0–10)
|
||||
|
||||
* Tracking is documented
|
||||
* Ownership is clear
|
||||
* Changes are versioned and monitored
|
||||
|
||||
---
|
||||
|
||||
### Readiness Bands (Required)
|
||||
|
||||
| Score | Verdict | Interpretation |
|
||||
| ------ | --------------------- | --------------------------------- |
|
||||
| 85–100 | **Measurement-Ready** | Safe to optimize and experiment |
|
||||
| 70–84 | **Usable with Gaps** | Fix issues before major decisions |
|
||||
| 55–69 | **Unreliable** | Data cannot be trusted yet |
|
||||
| <55 | **Broken** | Do not act on this data |
|
||||
|
||||
If verdict is **Broken**, stop and recommend remediation first.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Context & Decision Definition
|
||||
|
||||
(Proceed only after scoring)
|
||||
|
||||
### 1. Business Context
|
||||
|
||||
* What decisions will this data inform?
|
||||
* Who uses the data (marketing, product, leadership)?
|
||||
* What actions will be taken based on insights?
|
||||
|
||||
---
|
||||
|
||||
### 2. Current State
|
||||
|
||||
* Tools in use (GA4, GTM, Mixpanel, Amplitude, etc.)
|
||||
* Existing events and conversions
|
||||
* Known issues or distrust in data
|
||||
|
||||
---
|
||||
|
||||
### 3. Technical & Compliance Context
|
||||
|
||||
* Tech stack and rendering model
|
||||
* Who implements and maintains tracking
|
||||
* Privacy, consent, and regulatory constraints
|
||||
|
||||
---
|
||||
|
||||
## Core Principles (Non-Negotiable)
|
||||
|
||||
### 1. Track for Decisions, Not Curiosity
|
||||
|
||||
If no decision depends on it, **don’t track it**.
|
||||
|
||||
---
|
||||
|
||||
### 2. Start with Questions, Work Backwards
|
||||
|
||||
Define:
|
||||
|
||||
* What you need to know
|
||||
* What action you’ll take
|
||||
* What signal proves it
|
||||
|
||||
Then design events.
|
||||
|
||||
---
|
||||
|
||||
### 3. Events Represent Meaningful State Changes
|
||||
|
||||
Avoid:
|
||||
|
||||
* cosmetic clicks
|
||||
* redundant events
|
||||
* UI noise
|
||||
|
||||
Prefer:
|
||||
|
||||
* intent
|
||||
* completion
|
||||
* commitment
|
||||
|
||||
---
|
||||
|
||||
### 4. Data Quality Beats Volume
|
||||
|
||||
Fewer accurate events > many unreliable ones.
|
||||
|
||||
---
|
||||
|
||||
## Event Model Design
|
||||
|
||||
### Event Taxonomy
|
||||
|
||||
**Navigation / Exposure**
|
||||
|
||||
* page_view (enhanced)
|
||||
* content_viewed
|
||||
* pricing_viewed
|
||||
|
||||
**Intent Signals**
|
||||
|
||||
* cta_clicked
|
||||
* form_started
|
||||
* demo_requested
|
||||
|
||||
**Completion Signals**
|
||||
|
||||
* signup_completed
|
||||
* purchase_completed
|
||||
* subscription_changed
|
||||
|
||||
**System / State Changes**
|
||||
|
||||
* onboarding_completed
|
||||
* feature_activated
|
||||
* error_occurred
|
||||
|
||||
---
|
||||
|
||||
### Event Naming Conventions
|
||||
|
||||
**Recommended pattern:**
|
||||
|
||||
```
|
||||
Event Name | Event Category | Properties | Trigger | Notes
|
||||
---------- | ------------- | ---------- | ------- | -----
|
||||
object_action[_context]
|
||||
```
|
||||
|
||||
### Event Types
|
||||
Examples:
|
||||
|
||||
**Pageviews**
|
||||
- Automatic in most tools
|
||||
- Enhanced with page metadata
|
||||
* signup_completed
|
||||
* pricing_viewed
|
||||
* cta_hero_clicked
|
||||
* onboarding_step_completed
|
||||
|
||||
**User Actions**
|
||||
- Button clicks
|
||||
- Form submissions
|
||||
- Feature usage
|
||||
- Content interactions
|
||||
Rules:
|
||||
|
||||
**System Events**
|
||||
- Signup completed
|
||||
- Purchase completed
|
||||
- Subscription changed
|
||||
- Errors occurred
|
||||
|
||||
**Custom Conversions**
|
||||
- Goal completions
|
||||
- Funnel stages
|
||||
- Business-specific milestones
|
||||
* lowercase
|
||||
* underscores
|
||||
* no spaces
|
||||
* no ambiguity
|
||||
|
||||
---
|
||||
|
||||
## Event Naming Conventions
|
||||
### Event Properties (Context, Not Noise)
|
||||
|
||||
### Format Options
|
||||
Include:
|
||||
|
||||
**Object-Action (Recommended)**
|
||||
```
|
||||
signup_completed
|
||||
button_clicked
|
||||
form_submitted
|
||||
article_read
|
||||
```
|
||||
* where (page, section)
|
||||
* who (user_type, plan)
|
||||
* how (method, variant)
|
||||
|
||||
**Action-Object**
|
||||
```
|
||||
click_button
|
||||
submit_form
|
||||
complete_signup
|
||||
```
|
||||
Avoid:
|
||||
|
||||
**Category_Object_Action**
|
||||
```
|
||||
checkout_payment_completed
|
||||
blog_article_viewed
|
||||
onboarding_step_completed
|
||||
```
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Lowercase with underscores
|
||||
- Be specific: `cta_hero_clicked` vs. `button_clicked`
|
||||
- Include context in properties, not event name
|
||||
- Avoid spaces and special characters
|
||||
- Document decisions
|
||||
* PII
|
||||
* free-text fields
|
||||
* duplicated auto-properties
|
||||
|
||||
---
|
||||
|
||||
## Essential Events to Track
|
||||
## Conversion Strategy
|
||||
|
||||
### Marketing Site
|
||||
### What Qualifies as a Conversion
|
||||
|
||||
**Navigation**
|
||||
- page_view (enhanced)
|
||||
- outbound_link_clicked
|
||||
- scroll_depth (25%, 50%, 75%, 100%)
|
||||
A conversion must represent:
|
||||
|
||||
**Engagement**
|
||||
- cta_clicked (button_text, location)
|
||||
- video_played (video_id, duration)
|
||||
- form_started
|
||||
- form_submitted (form_type)
|
||||
- resource_downloaded (resource_name)
|
||||
* real value
|
||||
* completed intent
|
||||
* irreversible progress
|
||||
|
||||
**Conversion**
|
||||
- signup_started
|
||||
- signup_completed
|
||||
- demo_requested
|
||||
- contact_submitted
|
||||
Examples:
|
||||
|
||||
### Product/App
|
||||
* signup_completed
|
||||
* purchase_completed
|
||||
* demo_booked
|
||||
|
||||
**Onboarding**
|
||||
- signup_completed
|
||||
- onboarding_step_completed (step_number, step_name)
|
||||
- onboarding_completed
|
||||
- first_key_action_completed
|
||||
Not conversions:
|
||||
|
||||
**Core Usage**
|
||||
- feature_used (feature_name)
|
||||
- action_completed (action_type)
|
||||
- session_started
|
||||
- session_ended
|
||||
|
||||
**Monetization**
|
||||
- trial_started
|
||||
- pricing_viewed
|
||||
- checkout_started
|
||||
- purchase_completed (plan, value)
|
||||
- subscription_cancelled
|
||||
|
||||
### E-commerce
|
||||
|
||||
**Browsing**
|
||||
- product_viewed (product_id, category, price)
|
||||
- product_list_viewed (list_name, products)
|
||||
- product_searched (query, results_count)
|
||||
|
||||
**Cart**
|
||||
- product_added_to_cart
|
||||
- product_removed_from_cart
|
||||
- cart_viewed
|
||||
|
||||
**Checkout**
|
||||
- checkout_started
|
||||
- checkout_step_completed (step)
|
||||
- payment_info_entered
|
||||
- purchase_completed (order_id, value, products)
|
||||
* page views
|
||||
* button clicks
|
||||
* form starts
|
||||
|
||||
---
|
||||
|
||||
## Event Properties (Parameters)
|
||||
### Conversion Counting Rules
|
||||
|
||||
### Standard Properties to Consider
|
||||
|
||||
**Page/Screen**
|
||||
- page_title
|
||||
- page_location (URL)
|
||||
- page_referrer
|
||||
- content_group
|
||||
|
||||
**User**
|
||||
- user_id (if logged in)
|
||||
- user_type (free, paid, admin)
|
||||
- account_id (B2B)
|
||||
- plan_type
|
||||
|
||||
**Campaign**
|
||||
- source
|
||||
- medium
|
||||
- campaign
|
||||
- content
|
||||
- term
|
||||
|
||||
**Product** (e-commerce)
|
||||
- product_id
|
||||
- product_name
|
||||
- category
|
||||
- price
|
||||
- quantity
|
||||
- currency
|
||||
|
||||
**Timing**
|
||||
- timestamp
|
||||
- session_duration
|
||||
- time_on_page
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Use consistent property names
|
||||
- Include relevant context
|
||||
- Don't duplicate GA4 automatic properties
|
||||
- Avoid PII in properties
|
||||
- Document expected values
|
||||
* Once per session vs every occurrence
|
||||
* Explicitly documented
|
||||
* Consistent across tools
|
||||
|
||||
---
|
||||
|
||||
## GA4 Implementation
|
||||
## GA4 & GTM (Implementation Guidance)
|
||||
|
||||
### Configuration
|
||||
*(Tool-specific, but optional)*
|
||||
|
||||
**Data Streams**
|
||||
- One stream per platform (web, iOS, Android)
|
||||
- Enable enhanced measurement
|
||||
|
||||
**Enhanced Measurement Events**
|
||||
- page_view (automatic)
|
||||
- scroll (90% depth)
|
||||
- outbound_click
|
||||
- site_search
|
||||
- video_engagement
|
||||
- file_download
|
||||
|
||||
**Recommended Events**
|
||||
- Use Google's predefined events when possible
|
||||
- Correct naming for enhanced reporting
|
||||
- See: https://support.google.com/analytics/answer/9267735
|
||||
|
||||
### Custom Events (GA4)
|
||||
|
||||
```javascript
|
||||
// gtag.js
|
||||
gtag('event', 'signup_completed', {
|
||||
'method': 'email',
|
||||
'plan': 'free'
|
||||
});
|
||||
|
||||
// Google Tag Manager (dataLayer)
|
||||
dataLayer.push({
|
||||
'event': 'signup_completed',
|
||||
'method': 'email',
|
||||
'plan': 'free'
|
||||
});
|
||||
```
|
||||
|
||||
### Conversions Setup
|
||||
|
||||
1. Collect event in GA4
|
||||
2. Mark as conversion in Admin > Events
|
||||
3. Set conversion counting (once per session or every time)
|
||||
4. Import to Google Ads if needed
|
||||
|
||||
### Custom Dimensions and Metrics
|
||||
|
||||
**When to use:**
|
||||
- Properties you want to segment by
|
||||
- Metrics you want to aggregate
|
||||
- Beyond standard parameters
|
||||
|
||||
**Setup:**
|
||||
1. Create in Admin > Custom definitions
|
||||
2. Scope: Event, User, or Item
|
||||
3. Parameter name must match
|
||||
* Prefer GA4 recommended events
|
||||
* Use GTM for orchestration, not logic
|
||||
* Push clean dataLayer events
|
||||
* Avoid multiple containers
|
||||
* Version every publish
|
||||
|
||||
---
|
||||
|
||||
## Google Tag Manager Implementation
|
||||
## UTM & Attribution Discipline
|
||||
|
||||
### Container Structure
|
||||
### UTM Rules
|
||||
|
||||
**Tags**
|
||||
- GA4 Configuration (base)
|
||||
- GA4 Event tags (one per event or grouped)
|
||||
- Conversion pixels (Facebook, LinkedIn, etc.)
|
||||
* lowercase only
|
||||
* consistent separators
|
||||
* documented centrally
|
||||
* never overwritten client-side
|
||||
|
||||
**Triggers**
|
||||
- Page View (DOM Ready, Window Loaded)
|
||||
- Click - All Elements / Just Links
|
||||
- Form Submission
|
||||
- Custom Events
|
||||
|
||||
**Variables**
|
||||
- Built-in: Click Text, Click URL, Page Path, etc.
|
||||
- Data Layer variables
|
||||
- JavaScript variables
|
||||
- Lookup tables
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Use folders to organize
|
||||
- Consistent naming (Tag_Type_Description)
|
||||
- Version notes on every publish
|
||||
- Preview mode for testing
|
||||
- Workspaces for team collaboration
|
||||
|
||||
### Data Layer Pattern
|
||||
|
||||
```javascript
|
||||
// Push custom event
|
||||
dataLayer.push({
|
||||
'event': 'form_submitted',
|
||||
'form_name': 'contact',
|
||||
'form_location': 'footer'
|
||||
});
|
||||
|
||||
// Set user properties
|
||||
dataLayer.push({
|
||||
'user_id': '12345',
|
||||
'user_type': 'premium'
|
||||
});
|
||||
|
||||
// E-commerce event
|
||||
dataLayer.push({
|
||||
'event': 'purchase',
|
||||
'ecommerce': {
|
||||
'transaction_id': 'T12345',
|
||||
'value': 99.99,
|
||||
'currency': 'USD',
|
||||
'items': [{
|
||||
'item_id': 'SKU123',
|
||||
'item_name': 'Product Name',
|
||||
'price': 99.99
|
||||
}]
|
||||
}
|
||||
});
|
||||
```
|
||||
UTMs exist to **explain performance**, not inflate numbers.
|
||||
|
||||
---
|
||||
|
||||
## UTM Parameter Strategy
|
||||
## Validation & Debugging
|
||||
|
||||
### Standard Parameters
|
||||
### Required Validation
|
||||
|
||||
| Parameter | Purpose | Example |
|
||||
|-----------|---------|---------|
|
||||
| utm_source | Where traffic comes from | google, facebook, newsletter |
|
||||
| utm_medium | Marketing medium | cpc, email, social, referral |
|
||||
| utm_campaign | Campaign name | spring_sale, product_launch |
|
||||
| utm_content | Differentiate versions | hero_cta, sidebar_link |
|
||||
| utm_term | Paid search keywords | running+shoes |
|
||||
* Real-time verification
|
||||
* Duplicate detection
|
||||
* Cross-browser testing
|
||||
* Mobile testing
|
||||
* Consent-state testing
|
||||
|
||||
### Naming Conventions
|
||||
### Common Failure Modes
|
||||
|
||||
**Lowercase everything**
|
||||
- google, not Google
|
||||
- email, not Email
|
||||
|
||||
**Use underscores or hyphens consistently**
|
||||
- product_launch or product-launch
|
||||
- Pick one, stick with it
|
||||
|
||||
**Be specific but concise**
|
||||
- blog_footer_cta, not cta1
|
||||
- 2024_q1_promo, not promo
|
||||
|
||||
### UTM Documentation
|
||||
|
||||
Track all UTMs in a spreadsheet or tool:
|
||||
|
||||
| Campaign | Source | Medium | Content | Full URL | Owner | Date |
|
||||
|----------|--------|--------|---------|----------|-------|------|
|
||||
| ... | ... | ... | ... | ... | ... | ... |
|
||||
|
||||
### UTM Builder
|
||||
|
||||
Provide a consistent UTM builder link to team:
|
||||
- Google's URL builder
|
||||
- Internal tool
|
||||
- Spreadsheet formula
|
||||
* double firing
|
||||
* missing properties
|
||||
* broken attribution
|
||||
* PII leakage
|
||||
* inflated conversions
|
||||
|
||||
---
|
||||
|
||||
## Debugging and Validation
|
||||
## Privacy & Compliance
|
||||
|
||||
### Testing Tools
|
||||
* Consent before tracking where required
|
||||
* Data minimization
|
||||
* User deletion support
|
||||
* Retention policies reviewed
|
||||
|
||||
**GA4 DebugView**
|
||||
- Real-time event monitoring
|
||||
- Enable with ?debug_mode=true
|
||||
- Or via Chrome extension
|
||||
|
||||
**GTM Preview Mode**
|
||||
- Test triggers and tags
|
||||
- See data layer state
|
||||
- Validate before publish
|
||||
|
||||
**Browser Extensions**
|
||||
- GA Debugger
|
||||
- Tag Assistant
|
||||
- dataLayer Inspector
|
||||
|
||||
### Validation Checklist
|
||||
|
||||
- [ ] Events firing on correct triggers
|
||||
- [ ] Property values populating correctly
|
||||
- [ ] No duplicate events
|
||||
- [ ] Works across browsers
|
||||
- [ ] Works on mobile
|
||||
- [ ] Conversions recorded correctly
|
||||
- [ ] User ID passing when logged in
|
||||
- [ ] No PII leaking
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Events not firing**
|
||||
- Trigger misconfigured
|
||||
- Tag paused
|
||||
- GTM not loaded on page
|
||||
|
||||
**Wrong values**
|
||||
- Variable not configured
|
||||
- Data layer not pushing correctly
|
||||
- Timing issues (fire before data ready)
|
||||
|
||||
**Duplicate events**
|
||||
- Multiple GTM containers
|
||||
- Multiple tag instances
|
||||
- Trigger firing multiple times
|
||||
Analytics that violate trust undermine optimization.
|
||||
|
||||
---
|
||||
|
||||
## Privacy and Compliance
|
||||
## Output Format (Required)
|
||||
|
||||
### Considerations
|
||||
### Measurement Strategy Summary
|
||||
|
||||
- Cookie consent required in EU/UK/CA
|
||||
- No PII in analytics properties
|
||||
- Data retention settings
|
||||
- User deletion capabilities
|
||||
- Cross-device tracking consent
|
||||
|
||||
### Implementation
|
||||
|
||||
**Consent Mode (GA4)**
|
||||
- Wait for consent before tracking
|
||||
- Use consent mode for partial tracking
|
||||
- Integrate with consent management platform
|
||||
|
||||
**Data Minimization**
|
||||
- Only collect what you need
|
||||
- IP anonymization
|
||||
- No PII in custom dimensions
|
||||
* Measurement Readiness Index score + verdict
|
||||
* Key risks and gaps
|
||||
* Recommended remediation order
|
||||
|
||||
---
|
||||
|
||||
## Output Format
|
||||
### Tracking Plan
|
||||
|
||||
### Tracking Plan Document
|
||||
|
||||
```
|
||||
# [Site/Product] Tracking Plan
|
||||
|
||||
## Overview
|
||||
- Tools: GA4, GTM
|
||||
- Last updated: [Date]
|
||||
- Owner: [Name]
|
||||
|
||||
## Events
|
||||
|
||||
### Marketing Events
|
||||
|
||||
| Event Name | Description | Properties | Trigger |
|
||||
|------------|-------------|------------|---------|
|
||||
| signup_started | User initiates signup | source, page | Click signup CTA |
|
||||
| signup_completed | User completes signup | method, plan | Signup success page |
|
||||
|
||||
### Product Events
|
||||
[Similar table]
|
||||
|
||||
## Custom Dimensions
|
||||
|
||||
| Name | Scope | Parameter | Description |
|
||||
|------|-------|-----------|-------------|
|
||||
| user_type | User | user_type | Free, trial, paid |
|
||||
|
||||
## Conversions
|
||||
|
||||
| Conversion | Event | Counting | Google Ads |
|
||||
|------------|-------|----------|------------|
|
||||
| Signup | signup_completed | Once per session | Yes |
|
||||
|
||||
## UTM Convention
|
||||
|
||||
[Guidelines]
|
||||
```
|
||||
|
||||
### Implementation Code
|
||||
|
||||
Provide ready-to-use code snippets
|
||||
|
||||
### Testing Checklist
|
||||
|
||||
Specific validation steps
|
||||
| Event | Description | Properties | Trigger | Decision Supported |
|
||||
| ----- | ----------- | ---------- | ------- | ------------------ |
|
||||
|
||||
---
|
||||
|
||||
## Questions to Ask
|
||||
### Conversions
|
||||
|
||||
If you need more context:
|
||||
1. What tools are you using (GA4, Mixpanel, etc.)?
|
||||
2. What key actions do you want to track?
|
||||
3. What decisions will this data inform?
|
||||
4. Who implements - dev team or marketing?
|
||||
5. Are there privacy/consent requirements?
|
||||
6. What's already tracked?
|
||||
| Conversion | Event | Counting | Used By |
|
||||
| ---------- | ----- | -------- | ------- |
|
||||
|
||||
---
|
||||
|
||||
### Implementation Notes
|
||||
|
||||
* Tool-specific setup
|
||||
* Ownership
|
||||
* Validation steps
|
||||
|
||||
---
|
||||
|
||||
## Questions to Ask (If Needed)
|
||||
|
||||
1. What decisions depend on this data?
|
||||
2. Which metrics are currently trusted or distrusted?
|
||||
3. Who owns analytics long term?
|
||||
4. What compliance constraints apply?
|
||||
5. What tools are already in place?
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- **ab-test-setup**: For experiment tracking
|
||||
- **seo-audit**: For organic traffic analysis
|
||||
- **page-cro**: For conversion optimization (uses this data)
|
||||
* **page-cro** – Uses this data for optimization
|
||||
* **ab-test-setup** – Requires clean conversions
|
||||
* **seo-audit** – Organic performance analysis
|
||||
* **programmatic-seo** – Scale requires reliable signals
|
||||
|
||||
---
|
||||
|
||||
484
skills/api-documentation-generator/SKILL.md
Normal file
484
skills/api-documentation-generator/SKILL.md
Normal file
@@ -0,0 +1,484 @@
|
||||
---
|
||||
name: api-documentation-generator
|
||||
description: "Generate comprehensive, developer-friendly API documentation from code, including endpoints, parameters, examples, and best practices"
|
||||
---
|
||||
|
||||
# API Documentation Generator
|
||||
|
||||
## Overview
|
||||
|
||||
Automatically generate clear, comprehensive API documentation from your codebase. This skill helps you create professional documentation that includes endpoint descriptions, request/response examples, authentication details, error handling, and usage guidelines.
|
||||
|
||||
Perfect for REST APIs, GraphQL APIs, and WebSocket APIs.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Use when you need to document a new API
|
||||
- Use when updating existing API documentation
|
||||
- Use when your API lacks clear documentation
|
||||
- Use when onboarding new developers to your API
|
||||
- Use when preparing API documentation for external users
|
||||
- Use when creating OpenAPI/Swagger specifications
|
||||
|
||||
## How It Works
|
||||
|
||||
### Step 1: Analyze the API Structure
|
||||
|
||||
First, I'll examine your API codebase to understand:
|
||||
- Available endpoints and routes
|
||||
- HTTP methods (GET, POST, PUT, DELETE, etc.)
|
||||
- Request parameters and body structure
|
||||
- Response formats and status codes
|
||||
- Authentication and authorization requirements
|
||||
- Error handling patterns
|
||||
|
||||
### Step 2: Generate Endpoint Documentation
|
||||
|
||||
For each endpoint, I'll create documentation including:
|
||||
|
||||
**Endpoint Details:**
|
||||
- HTTP method and URL path
|
||||
- Brief description of what it does
|
||||
- Authentication requirements
|
||||
- Rate limiting information (if applicable)
|
||||
|
||||
**Request Specification:**
|
||||
- Path parameters
|
||||
- Query parameters
|
||||
- Request headers
|
||||
- Request body schema (with types and validation rules)
|
||||
|
||||
**Response Specification:**
|
||||
- Success response (status code + body structure)
|
||||
- Error responses (all possible error codes)
|
||||
- Response headers
|
||||
|
||||
**Code Examples:**
|
||||
- cURL command
|
||||
- JavaScript/TypeScript (fetch/axios)
|
||||
- Python (requests)
|
||||
- Other languages as needed
|
||||
|
||||
### Step 3: Add Usage Guidelines
|
||||
|
||||
I'll include:
|
||||
- Getting started guide
|
||||
- Authentication setup
|
||||
- Common use cases
|
||||
- Best practices
|
||||
- Rate limiting details
|
||||
- Pagination patterns
|
||||
- Filtering and sorting options
|
||||
|
||||
### Step 4: Document Error Handling
|
||||
|
||||
Clear error documentation including:
|
||||
- All possible error codes
|
||||
- Error message formats
|
||||
- Troubleshooting guide
|
||||
- Common error scenarios and solutions
|
||||
|
||||
### Step 5: Create Interactive Examples
|
||||
|
||||
Where possible, I'll provide:
|
||||
- Postman collection
|
||||
- OpenAPI/Swagger specification
|
||||
- Interactive code examples
|
||||
- Sample responses
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: REST API Endpoint Documentation
|
||||
|
||||
```markdown
|
||||
## Create User
|
||||
|
||||
Creates a new user account.
|
||||
|
||||
**Endpoint:** `POST /api/v1/users`
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Request Body:**
|
||||
\`\`\`json
|
||||
{
|
||||
"email": "user@example.com", // Required: Valid email address
|
||||
"password": "SecurePass123!", // Required: Min 8 chars, 1 uppercase, 1 number
|
||||
"name": "John Doe", // Required: 2-50 characters
|
||||
"role": "user" // Optional: "user" or "admin" (default: "user")
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Success Response (201 Created):**
|
||||
\`\`\`json
|
||||
{
|
||||
"id": "usr_1234567890",
|
||||
"email": "user@example.com",
|
||||
"name": "John Doe",
|
||||
"role": "user",
|
||||
"createdAt": "2026-01-20T10:30:00Z",
|
||||
"emailVerified": false
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
- `400 Bad Request` - Invalid input data
|
||||
\`\`\`json
|
||||
{
|
||||
"error": "VALIDATION_ERROR",
|
||||
"message": "Invalid email format",
|
||||
"field": "email"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
- `409 Conflict` - Email already exists
|
||||
\`\`\`json
|
||||
{
|
||||
"error": "EMAIL_EXISTS",
|
||||
"message": "An account with this email already exists"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
- `401 Unauthorized` - Missing or invalid authentication token
|
||||
|
||||
**Example Request (cURL):**
|
||||
\`\`\`bash
|
||||
curl -X POST https://api.example.com/api/v1/users \
|
||||
-H "Authorization: Bearer YOUR_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"email": "user@example.com",
|
||||
"password": "SecurePass123!",
|
||||
"name": "John Doe"
|
||||
}'
|
||||
\`\`\`
|
||||
|
||||
**Example Request (JavaScript):**
|
||||
\`\`\`javascript
|
||||
const response = await fetch('https://api.example.com/api/v1/users', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: 'user@example.com',
|
||||
password: 'SecurePass123!',
|
||||
name: 'John Doe'
|
||||
})
|
||||
});
|
||||
|
||||
const user = await response.json();
|
||||
console.log(user);
|
||||
\`\`\`
|
||||
|
||||
**Example Request (Python):**
|
||||
\`\`\`python
|
||||
import requests
|
||||
|
||||
response = requests.post(
|
||||
'https://api.example.com/api/v1/users',
|
||||
headers={
|
||||
'Authorization': f'Bearer {token}',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
json={
|
||||
'email': 'user@example.com',
|
||||
'password': 'SecurePass123!',
|
||||
'name': 'John Doe'
|
||||
}
|
||||
)
|
||||
|
||||
user = response.json()
|
||||
print(user)
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Example 2: GraphQL API Documentation
|
||||
|
||||
```markdown
|
||||
## User Query
|
||||
|
||||
Fetch user information by ID.
|
||||
|
||||
**Query:**
|
||||
\`\`\`graphql
|
||||
query GetUser($id: ID!) {
|
||||
user(id: $id) {
|
||||
id
|
||||
email
|
||||
name
|
||||
role
|
||||
createdAt
|
||||
posts {
|
||||
id
|
||||
title
|
||||
publishedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Variables:**
|
||||
\`\`\`json
|
||||
{
|
||||
"id": "usr_1234567890"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Response:**
|
||||
\`\`\`json
|
||||
{
|
||||
"data": {
|
||||
"user": {
|
||||
"id": "usr_1234567890",
|
||||
"email": "user@example.com",
|
||||
"name": "John Doe",
|
||||
"role": "user",
|
||||
"createdAt": "2026-01-20T10:30:00Z",
|
||||
"posts": [
|
||||
{
|
||||
"id": "post_123",
|
||||
"title": "My First Post",
|
||||
"publishedAt": "2026-01-21T14:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Errors:**
|
||||
\`\`\`json
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"message": "User not found",
|
||||
"extensions": {
|
||||
"code": "USER_NOT_FOUND",
|
||||
"userId": "usr_1234567890"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Example 3: Authentication Documentation
|
||||
|
||||
```markdown
|
||||
## Authentication
|
||||
|
||||
All API requests require authentication using Bearer tokens.
|
||||
|
||||
### Getting a Token
|
||||
|
||||
**Endpoint:** `POST /api/v1/auth/login`
|
||||
|
||||
**Request:**
|
||||
\`\`\`json
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "your-password"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Response:**
|
||||
\`\`\`json
|
||||
{
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"expiresIn": 3600,
|
||||
"refreshToken": "refresh_token_here"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
### Using the Token
|
||||
|
||||
Include the token in the Authorization header:
|
||||
|
||||
\`\`\`
|
||||
Authorization: Bearer YOUR_TOKEN
|
||||
\`\`\`
|
||||
|
||||
### Token Expiration
|
||||
|
||||
Tokens expire after 1 hour. Use the refresh token to get a new access token:
|
||||
|
||||
**Endpoint:** `POST /api/v1/auth/refresh`
|
||||
|
||||
**Request:**
|
||||
\`\`\`json
|
||||
{
|
||||
"refreshToken": "refresh_token_here"
|
||||
}
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ Do This
|
||||
|
||||
- **Be Consistent** - Use the same format for all endpoints
|
||||
- **Include Examples** - Provide working code examples in multiple languages
|
||||
- **Document Errors** - List all possible error codes and their meanings
|
||||
- **Show Real Data** - Use realistic example data, not "foo" and "bar"
|
||||
- **Explain Parameters** - Describe what each parameter does and its constraints
|
||||
- **Version Your API** - Include version numbers in URLs (/api/v1/)
|
||||
- **Add Timestamps** - Show when documentation was last updated
|
||||
- **Link Related Endpoints** - Help users discover related functionality
|
||||
- **Include Rate Limits** - Document any rate limiting policies
|
||||
- **Provide Postman Collection** - Make it easy to test your API
|
||||
|
||||
### ❌ Don't Do This
|
||||
|
||||
- **Don't Skip Error Cases** - Users need to know what can go wrong
|
||||
- **Don't Use Vague Descriptions** - "Gets data" is not helpful
|
||||
- **Don't Forget Authentication** - Always document auth requirements
|
||||
- **Don't Ignore Edge Cases** - Document pagination, filtering, sorting
|
||||
- **Don't Leave Examples Broken** - Test all code examples
|
||||
- **Don't Use Outdated Info** - Keep documentation in sync with code
|
||||
- **Don't Overcomplicate** - Keep it simple and scannable
|
||||
- **Don't Forget Response Headers** - Document important headers
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
### Recommended Sections
|
||||
|
||||
1. **Introduction**
|
||||
- What the API does
|
||||
- Base URL
|
||||
- API version
|
||||
- Support contact
|
||||
|
||||
2. **Authentication**
|
||||
- How to authenticate
|
||||
- Token management
|
||||
- Security best practices
|
||||
|
||||
3. **Quick Start**
|
||||
- Simple example to get started
|
||||
- Common use case walkthrough
|
||||
|
||||
4. **Endpoints**
|
||||
- Organized by resource
|
||||
- Full details for each endpoint
|
||||
|
||||
5. **Data Models**
|
||||
- Schema definitions
|
||||
- Field descriptions
|
||||
- Validation rules
|
||||
|
||||
6. **Error Handling**
|
||||
- Error code reference
|
||||
- Error response format
|
||||
- Troubleshooting guide
|
||||
|
||||
7. **Rate Limiting**
|
||||
- Limits and quotas
|
||||
- Headers to check
|
||||
- Handling rate limit errors
|
||||
|
||||
8. **Changelog**
|
||||
- API version history
|
||||
- Breaking changes
|
||||
- Deprecation notices
|
||||
|
||||
9. **SDKs and Tools**
|
||||
- Official client libraries
|
||||
- Postman collection
|
||||
- OpenAPI specification
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Problem: Documentation Gets Out of Sync
|
||||
**Symptoms:** Examples don't work, parameters are wrong, endpoints return different data
|
||||
**Solution:**
|
||||
- Generate docs from code comments/annotations
|
||||
- Use tools like Swagger/OpenAPI
|
||||
- Add API tests that validate documentation
|
||||
- Review docs with every API change
|
||||
|
||||
### Problem: Missing Error Documentation
|
||||
**Symptoms:** Users don't know how to handle errors, support tickets increase
|
||||
**Solution:**
|
||||
- Document every possible error code
|
||||
- Provide clear error messages
|
||||
- Include troubleshooting steps
|
||||
- Show example error responses
|
||||
|
||||
### Problem: Examples Don't Work
|
||||
**Symptoms:** Users can't get started, frustration increases
|
||||
**Solution:**
|
||||
- Test every code example
|
||||
- Use real, working endpoints
|
||||
- Include complete examples (not fragments)
|
||||
- Provide a sandbox environment
|
||||
|
||||
### Problem: Unclear Parameter Requirements
|
||||
**Symptoms:** Users send invalid requests, validation errors
|
||||
**Solution:**
|
||||
- Mark required vs optional clearly
|
||||
- Document data types and formats
|
||||
- Show validation rules
|
||||
- Provide example values
|
||||
|
||||
## Tools and Formats
|
||||
|
||||
### OpenAPI/Swagger
|
||||
Generate interactive documentation:
|
||||
```yaml
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: My API
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/users:
|
||||
post:
|
||||
summary: Create a new user
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateUserRequest'
|
||||
```
|
||||
|
||||
### Postman Collection
|
||||
Export collection for easy testing:
|
||||
```json
|
||||
{
|
||||
"info": {
|
||||
"name": "My API",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "Create User",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "{{baseUrl}}/api/v1/users"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `@doc-coauthoring` - For collaborative documentation writing
|
||||
- `@copywriting` - For clear, user-friendly descriptions
|
||||
- `@test-driven-development` - For ensuring API behavior matches docs
|
||||
- `@systematic-debugging` - For troubleshooting API issues
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [OpenAPI Specification](https://swagger.io/specification/)
|
||||
- [REST API Best Practices](https://restfulapi.net/)
|
||||
- [GraphQL Documentation](https://graphql.org/learn/)
|
||||
- [API Design Patterns](https://www.apiguide.com/)
|
||||
- [Postman Documentation](https://learning.postman.com/docs/)
|
||||
|
||||
---
|
||||
|
||||
**Pro Tip:** Keep your API documentation as close to your code as possible. Use tools that generate docs from code comments to ensure they stay in sync!
|
||||
907
skills/api-security-best-practices/SKILL.md
Normal file
907
skills/api-security-best-practices/SKILL.md
Normal file
@@ -0,0 +1,907 @@
|
||||
---
|
||||
name: api-security-best-practices
|
||||
description: "Implement secure API design patterns including authentication, authorization, input validation, rate limiting, and protection against common API vulnerabilities"
|
||||
---
|
||||
|
||||
# API Security Best Practices
|
||||
|
||||
## Overview
|
||||
|
||||
Guide developers in building secure APIs by implementing authentication, authorization, input validation, rate limiting, and protection against common vulnerabilities. This skill covers security patterns for REST, GraphQL, and WebSocket APIs.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Use when designing new API endpoints
|
||||
- Use when securing existing APIs
|
||||
- Use when implementing authentication and authorization
|
||||
- Use when protecting against API attacks (injection, DDoS, etc.)
|
||||
- Use when conducting API security reviews
|
||||
- Use when preparing for security audits
|
||||
- Use when implementing rate limiting and throttling
|
||||
- Use when handling sensitive data in APIs
|
||||
|
||||
## How It Works
|
||||
|
||||
### Step 1: Authentication & Authorization
|
||||
|
||||
I'll help you implement secure authentication:
|
||||
- Choose authentication method (JWT, OAuth 2.0, API keys)
|
||||
- Implement token-based authentication
|
||||
- Set up role-based access control (RBAC)
|
||||
- Secure session management
|
||||
- Implement multi-factor authentication (MFA)
|
||||
|
||||
### Step 2: Input Validation & Sanitization
|
||||
|
||||
Protect against injection attacks:
|
||||
- Validate all input data
|
||||
- Sanitize user inputs
|
||||
- Use parameterized queries
|
||||
- Implement request schema validation
|
||||
- Prevent SQL injection, XSS, and command injection
|
||||
|
||||
### Step 3: Rate Limiting & Throttling
|
||||
|
||||
Prevent abuse and DDoS attacks:
|
||||
- Implement rate limiting per user/IP
|
||||
- Set up API throttling
|
||||
- Configure request quotas
|
||||
- Handle rate limit errors gracefully
|
||||
- Monitor for suspicious activity
|
||||
|
||||
### Step 4: Data Protection
|
||||
|
||||
Secure sensitive data:
|
||||
- Encrypt data in transit (HTTPS/TLS)
|
||||
- Encrypt sensitive data at rest
|
||||
- Implement proper error handling (no data leaks)
|
||||
- Sanitize error messages
|
||||
- Use secure headers
|
||||
|
||||
### Step 5: API Security Testing
|
||||
|
||||
Verify security implementation:
|
||||
- Test authentication and authorization
|
||||
- Perform penetration testing
|
||||
- Check for common vulnerabilities (OWASP API Top 10)
|
||||
- Validate input handling
|
||||
- Test rate limiting
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Implementing JWT Authentication
|
||||
|
||||
```markdown
|
||||
## Secure JWT Authentication Implementation
|
||||
|
||||
### Authentication Flow
|
||||
|
||||
1. User logs in with credentials
|
||||
2. Server validates credentials
|
||||
3. Server generates JWT token
|
||||
4. Client stores token securely
|
||||
5. Client sends token with each request
|
||||
6. Server validates token
|
||||
|
||||
### Implementation
|
||||
|
||||
#### 1. Generate Secure JWT Tokens
|
||||
|
||||
\`\`\`javascript
|
||||
// auth.js
|
||||
const jwt = require('jsonwebtoken');
|
||||
const bcrypt = require('bcrypt');
|
||||
|
||||
// Login endpoint
|
||||
app.post('/api/auth/login', async (req, res) => {
|
||||
try {
|
||||
const { email, password } = req.body;
|
||||
|
||||
// Validate input
|
||||
if (!email || !password) {
|
||||
return res.status(400).json({
|
||||
error: 'Email and password are required'
|
||||
});
|
||||
}
|
||||
|
||||
// Find user
|
||||
const user = await db.user.findUnique({
|
||||
where: { email }
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
// Don't reveal if user exists
|
||||
return res.status(401).json({
|
||||
error: 'Invalid credentials'
|
||||
});
|
||||
}
|
||||
|
||||
// Verify password
|
||||
const validPassword = await bcrypt.compare(
|
||||
password,
|
||||
user.passwordHash
|
||||
);
|
||||
|
||||
if (!validPassword) {
|
||||
return res.status(401).json({
|
||||
error: 'Invalid credentials'
|
||||
});
|
||||
}
|
||||
|
||||
// Generate JWT token
|
||||
const token = jwt.sign(
|
||||
{
|
||||
userId: user.id,
|
||||
email: user.email,
|
||||
role: user.role
|
||||
},
|
||||
process.env.JWT_SECRET,
|
||||
{
|
||||
expiresIn: '1h',
|
||||
issuer: 'your-app',
|
||||
audience: 'your-app-users'
|
||||
}
|
||||
);
|
||||
|
||||
// Generate refresh token
|
||||
const refreshToken = jwt.sign(
|
||||
{ userId: user.id },
|
||||
process.env.JWT_REFRESH_SECRET,
|
||||
{ expiresIn: '7d' }
|
||||
);
|
||||
|
||||
// Store refresh token in database
|
||||
await db.refreshToken.create({
|
||||
data: {
|
||||
token: refreshToken,
|
||||
userId: user.id,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
|
||||
}
|
||||
});
|
||||
|
||||
res.json({
|
||||
token,
|
||||
refreshToken,
|
||||
expiresIn: 3600
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Login error:', error);
|
||||
res.status(500).json({
|
||||
error: 'An error occurred during login'
|
||||
});
|
||||
}
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
#### 2. Verify JWT Tokens (Middleware)
|
||||
|
||||
\`\`\`javascript
|
||||
// middleware/auth.js
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
function authenticateToken(req, res, next) {
|
||||
// Get token from header
|
||||
const authHeader = req.headers['authorization'];
|
||||
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({
|
||||
error: 'Access token required'
|
||||
});
|
||||
}
|
||||
|
||||
// Verify token
|
||||
jwt.verify(
|
||||
token,
|
||||
process.env.JWT_SECRET,
|
||||
{
|
||||
issuer: 'your-app',
|
||||
audience: 'your-app-users'
|
||||
},
|
||||
(err, user) => {
|
||||
if (err) {
|
||||
if (err.name === 'TokenExpiredError') {
|
||||
return res.status(401).json({
|
||||
error: 'Token expired'
|
||||
});
|
||||
}
|
||||
return res.status(403).json({
|
||||
error: 'Invalid token'
|
||||
});
|
||||
}
|
||||
|
||||
// Attach user to request
|
||||
req.user = user;
|
||||
next();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = { authenticateToken };
|
||||
\`\`\`
|
||||
|
||||
#### 3. Protect Routes
|
||||
|
||||
\`\`\`javascript
|
||||
const { authenticateToken } = require('./middleware/auth');
|
||||
|
||||
// Protected route
|
||||
app.get('/api/user/profile', authenticateToken, async (req, res) => {
|
||||
try {
|
||||
const user = await db.user.findUnique({
|
||||
where: { id: req.user.userId },
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
// Don't return passwordHash
|
||||
}
|
||||
});
|
||||
|
||||
res.json(user);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
}
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
#### 4. Implement Token Refresh
|
||||
|
||||
\`\`\`javascript
|
||||
app.post('/api/auth/refresh', async (req, res) => {
|
||||
const { refreshToken } = req.body;
|
||||
|
||||
if (!refreshToken) {
|
||||
return res.status(401).json({
|
||||
error: 'Refresh token required'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// Verify refresh token
|
||||
const decoded = jwt.verify(
|
||||
refreshToken,
|
||||
process.env.JWT_REFRESH_SECRET
|
||||
);
|
||||
|
||||
// Check if refresh token exists in database
|
||||
const storedToken = await db.refreshToken.findFirst({
|
||||
where: {
|
||||
token: refreshToken,
|
||||
userId: decoded.userId,
|
||||
expiresAt: { gt: new Date() }
|
||||
}
|
||||
});
|
||||
|
||||
if (!storedToken) {
|
||||
return res.status(403).json({
|
||||
error: 'Invalid refresh token'
|
||||
});
|
||||
}
|
||||
|
||||
// Generate new access token
|
||||
const user = await db.user.findUnique({
|
||||
where: { id: decoded.userId }
|
||||
});
|
||||
|
||||
const newToken = jwt.sign(
|
||||
{
|
||||
userId: user.id,
|
||||
email: user.email,
|
||||
role: user.role
|
||||
},
|
||||
process.env.JWT_SECRET,
|
||||
{ expiresIn: '1h' }
|
||||
);
|
||||
|
||||
res.json({
|
||||
token: newToken,
|
||||
expiresIn: 3600
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
res.status(403).json({
|
||||
error: 'Invalid refresh token'
|
||||
});
|
||||
}
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
### Security Best Practices
|
||||
|
||||
- ✅ Use strong JWT secrets (256-bit minimum)
|
||||
- ✅ Set short expiration times (1 hour for access tokens)
|
||||
- ✅ Implement refresh tokens for long-lived sessions
|
||||
- ✅ Store refresh tokens in database (can be revoked)
|
||||
- ✅ Use HTTPS only
|
||||
- ✅ Don't store sensitive data in JWT payload
|
||||
- ✅ Validate token issuer and audience
|
||||
- ✅ Implement token blacklisting for logout
|
||||
```
|
||||
|
||||
|
||||
### Example 2: Input Validation and SQL Injection Prevention
|
||||
|
||||
```markdown
|
||||
## Preventing SQL Injection and Input Validation
|
||||
|
||||
### The Problem
|
||||
|
||||
**❌ Vulnerable Code:**
|
||||
\`\`\`javascript
|
||||
// NEVER DO THIS - SQL Injection vulnerability
|
||||
app.get('/api/users/:id', async (req, res) => {
|
||||
const userId = req.params.id;
|
||||
|
||||
// Dangerous: User input directly in query
|
||||
const query = \`SELECT * FROM users WHERE id = '\${userId}'\`;
|
||||
const user = await db.query(query);
|
||||
|
||||
res.json(user);
|
||||
});
|
||||
|
||||
// Attack example:
|
||||
// GET /api/users/1' OR '1'='1
|
||||
// Returns all users!
|
||||
\`\`\`
|
||||
|
||||
### The Solution
|
||||
|
||||
#### 1. Use Parameterized Queries
|
||||
|
||||
\`\`\`javascript
|
||||
// ✅ Safe: Parameterized query
|
||||
app.get('/api/users/:id', async (req, res) => {
|
||||
const userId = req.params.id;
|
||||
|
||||
// Validate input first
|
||||
if (!userId || !/^\d+$/.test(userId)) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid user ID'
|
||||
});
|
||||
}
|
||||
|
||||
// Use parameterized query
|
||||
const user = await db.query(
|
||||
'SELECT id, email, name FROM users WHERE id = $1',
|
||||
[userId]
|
||||
);
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({
|
||||
error: 'User not found'
|
||||
});
|
||||
}
|
||||
|
||||
res.json(user);
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
#### 2. Use ORM with Proper Escaping
|
||||
|
||||
\`\`\`javascript
|
||||
// ✅ Safe: Using Prisma ORM
|
||||
app.get('/api/users/:id', async (req, res) => {
|
||||
const userId = parseInt(req.params.id);
|
||||
|
||||
if (isNaN(userId)) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid user ID'
|
||||
});
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
// Don't select sensitive fields
|
||||
}
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({
|
||||
error: 'User not found'
|
||||
});
|
||||
}
|
||||
|
||||
res.json(user);
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
#### 3. Implement Request Validation with Zod
|
||||
|
||||
\`\`\`javascript
|
||||
const { z } = require('zod');
|
||||
|
||||
// Define validation schema
|
||||
const createUserSchema = z.object({
|
||||
email: z.string().email('Invalid email format'),
|
||||
password: z.string()
|
||||
.min(8, 'Password must be at least 8 characters')
|
||||
.regex(/[A-Z]/, 'Password must contain uppercase letter')
|
||||
.regex(/[a-z]/, 'Password must contain lowercase letter')
|
||||
.regex(/[0-9]/, 'Password must contain number'),
|
||||
name: z.string()
|
||||
.min(2, 'Name must be at least 2 characters')
|
||||
.max(100, 'Name too long'),
|
||||
age: z.number()
|
||||
.int('Age must be an integer')
|
||||
.min(18, 'Must be 18 or older')
|
||||
.max(120, 'Invalid age')
|
||||
.optional()
|
||||
});
|
||||
|
||||
// Validation middleware
|
||||
function validateRequest(schema) {
|
||||
return (req, res, next) => {
|
||||
try {
|
||||
schema.parse(req.body);
|
||||
next();
|
||||
} catch (error) {
|
||||
res.status(400).json({
|
||||
error: 'Validation failed',
|
||||
details: error.errors
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Use validation
|
||||
app.post('/api/users',
|
||||
validateRequest(createUserSchema),
|
||||
async (req, res) => {
|
||||
// Input is validated at this point
|
||||
const { email, password, name, age } = req.body;
|
||||
|
||||
// Hash password
|
||||
const passwordHash = await bcrypt.hash(password, 10);
|
||||
|
||||
// Create user
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email,
|
||||
passwordHash,
|
||||
name,
|
||||
age
|
||||
}
|
||||
});
|
||||
|
||||
// Don't return password hash
|
||||
const { passwordHash: _, ...userWithoutPassword } = user;
|
||||
res.status(201).json(userWithoutPassword);
|
||||
}
|
||||
);
|
||||
\`\`\`
|
||||
|
||||
#### 4. Sanitize Output to Prevent XSS
|
||||
|
||||
\`\`\`javascript
|
||||
const DOMPurify = require('isomorphic-dompurify');
|
||||
|
||||
app.post('/api/comments', authenticateToken, async (req, res) => {
|
||||
const { content } = req.body;
|
||||
|
||||
// Validate
|
||||
if (!content || content.length > 1000) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid comment content'
|
||||
});
|
||||
}
|
||||
|
||||
// Sanitize HTML to prevent XSS
|
||||
const sanitizedContent = DOMPurify.sanitize(content, {
|
||||
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
|
||||
ALLOWED_ATTR: ['href']
|
||||
});
|
||||
|
||||
const comment = await prisma.comment.create({
|
||||
data: {
|
||||
content: sanitizedContent,
|
||||
userId: req.user.userId
|
||||
}
|
||||
});
|
||||
|
||||
res.status(201).json(comment);
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
### Validation Checklist
|
||||
|
||||
- [ ] Validate all user inputs
|
||||
- [ ] Use parameterized queries or ORM
|
||||
- [ ] Validate data types (string, number, email, etc.)
|
||||
- [ ] Validate data ranges (min/max length, value ranges)
|
||||
- [ ] Sanitize HTML content
|
||||
- [ ] Escape special characters
|
||||
- [ ] Validate file uploads (type, size, content)
|
||||
- [ ] Use allowlists, not blocklists
|
||||
```
|
||||
|
||||
|
||||
### Example 3: Rate Limiting and DDoS Protection
|
||||
|
||||
```markdown
|
||||
## Implementing Rate Limiting
|
||||
|
||||
### Why Rate Limiting?
|
||||
|
||||
- Prevent brute force attacks
|
||||
- Protect against DDoS
|
||||
- Prevent API abuse
|
||||
- Ensure fair usage
|
||||
- Reduce server costs
|
||||
|
||||
### Implementation with Express Rate Limit
|
||||
|
||||
\`\`\`javascript
|
||||
const rateLimit = require('express-rate-limit');
|
||||
const RedisStore = require('rate-limit-redis');
|
||||
const Redis = require('ioredis');
|
||||
|
||||
// Create Redis client
|
||||
const redis = new Redis({
|
||||
host: process.env.REDIS_HOST,
|
||||
port: process.env.REDIS_PORT
|
||||
});
|
||||
|
||||
// General API rate limit
|
||||
const apiLimiter = rateLimit({
|
||||
store: new RedisStore({
|
||||
client: redis,
|
||||
prefix: 'rl:api:'
|
||||
}),
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // 100 requests per window
|
||||
message: {
|
||||
error: 'Too many requests, please try again later',
|
||||
retryAfter: 900 // seconds
|
||||
},
|
||||
standardHeaders: true, // Return rate limit info in headers
|
||||
legacyHeaders: false,
|
||||
// Custom key generator (by user ID or IP)
|
||||
keyGenerator: (req) => {
|
||||
return req.user?.userId || req.ip;
|
||||
}
|
||||
});
|
||||
|
||||
// Strict rate limit for authentication endpoints
|
||||
const authLimiter = rateLimit({
|
||||
store: new RedisStore({
|
||||
client: redis,
|
||||
prefix: 'rl:auth:'
|
||||
}),
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 5, // Only 5 login attempts per 15 minutes
|
||||
skipSuccessfulRequests: true, // Don't count successful logins
|
||||
message: {
|
||||
error: 'Too many login attempts, please try again later',
|
||||
retryAfter: 900
|
||||
}
|
||||
});
|
||||
|
||||
// Apply rate limiters
|
||||
app.use('/api/', apiLimiter);
|
||||
app.use('/api/auth/login', authLimiter);
|
||||
app.use('/api/auth/register', authLimiter);
|
||||
|
||||
// Custom rate limiter for expensive operations
|
||||
const expensiveLimiter = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 1 hour
|
||||
max: 10, // 10 requests per hour
|
||||
message: {
|
||||
error: 'Rate limit exceeded for this operation'
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/reports/generate',
|
||||
authenticateToken,
|
||||
expensiveLimiter,
|
||||
async (req, res) => {
|
||||
// Expensive operation
|
||||
}
|
||||
);
|
||||
\`\`\`
|
||||
|
||||
### Advanced: Per-User Rate Limiting
|
||||
|
||||
\`\`\`javascript
|
||||
// Different limits based on user tier
|
||||
function createTieredRateLimiter() {
|
||||
const limits = {
|
||||
free: { windowMs: 60 * 60 * 1000, max: 100 },
|
||||
pro: { windowMs: 60 * 60 * 1000, max: 1000 },
|
||||
enterprise: { windowMs: 60 * 60 * 1000, max: 10000 }
|
||||
};
|
||||
|
||||
return async (req, res, next) => {
|
||||
const user = req.user;
|
||||
const tier = user?.tier || 'free';
|
||||
const limit = limits[tier];
|
||||
|
||||
const key = \`rl:user:\${user.userId}\`;
|
||||
const current = await redis.incr(key);
|
||||
|
||||
if (current === 1) {
|
||||
await redis.expire(key, limit.windowMs / 1000);
|
||||
}
|
||||
|
||||
if (current > limit.max) {
|
||||
return res.status(429).json({
|
||||
error: 'Rate limit exceeded',
|
||||
limit: limit.max,
|
||||
remaining: 0,
|
||||
reset: await redis.ttl(key)
|
||||
});
|
||||
}
|
||||
|
||||
// Set rate limit headers
|
||||
res.set({
|
||||
'X-RateLimit-Limit': limit.max,
|
||||
'X-RateLimit-Remaining': limit.max - current,
|
||||
'X-RateLimit-Reset': await redis.ttl(key)
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
app.use('/api/', authenticateToken, createTieredRateLimiter());
|
||||
\`\`\`
|
||||
|
||||
### DDoS Protection with Helmet
|
||||
|
||||
\`\`\`javascript
|
||||
const helmet = require('helmet');
|
||||
|
||||
app.use(helmet({
|
||||
// Content Security Policy
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
styleSrc: ["'self'", "'unsafe-inline'"],
|
||||
scriptSrc: ["'self'"],
|
||||
imgSrc: ["'self'", 'data:', 'https:']
|
||||
}
|
||||
},
|
||||
// Prevent clickjacking
|
||||
frameguard: { action: 'deny' },
|
||||
// Hide X-Powered-By header
|
||||
hidePoweredBy: true,
|
||||
// Prevent MIME type sniffing
|
||||
noSniff: true,
|
||||
// Enable HSTS
|
||||
hsts: {
|
||||
maxAge: 31536000,
|
||||
includeSubDomains: true,
|
||||
preload: true
|
||||
}
|
||||
}));
|
||||
\`\`\`
|
||||
|
||||
### Rate Limit Response Headers
|
||||
|
||||
\`\`\`
|
||||
X-RateLimit-Limit: 100
|
||||
X-RateLimit-Remaining: 87
|
||||
X-RateLimit-Reset: 1640000000
|
||||
Retry-After: 900
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ Do This
|
||||
|
||||
- **Use HTTPS Everywhere** - Never send sensitive data over HTTP
|
||||
- **Implement Authentication** - Require authentication for protected endpoints
|
||||
- **Validate All Inputs** - Never trust user input
|
||||
- **Use Parameterized Queries** - Prevent SQL injection
|
||||
- **Implement Rate Limiting** - Protect against brute force and DDoS
|
||||
- **Hash Passwords** - Use bcrypt with salt rounds >= 10
|
||||
- **Use Short-Lived Tokens** - JWT access tokens should expire quickly
|
||||
- **Implement CORS Properly** - Only allow trusted origins
|
||||
- **Log Security Events** - Monitor for suspicious activity
|
||||
- **Keep Dependencies Updated** - Regularly update packages
|
||||
- **Use Security Headers** - Implement Helmet.js
|
||||
- **Sanitize Error Messages** - Don't leak sensitive information
|
||||
|
||||
### ❌ Don't Do This
|
||||
|
||||
- **Don't Store Passwords in Plain Text** - Always hash passwords
|
||||
- **Don't Use Weak Secrets** - Use strong, random JWT secrets
|
||||
- **Don't Trust User Input** - Always validate and sanitize
|
||||
- **Don't Expose Stack Traces** - Hide error details in production
|
||||
- **Don't Use String Concatenation for SQL** - Use parameterized queries
|
||||
- **Don't Store Sensitive Data in JWT** - JWTs are not encrypted
|
||||
- **Don't Ignore Security Updates** - Update dependencies regularly
|
||||
- **Don't Use Default Credentials** - Change all default passwords
|
||||
- **Don't Disable CORS Completely** - Configure it properly instead
|
||||
- **Don't Log Sensitive Data** - Sanitize logs
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Problem: JWT Secret Exposed in Code
|
||||
**Symptoms:** JWT secret hardcoded or committed to Git
|
||||
**Solution:**
|
||||
\`\`\`javascript
|
||||
// ❌ Bad
|
||||
const JWT_SECRET = 'my-secret-key';
|
||||
|
||||
// ✅ Good
|
||||
const JWT_SECRET = process.env.JWT_SECRET;
|
||||
if (!JWT_SECRET) {
|
||||
throw new Error('JWT_SECRET environment variable is required');
|
||||
}
|
||||
|
||||
// Generate strong secret
|
||||
// node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
|
||||
\`\`\`
|
||||
|
||||
### Problem: Weak Password Requirements
|
||||
**Symptoms:** Users can set weak passwords like "password123"
|
||||
**Solution:**
|
||||
\`\`\`javascript
|
||||
const passwordSchema = z.string()
|
||||
.min(12, 'Password must be at least 12 characters')
|
||||
.regex(/[A-Z]/, 'Must contain uppercase letter')
|
||||
.regex(/[a-z]/, 'Must contain lowercase letter')
|
||||
.regex(/[0-9]/, 'Must contain number')
|
||||
.regex(/[^A-Za-z0-9]/, 'Must contain special character');
|
||||
|
||||
// Or use a password strength library
|
||||
const zxcvbn = require('zxcvbn');
|
||||
const result = zxcvbn(password);
|
||||
if (result.score < 3) {
|
||||
return res.status(400).json({
|
||||
error: 'Password too weak',
|
||||
suggestions: result.feedback.suggestions
|
||||
});
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
### Problem: Missing Authorization Checks
|
||||
**Symptoms:** Users can access resources they shouldn't
|
||||
**Solution:**
|
||||
\`\`\`javascript
|
||||
// ❌ Bad: Only checks authentication
|
||||
app.delete('/api/posts/:id', authenticateToken, async (req, res) => {
|
||||
await prisma.post.delete({ where: { id: req.params.id } });
|
||||
res.json({ success: true });
|
||||
});
|
||||
|
||||
// ✅ Good: Checks both authentication and authorization
|
||||
app.delete('/api/posts/:id', authenticateToken, async (req, res) => {
|
||||
const post = await prisma.post.findUnique({
|
||||
where: { id: req.params.id }
|
||||
});
|
||||
|
||||
if (!post) {
|
||||
return res.status(404).json({ error: 'Post not found' });
|
||||
}
|
||||
|
||||
// Check if user owns the post or is admin
|
||||
if (post.userId !== req.user.userId && req.user.role !== 'admin') {
|
||||
return res.status(403).json({
|
||||
error: 'Not authorized to delete this post'
|
||||
});
|
||||
}
|
||||
|
||||
await prisma.post.delete({ where: { id: req.params.id } });
|
||||
res.json({ success: true });
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
### Problem: Verbose Error Messages
|
||||
**Symptoms:** Error messages reveal system details
|
||||
**Solution:**
|
||||
\`\`\`javascript
|
||||
// ❌ Bad: Exposes database details
|
||||
app.post('/api/users', async (req, res) => {
|
||||
try {
|
||||
const user = await prisma.user.create({ data: req.body });
|
||||
res.json(user);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
// Error: "Unique constraint failed on the fields: (`email`)"
|
||||
}
|
||||
});
|
||||
|
||||
// ✅ Good: Generic error message
|
||||
app.post('/api/users', async (req, res) => {
|
||||
try {
|
||||
const user = await prisma.user.create({ data: req.body });
|
||||
res.json(user);
|
||||
} catch (error) {
|
||||
console.error('User creation error:', error); // Log full error
|
||||
|
||||
if (error.code === 'P2002') {
|
||||
return res.status(400).json({
|
||||
error: 'Email already exists'
|
||||
});
|
||||
}
|
||||
|
||||
res.status(500).json({
|
||||
error: 'An error occurred while creating user'
|
||||
});
|
||||
}
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
## Security Checklist
|
||||
|
||||
### Authentication & Authorization
|
||||
- [ ] Implement strong authentication (JWT, OAuth 2.0)
|
||||
- [ ] Use HTTPS for all endpoints
|
||||
- [ ] Hash passwords with bcrypt (salt rounds >= 10)
|
||||
- [ ] Implement token expiration
|
||||
- [ ] Add refresh token mechanism
|
||||
- [ ] Verify user authorization for each request
|
||||
- [ ] Implement role-based access control (RBAC)
|
||||
|
||||
### Input Validation
|
||||
- [ ] Validate all user inputs
|
||||
- [ ] Use parameterized queries or ORM
|
||||
- [ ] Sanitize HTML content
|
||||
- [ ] Validate file uploads
|
||||
- [ ] Implement request schema validation
|
||||
- [ ] Use allowlists, not blocklists
|
||||
|
||||
### Rate Limiting & DDoS Protection
|
||||
- [ ] Implement rate limiting per user/IP
|
||||
- [ ] Add stricter limits for auth endpoints
|
||||
- [ ] Use Redis for distributed rate limiting
|
||||
- [ ] Return proper rate limit headers
|
||||
- [ ] Implement request throttling
|
||||
|
||||
### Data Protection
|
||||
- [ ] Use HTTPS/TLS for all traffic
|
||||
- [ ] Encrypt sensitive data at rest
|
||||
- [ ] Don't store sensitive data in JWT
|
||||
- [ ] Sanitize error messages
|
||||
- [ ] Implement proper CORS configuration
|
||||
- [ ] Use security headers (Helmet.js)
|
||||
|
||||
### Monitoring & Logging
|
||||
- [ ] Log security events
|
||||
- [ ] Monitor for suspicious activity
|
||||
- [ ] Set up alerts for failed auth attempts
|
||||
- [ ] Track API usage patterns
|
||||
- [ ] Don't log sensitive data
|
||||
|
||||
## OWASP API Security Top 10
|
||||
|
||||
1. **Broken Object Level Authorization** - Always verify user can access resource
|
||||
2. **Broken Authentication** - Implement strong authentication mechanisms
|
||||
3. **Broken Object Property Level Authorization** - Validate which properties user can access
|
||||
4. **Unrestricted Resource Consumption** - Implement rate limiting and quotas
|
||||
5. **Broken Function Level Authorization** - Verify user role for each function
|
||||
6. **Unrestricted Access to Sensitive Business Flows** - Protect critical workflows
|
||||
7. **Server Side Request Forgery (SSRF)** - Validate and sanitize URLs
|
||||
8. **Security Misconfiguration** - Use security best practices and headers
|
||||
9. **Improper Inventory Management** - Document and secure all API endpoints
|
||||
10. **Unsafe Consumption of APIs** - Validate data from third-party APIs
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `@ethical-hacking-methodology` - Security testing perspective
|
||||
- `@sql-injection-testing` - Testing for SQL injection
|
||||
- `@xss-html-injection` - Testing for XSS vulnerabilities
|
||||
- `@broken-authentication` - Authentication vulnerabilities
|
||||
- `@backend-dev-guidelines` - Backend development standards
|
||||
- `@systematic-debugging` - Debug security issues
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
|
||||
- [JWT Best Practices](https://tools.ietf.org/html/rfc8725)
|
||||
- [Express Security Best Practices](https://expressjs.com/en/advanced/best-practice-security.html)
|
||||
- [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/)
|
||||
- [API Security Checklist](https://github.com/shieldfy/API-Security-Checklist)
|
||||
|
||||
---
|
||||
|
||||
**Pro Tip:** Security is not a one-time task - regularly audit your APIs, keep dependencies updated, and stay informed about new vulnerabilities!
|
||||
59
skills/avalonia-layout-zafiro/SKILL.md
Normal file
59
skills/avalonia-layout-zafiro/SKILL.md
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
name: avalonia-layout-zafiro
|
||||
description: Guidelines for modern Avalonia UI layout using Zafiro.Avalonia, emphasizing shared styles, generic components, and avoiding XAML redundancy.
|
||||
allowed-tools: Read, Write, Edit, Glob, Grep
|
||||
---
|
||||
|
||||
# Avalonia Layout with Zafiro.Avalonia
|
||||
|
||||
> Master modern, clean, and maintainable Avalonia UI layouts.
|
||||
> **Focus on semantic containers, shared styles, and minimal XAML.**
|
||||
|
||||
## 🎯 Selective Reading Rule
|
||||
|
||||
**Read ONLY files relevant to the layout challenge!**
|
||||
|
||||
---
|
||||
|
||||
## 📑 Content Map
|
||||
|
||||
| File | Description | When to Read |
|
||||
|------|-------------|--------------|
|
||||
| `themes.md` | Theme organization and shared styles | Setting up or refining app themes |
|
||||
| `containers.md` | Semantic containers (`HeaderedContainer`, `EdgePanel`, `Card`) | Structuring views and layouts |
|
||||
| `icons.md` | Icon usage with `IconExtension` and `IconOptions` | Adding and customizing icons |
|
||||
| `behaviors.md` | `Xaml.Interaction.Behaviors` and avoiding Converters | Implementing complex interactions |
|
||||
| `components.md` | Generic components and avoiding nesting | Creating reusable UI elements |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Related Project (Exemplary Implementation)
|
||||
|
||||
For a real-world example, refer to the **Angor** project:
|
||||
`/mnt/fast/Repos/angor/src/Angor/Avalonia/Angor.Avalonia.sln`
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist for Clean Layouts
|
||||
|
||||
- [ ] **Used semantic containers?** (e.g., `HeaderedContainer` instead of `Border` with manual header)
|
||||
- [ ] **Avoided redundant properties?** Use shared styles in `axaml` files.
|
||||
- [ ] **Minimized nesting?** Flatten layouts using `EdgePanel` or generic components.
|
||||
- [ ] **Icons via extension?** Use `{Icon fa-name}` and `IconOptions` for styling.
|
||||
- [ ] **Behaviors over code-behind?** Use `Interaction.Behaviors` for UI-logic.
|
||||
- [ ] **Avoided Converters?** Prefer ViewModel properties or Behaviors unless necessary.
|
||||
|
||||
---
|
||||
|
||||
## ❌ Anti-Patterns
|
||||
|
||||
**DON'T:**
|
||||
- Use hardcoded colors or sizes (literals) in views.
|
||||
- Create deep nesting of `Grid` and `StackPanel`.
|
||||
- Repeat visual properties across multiple elements (use Styles).
|
||||
- Use `IValueConverter` for simple logic that belongs in the ViewModel.
|
||||
|
||||
**DO:**
|
||||
- Use `DynamicResource` for colors and brushes.
|
||||
- Extract repeated layouts into generic components.
|
||||
- Leverage `Zafiro.Avalonia` specific panels like `EdgePanel` for common UI patterns.
|
||||
35
skills/avalonia-layout-zafiro/behaviors.md
Normal file
35
skills/avalonia-layout-zafiro/behaviors.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Interactions and Logic
|
||||
|
||||
To keep XAML clean and maintainable, minimize logic in views and avoid excessive use of converters.
|
||||
|
||||
## 🎭 Xaml.Interaction.Behaviors
|
||||
|
||||
Use `Interaction.Behaviors` to handle UI-related logic that doesn't belong in the ViewModel, such as focus management, animations, or specialized event handling.
|
||||
|
||||
```xml
|
||||
<TextBox Text="{Binding Address}">
|
||||
<Interaction.Behaviors>
|
||||
<UntouchedClassBehavior />
|
||||
</Interaction.Behaviors>
|
||||
</TextBox>
|
||||
```
|
||||
|
||||
### Why use Behaviors?
|
||||
- **Encapsulation**: UI logic is contained in a reusable behavior class.
|
||||
- **Clean XAML**: Avoids code-behind and complex XAML triggers.
|
||||
- **Testability**: Behaviors can be tested independently of the View.
|
||||
|
||||
## 🚫 Avoiding Converters
|
||||
|
||||
Converters often lead to "magical" logic hidden in XAML. Whenever possible, prefer:
|
||||
|
||||
1. **ViewModel Properties**: Let the ViewModel provide the final data format (e.g., a `string` formatted for display).
|
||||
2. **MultiBinding**: Use for simple logic combinations (And/Or) directly in XAML.
|
||||
3. **Behaviors**: For more complex interactions that involve state or events.
|
||||
|
||||
### When to use Converters?
|
||||
Only use them when the conversion is purely visual and highly reusable across different contexts (e.g., `BoolToOpacityConverter`).
|
||||
|
||||
## 🧩 Simplified Interactions
|
||||
|
||||
If you find yourself needing a complex converter or behavior, consider if the component can be simplified or if the data model can be adjusted to make the view binding more direct.
|
||||
41
skills/avalonia-layout-zafiro/components.md
Normal file
41
skills/avalonia-layout-zafiro/components.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Building Generic Components
|
||||
|
||||
Reducing nesting and complexity is achieved by breaking down views into generic, reusable components.
|
||||
|
||||
## 🧊 Generic Components
|
||||
|
||||
Instead of building large, complex views, extract recurring patterns into small `UserControl`s.
|
||||
|
||||
### Example: A generic "Summary Item"
|
||||
Instead of repeating a `Grid` with labels and values:
|
||||
|
||||
```xml
|
||||
<!-- ❌ BAD: Repeated Grid -->
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<TextBlock Text="Total:" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding Total}" />
|
||||
</Grid>
|
||||
```
|
||||
|
||||
Create a generic component (or use `EdgePanel` with a Style):
|
||||
|
||||
```xml
|
||||
<!-- ✅ GOOD: Use a specialized control or style -->
|
||||
<EdgePanel StartContent="Total:" EndContent="{Binding Total}" Classes="SummaryItem" />
|
||||
```
|
||||
|
||||
## 📉 Flattening Layouts
|
||||
|
||||
Avoid deep nesting. Deeply nested XAML is hard to read and can impact performance.
|
||||
|
||||
- **StackPanel vs Grid**: Use `StackPanel` (with `Spacing`) for simple linear layouts.
|
||||
- **EdgePanel**: Great for "Label - Value" or "Icon - Text - Action" rows.
|
||||
- **UniformGrid**: Use for grids where all cells are the same size.
|
||||
|
||||
## 🔧 Component Granularity
|
||||
|
||||
- **Atomical**: Small controls like custom buttons or icons.
|
||||
- **Molecular**: Groups of atoms like a `HeaderedContainer` with specific content.
|
||||
- **Organisms**: Higher-level sections of a page.
|
||||
|
||||
Aim for components that are generic enough to be reused but specific enough to simplify the parent view significantly.
|
||||
50
skills/avalonia-layout-zafiro/containers.md
Normal file
50
skills/avalonia-layout-zafiro/containers.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Semantic Containers
|
||||
|
||||
Using the right container for the data type simplifies XAML and improves maintainability. `Zafiro.Avalonia` provides specialized controls for common layout patterns.
|
||||
|
||||
## 📦 HeaderedContainer
|
||||
|
||||
Prefer `HeaderedContainer` over a `Border` or `Grid` when a section needs a title or header.
|
||||
|
||||
```xml
|
||||
<HeaderedContainer Header="Security Settings" Classes="WizardSection">
|
||||
<StackPanel>
|
||||
<!-- Content here -->
|
||||
</StackPanel>
|
||||
</HeaderedContainer>
|
||||
```
|
||||
|
||||
### Key Properties:
|
||||
- `Header`: The content or string for the header.
|
||||
- `HeaderBackground`: Brush for the header area.
|
||||
- `ContentPadding`: Padding for the content area.
|
||||
|
||||
## ↔️ EdgePanel
|
||||
|
||||
Use `EdgePanel` to position elements at the edges of a container without complex `Grid` definitions.
|
||||
|
||||
```xml
|
||||
<EdgePanel StartContent="{Icon fa-wallet}"
|
||||
Content="Wallet Balance"
|
||||
EndContent="$1,234.00" />
|
||||
```
|
||||
|
||||
### Slots:
|
||||
- `StartContent`: Aligned to the left (or beginning).
|
||||
- `Content`: Fills the remaining space in the middle.
|
||||
- `EndContent`: Aligned to the right (or end).
|
||||
|
||||
## 📇 Card
|
||||
|
||||
A simple container for grouping related information, often used inside `HeaderedContainer` or as a standalone element in a list.
|
||||
|
||||
```xml
|
||||
<Card Header="Enter recipient address:">
|
||||
<TextBox Text="{Binding Address}" />
|
||||
</Card>
|
||||
```
|
||||
|
||||
## 📐 Best Practices
|
||||
|
||||
- Use `Classes` to apply themed variants (e.g., `Classes="Section"`, `Classes="Highlight"`).
|
||||
- Customize internal parts of the containers using templates in your styles when necessary, rather than nesting more controls.
|
||||
53
skills/avalonia-layout-zafiro/icons.md
Normal file
53
skills/avalonia-layout-zafiro/icons.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Icon Usage
|
||||
|
||||
`Zafiro.Avalonia` simplifies icon management using a specialized markup extension and styling options.
|
||||
|
||||
## 🛠️ IconExtension
|
||||
|
||||
Use the `{Icon}` markup extension to easily include icons from libraries like FontAwesome.
|
||||
|
||||
```xml
|
||||
<!-- Positional parameter -->
|
||||
<Button Content="{Icon fa-wallet}" />
|
||||
|
||||
<!-- Named parameter -->
|
||||
<ContentControl Content="{Icon Source=fa-gear}" />
|
||||
```
|
||||
|
||||
## 🎨 IconOptions
|
||||
|
||||
`IconOptions` allows you to customize icons without manually wrapping them in other controls. It's often used in styles to provide a consistent look.
|
||||
|
||||
```xml
|
||||
<Style Selector="HeaderedContainer /template/ ContentPresenter#Header EdgePanel /template/ ContentControl#StartContent">
|
||||
<Setter Property="IconOptions.Size" Value="20" />
|
||||
<Setter Property="IconOptions.Fill" Value="{DynamicResource Accent}" />
|
||||
<Setter Property="IconOptions.Padding" Value="10" />
|
||||
<Setter Property="IconOptions.CornerRadius" Value="10" />
|
||||
</Style>
|
||||
```
|
||||
|
||||
### Common Properties:
|
||||
- `IconOptions.Size`: Sets the width and height of the icon.
|
||||
- `IconOptions.Fill`: The color/brush of the icon.
|
||||
- `IconOptions.Background`: Background brush for the icon container.
|
||||
- `IconOptions.Padding`: Padding inside the icon container.
|
||||
- `IconOptions.CornerRadius`: Corner radius if a background is used.
|
||||
|
||||
## 📁 Shared Icon Resources
|
||||
|
||||
Define icons as resources for reuse across the application.
|
||||
|
||||
```xml
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui">
|
||||
<Icon x:Key="fa-wallet" Source="fa-wallet" />
|
||||
</ResourceDictionary>
|
||||
```
|
||||
|
||||
Then use them with `StaticResource` if they are already defined:
|
||||
|
||||
```xml
|
||||
<Button Content="{StaticResource fa-wallet}" />
|
||||
```
|
||||
|
||||
However, the `{Icon ...}` extension is usually preferred for its brevity and ability to create new icon instances on the fly.
|
||||
51
skills/avalonia-layout-zafiro/themes.md
Normal file
51
skills/avalonia-layout-zafiro/themes.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Theme Organization and Shared Styles
|
||||
|
||||
Efficient theme organization is key to avoiding redundant XAML and ensuring visual consistency.
|
||||
|
||||
## 🏗️ Structure
|
||||
|
||||
Follow the pattern from Angor:
|
||||
|
||||
1. **Colors & Brushes**: Define in a dedicated `Colors.axaml`. Use `DynamicResource` to support theme switching.
|
||||
2. **Styles**: Group styles by category (e.g., `Buttons.axaml`, `Containers.axaml`, `Typography.axaml`).
|
||||
3. **App-wide Theme**: Aggregate all styles in a main `Theme.axaml`.
|
||||
|
||||
## 🎨 Avoiding Redundancy
|
||||
|
||||
Instead of setting properties directly on elements:
|
||||
|
||||
```xml
|
||||
<!-- ❌ BAD: Redundant properties -->
|
||||
<HeaderedContainer CornerRadius="10" BorderThickness="1" BorderBrush="Blue" Background="LightBlue" />
|
||||
<HeaderedContainer CornerRadius="10" BorderThickness="1" BorderBrush="Blue" Background="LightBlue" />
|
||||
|
||||
<!-- ✅ GOOD: Use Classes and Styles -->
|
||||
<HeaderedContainer Classes="BlueSection" />
|
||||
<HeaderedContainer Classes="BlueSection" />
|
||||
```
|
||||
|
||||
Define the style in a shared `axaml` file:
|
||||
|
||||
```xml
|
||||
<Style Selector="HeaderedContainer.BlueSection">
|
||||
<Setter Property="CornerRadius" Value="10" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource Accent}" />
|
||||
<Setter Property="Background" Value="{DynamicResource SurfaceSubtle}" />
|
||||
</Style>
|
||||
```
|
||||
|
||||
## 🧩 Shared Icons and Resources
|
||||
|
||||
Centralize icon definitions and other shared resources in `Icons.axaml` and include them in the `MergedDictionaries` of your theme or `App.axaml`.
|
||||
|
||||
```xml
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<MergeResourceInclude Source="UI/Themes/Styles/Containers.axaml" />
|
||||
<MergeResourceInclude Source="UI/Shared/Resources/Icons.axaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
```
|
||||
29
skills/avalonia-viewmodels-zafiro/SKILL.md
Normal file
29
skills/avalonia-viewmodels-zafiro/SKILL.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: avalonia-viewmodels-zafiro
|
||||
description: Optimal ViewModel and Wizard creation patterns for Avalonia using Zafiro and ReactiveUI.
|
||||
---
|
||||
|
||||
# Avalonia ViewModels with Zafiro
|
||||
|
||||
This skill provides a set of best practices and patterns for creating ViewModels, Wizards, and managing navigation in Avalonia applications, leveraging the power of **ReactiveUI** and the **Zafiro** toolkit.
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Functional-Reactive Approach**: Use ReactiveUI (`ReactiveObject`, `WhenAnyValue`, etc.) to handle state and logic.
|
||||
2. **Enhanced Commands**: Utilize `IEnhancedCommand` for better command management, including progress reporting and name/text attributes.
|
||||
3. **Wizard Pattern**: Implement complex flows using `SlimWizard` and `WizardBuilder` for a declarative and maintainable approach.
|
||||
4. **Automatic Section Discovery**: Use the `[Section]` attribute to register and discover UI sections automatically.
|
||||
5. **Clean Composition**: map ViewModels to Views using `DataTypeViewLocator` and manage dependencies in the `CompositionRoot`.
|
||||
|
||||
## Guides
|
||||
|
||||
- [ViewModels & Commands](viewmodels.md): Creating robust ViewModels and handling commands.
|
||||
- [Wizards & Flows](wizards.md): Building multi-step wizards with `SlimWizard`.
|
||||
- [Navigation & Sections](navigation_sections.md): Managing navigation and section-based UIs.
|
||||
- [Composition & Mapping](composition.md): Best practices for View-ViewModel wiring and DI.
|
||||
|
||||
## Example Reference
|
||||
|
||||
For real-world implementations, refer to the **Angor** project:
|
||||
- `CreateProjectFlowV2.cs`: Excellent example of complex Wizard building.
|
||||
- `HomeViewModel.cs`: Simple section ViewModel using functional-reactive commands.
|
||||
75
skills/avalonia-viewmodels-zafiro/composition.md
Normal file
75
skills/avalonia-viewmodels-zafiro/composition.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Composition & Mapping
|
||||
|
||||
Ensuring your ViewModels are correctly instantiated and mapped to their corresponding Views is crucial for a maintainable application.
|
||||
|
||||
## ViewModel-to-View Mapping
|
||||
|
||||
Zafiro uses the `DataTypeViewLocator` to automatically map ViewModels to Views based on their data type.
|
||||
|
||||
### Integration in App.axaml
|
||||
|
||||
Register the `DataTypeViewLocator` in your application's data templates:
|
||||
|
||||
```xml
|
||||
<Application.DataTemplates>
|
||||
<DataTypeViewLocator />
|
||||
<DataTemplateInclude Source="avares://Zafiro.Avalonia/DataTemplates.axaml" />
|
||||
</Application.DataTemplates>
|
||||
```
|
||||
|
||||
### Registration
|
||||
|
||||
Mappings can be registered globally or locally. Common practice in Zafiro projects is to use naming conventions or explicit registrations made by source generators.
|
||||
|
||||
## Composition Root
|
||||
|
||||
Use a central `CompositionRoot` to manage dependency injection and service registration.
|
||||
|
||||
```csharp
|
||||
public static class CompositionRoot
|
||||
{
|
||||
public static IShellViewModel CreateMainViewModel(Control topLevelView)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services
|
||||
.AddViewModels()
|
||||
.AddUIServices(topLevelView);
|
||||
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
return serviceProvider.GetRequiredService<IShellViewModel>();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Registering ViewModels
|
||||
|
||||
Register ViewModels with appropriate scopes (Transient, Scoped, or Singleton).
|
||||
|
||||
```csharp
|
||||
public static IServiceCollection AddViewModels(this IServiceCollection services)
|
||||
{
|
||||
return services
|
||||
.AddTransient<IHomeSectionViewModel, HomeSectionSectionViewModel>()
|
||||
.AddSingleton<IShellViewModel, ShellViewModel>();
|
||||
}
|
||||
```
|
||||
|
||||
## View Injection
|
||||
|
||||
Use the `Connect` helper (if available) or manual instantiation in `OnFrameworkInitializationCompleted`:
|
||||
|
||||
```csharp
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
this.Connect(
|
||||
() => new ShellView(),
|
||||
view => CompositionRoot.CreateMainViewModel(view),
|
||||
() => new MainWindow());
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Use `ActivatorUtilities.CreateInstance` when you need to manually instantiate a class while still resolving its dependencies from the `IServiceProvider`.
|
||||
53
skills/avalonia-viewmodels-zafiro/navigation_sections.md
Normal file
53
skills/avalonia-viewmodels-zafiro/navigation_sections.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Navigation & Sections
|
||||
|
||||
Zafiro provides powerful abstractions for managing application-wide navigation and modular UI sections.
|
||||
|
||||
## Navigation with INavigator
|
||||
|
||||
The `INavigator` interface is used to switch between different views or viewmodels.
|
||||
|
||||
```csharp
|
||||
public class MyViewModel(INavigator navigator)
|
||||
{
|
||||
public async Task GoToDetails()
|
||||
{
|
||||
await navigator.Navigate(() => new DetailsViewModel());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## UI Sections
|
||||
|
||||
Sections are modular parts of the UI (like tabs or sidebar items) that can be automatically registered.
|
||||
|
||||
### The [Section] Attribute
|
||||
|
||||
ViewModels intended to be sections should be marked with the `[Section]` attribute.
|
||||
|
||||
```csharp
|
||||
[Section("Wallet", icon: "fa-wallet")]
|
||||
public class WalletSectionViewModel : IWalletSectionViewModel
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Automatic Registration
|
||||
|
||||
In the `CompositionRoot`, sections can be automatically registered:
|
||||
|
||||
```csharp
|
||||
services.AddAnnotatedSections(logger);
|
||||
services.AddSectionsFromAttributes(logger);
|
||||
```
|
||||
|
||||
### Switching Sections
|
||||
|
||||
You can switch the current active section via the `IShellViewModel`:
|
||||
|
||||
```csharp
|
||||
shellViewModel.SetSection("Browse");
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The `icon` parameter in the `[Section]` attribute supports FontAwesome icons (e.g., `fa-home`) when configured with `ProjektankerIconControlProvider`.
|
||||
68
skills/avalonia-viewmodels-zafiro/viewmodels.md
Normal file
68
skills/avalonia-viewmodels-zafiro/viewmodels.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# ViewModels & Commands
|
||||
|
||||
In a Zafiro-based application, ViewModels should be functional, reactive, and resilient.
|
||||
|
||||
## Reactive ViewModels
|
||||
|
||||
Use `ReactiveObject` as the base class. Properties should be defined using the `[Reactive]` attribute (from ReactiveUI.SourceGenerators) for brevity.
|
||||
|
||||
```csharp
|
||||
public partial class MyViewModel : ReactiveObject
|
||||
{
|
||||
[Reactive] private string name;
|
||||
[Reactive] private bool isBusy;
|
||||
}
|
||||
```
|
||||
|
||||
### Observation and Transformation
|
||||
|
||||
Use `WhenAnyValue` to react to property changes:
|
||||
|
||||
```csharp
|
||||
this.WhenAnyValue(x => x.Name)
|
||||
.Select(name => !string.IsNullOrEmpty(name))
|
||||
.ToPropertyEx(this, x => x.CanSubmit);
|
||||
```
|
||||
|
||||
## Enhanced Commands
|
||||
|
||||
Zafiro uses `IEnhancedCommand`, which extends `ICommand` and `IReactiveCommand` with additional metadata like `Name` and `Text`.
|
||||
|
||||
### Creating a Command
|
||||
|
||||
Use `ReactiveCommand.Create` or `ReactiveCommand.CreateFromTask` and then `Enhance()` it.
|
||||
|
||||
```csharp
|
||||
public IEnhancedCommand Submit { get; }
|
||||
|
||||
public MyViewModel()
|
||||
{
|
||||
Submit = ReactiveCommand.CreateFromTask(OnSubmit, canSubmit)
|
||||
.Enhance(text: "Submit Data", name: "SubmitCommand");
|
||||
}
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
Use `HandleErrorsWith` to automatically channel command errors to the `NotificationService`.
|
||||
|
||||
```csharp
|
||||
Submit.HandleErrorsWith(uiServices.NotificationService, "Submission Failed")
|
||||
.DisposeWith(disposable);
|
||||
```
|
||||
|
||||
## Disposables
|
||||
|
||||
Always use a `CompositeDisposable` to manage subscriptions and command lifetimes.
|
||||
|
||||
```csharp
|
||||
public class MyViewModel : ReactiveObject, IDisposable
|
||||
{
|
||||
private readonly CompositeDisposable disposables = new();
|
||||
|
||||
public void Dispose() => disposables.Dispose();
|
||||
}
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Use `.DisposeWith(disposables)` on any observable subscription or command to ensure proper cleanup.
|
||||
47
skills/avalonia-viewmodels-zafiro/wizards.md
Normal file
47
skills/avalonia-viewmodels-zafiro/wizards.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Wizards & Flows
|
||||
|
||||
Complex multi-step processes are handled using the `SlimWizard` pattern. This provides a declarative way to define steps, navigation logic, and final results.
|
||||
|
||||
## Defining a Wizard
|
||||
|
||||
Use `WizardBuilder` to define the steps. Each step corresponds to a ViewModel.
|
||||
|
||||
```csharp
|
||||
SlimWizard<string> wizard = WizardBuilder
|
||||
.StartWith(() => new Step1ViewModel(data))
|
||||
.NextUnit()
|
||||
.WhenValid()
|
||||
.Then(prevResult => new Step2ViewModel(prevResult))
|
||||
.NextCommand(vm => vm.CustomNextCommand)
|
||||
.Then(result => new SuccessViewModel("Done!"))
|
||||
.Next((_, s) => s, "Finish")
|
||||
.WithCompletionFinalStep();
|
||||
```
|
||||
|
||||
### Navigation Rules
|
||||
|
||||
- **NextUnit()**: Advances when a simple signal is emitted.
|
||||
- **NextCommand()**: Advances when a specific command in the ViewModel execution successfully.
|
||||
- **WhenValid()**: Wait until the current ViewModel's validation passes before allowing navigation.
|
||||
- **Always()**: Navigation is always allowed.
|
||||
|
||||
## Navigation Integration
|
||||
|
||||
The wizard is navigated using an `INavigator`:
|
||||
|
||||
```csharp
|
||||
public async Task CreateSomething()
|
||||
{
|
||||
var wizard = BuildWizard();
|
||||
var result = await wizard.Navigate(navigator);
|
||||
// Handle result
|
||||
}
|
||||
```
|
||||
|
||||
## Step Configuration
|
||||
|
||||
- **WithCompletionFinalStep()**: Marks the wizard as finished when the last step completes.
|
||||
- **WithCommitFinalStep()**: Typically used for wizards that perform a final "Save" or "Deploy" action.
|
||||
|
||||
> [!NOTE]
|
||||
> The `SlimWizard` handles the "Back" command automatically, providing a consistent user experience across different flows.
|
||||
29
skills/avalonia-zafiro-development/SKILL.md
Normal file
29
skills/avalonia-zafiro-development/SKILL.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: avalonia-zafiro-development
|
||||
description: Mandatory skills, conventions, and behavioral rules for Avalonia UI development using the Zafiro toolkit.
|
||||
---
|
||||
|
||||
# Avalonia Zafiro Development
|
||||
|
||||
This skill defines the mandatory conventions and behavioral rules for developing cross-platform applications with Avalonia UI and the Zafiro toolkit. These rules prioritize maintainability, correctness, and a functional-reactive approach.
|
||||
|
||||
## Core Pillars
|
||||
|
||||
1. **Functional-Reactive MVVM**: Pure MVVM logic using DynamicData and ReactiveUI.
|
||||
2. **Safety & Predictability**: Explicit error handling with `Result` types and avoidance of exceptions for flow control.
|
||||
3. **Cross-Platform Excellence**: Strictly Avalonia-independent ViewModels and composition-over-inheritance.
|
||||
4. **Zafiro First**: Leverage existing Zafiro abstractions and helpers to avoid redundancy.
|
||||
|
||||
## Guides
|
||||
|
||||
- [Core Technical Skills & Architecture](core-technical-skills.md): Fundamental skills and architectural principles.
|
||||
- [Naming & Coding Standards](naming-standards.md): Rules for naming, fields, and error handling.
|
||||
- [Avalonia, Zafiro & Reactive Rules](avalonia-reactive-rules.md): Specific guidelines for UI, Zafiro integration, and DynamicData pipelines.
|
||||
- [Zafiro Shortcuts](zafiro-shortcuts.md): Concise mappings for common Rx/Zafiro operations.
|
||||
- [Common Patterns](patterns.md): Advanced patterns like `RefreshableCollection` and Validation.
|
||||
|
||||
## Procedure Before Writing Code
|
||||
|
||||
1. **Search First**: Search the codebase for similar implementations or existing Zafiro helpers.
|
||||
2. **Reusable Extensions**: If a helper is missing, propose a new reusable extension method instead of inlining complex logic.
|
||||
3. **Reactive Pipelines**: Ensure DynamicData operators are used instead of plain Rx where applicable.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Avalonia, Zafiro & Reactive Rules
|
||||
|
||||
## Avalonia UI Rules
|
||||
|
||||
- **Strict Avalonia**: Never use `System.Drawing`; always use Avalonia types.
|
||||
- **Pure ViewModels**: ViewModels must **never** reference Avalonia types.
|
||||
- **Bindings Over Code-Behind**: Logic should be driven by bindings.
|
||||
- **DataTemplates**: Prefer explicit `DataTemplate`s and typed `DataContext`s.
|
||||
- **VisualStates**: Avoid using `VisualStates` unless absolutely required.
|
||||
|
||||
## Zafiro Guidelines
|
||||
|
||||
- **Prefer Abstractions**: Always look for existing Zafiro helpers, extension methods, and abstractions before re-implementing logic.
|
||||
- **Validation**: Use Zafiro's `ValidationRule` and validation extensions instead of ad-hoc reactive logic.
|
||||
|
||||
## DynamicData & Reactive Rules
|
||||
|
||||
### The Mandatory Approach
|
||||
|
||||
- **Operator Preference**: Always prefer **DynamicData** operators (`Connect`, `Filter`, `Transform`, `Sort`, `Bind`, `DisposeMany`) over plain Rx operators when working with collections.
|
||||
- **Readable Pipelines**: Build and maintain pipelines as a single, readable chain.
|
||||
- **Lifecycle**: Use `DisposeWith` for lifecycle management.
|
||||
- **Minimal Subscriptions**: Subscriptions should be minimal, centralized, and strictly for side-effects.
|
||||
|
||||
### Forbidden Anti-Patterns
|
||||
|
||||
- **Ad-hoc Sources**: Do NOT create new `SourceList` / `SourceCache` on the fly for local problems.
|
||||
- **Logic in Subscribe**: Do NOT place business logic inside `Subscribe`.
|
||||
- **Operator Mismatch**: Do NOT use `System.Reactive` operators if a DynamicData equivalent exists.
|
||||
|
||||
### Canonical Patterns
|
||||
|
||||
**Validation of Dynamic Collections:**
|
||||
```csharp
|
||||
this.ValidationRule(
|
||||
StagesSource
|
||||
.Connect()
|
||||
.FilterOnObservable(stage => stage.IsValid)
|
||||
.IsEmpty(),
|
||||
b => !b,
|
||||
_ => "Stages are not valid")
|
||||
.DisposeWith(Disposables);
|
||||
```
|
||||
|
||||
**Filtering Nulls:**
|
||||
Use `WhereNotNull()` in reactive pipelines.
|
||||
```csharp
|
||||
this.WhenAnyValue(x => x.DurationPreset).WhereNotNull()
|
||||
```
|
||||
19
skills/avalonia-zafiro-development/core-technical-skills.md
Normal file
19
skills/avalonia-zafiro-development/core-technical-skills.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Core Technical Skills & Architecture
|
||||
|
||||
## Mandatory Expertise
|
||||
|
||||
The developer must possess strong expertise in:
|
||||
- **C# and modern .NET**: Utilizing the latest features of the language and framework.
|
||||
- **Avalonia UI**: For cross-platform UI development.
|
||||
- **MVVM Architecture**: Maintaining strict separation between UI and business logic.
|
||||
- **Clean Code & Clean Architecture**: Focusing on maintainability and inward dependency flow.
|
||||
- **Functional Programming in C#**: Embracing immutability and functional patterns.
|
||||
- **Reactive Programming**: Expertise in DynamicData and System.Reactive.
|
||||
|
||||
## Architectural Principles
|
||||
|
||||
- **Pure MVVM**: Mandatory for all UI code. Logic must be independent of UI concerns.
|
||||
- **Composition over Inheritance**: Favor modular building blocks over deep inheritance hierarchies.
|
||||
- **Inward Dependency Flow**: Abstractions must not depend on implementations.
|
||||
- **Immutability**: Prefer immutable structures where practical to ensure predictability.
|
||||
- **Stable Public APIs**: Design APIs carefully to ensure long-term stability and clarity.
|
||||
15
skills/avalonia-zafiro-development/naming-standards.md
Normal file
15
skills/avalonia-zafiro-development/naming-standards.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Naming & Coding Standards
|
||||
|
||||
## General Standards
|
||||
|
||||
- **Explicit Names**: Favor clarity over cleverness.
|
||||
- **Async Suffix**: Do **NOT** use the `Async` suffix in method names, even if they return `Task`.
|
||||
- **Private Fields**: Do **NOT** use the `_` prefix for private fields.
|
||||
- **Static State**: Avoid static state unless explicitly justified and documented.
|
||||
- **Method Design**: Keep methods small, expressive, and with low cyclomatic complexity.
|
||||
|
||||
## Error Handling
|
||||
|
||||
- **Result & Maybe**: Use types from **CSharpFunctionalExtensions** for flow control and error handling.
|
||||
- **Exceptions**: Reserved strictly for truly exceptional, unrecoverable situations.
|
||||
- **Boundaries**: Never allow exceptions to leak across architectural boundaries.
|
||||
45
skills/avalonia-zafiro-development/patterns.md
Normal file
45
skills/avalonia-zafiro-development/patterns.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Common Patterns in Angor/Zafiro
|
||||
|
||||
## Refreshable Collections
|
||||
|
||||
The `RefreshableCollection` pattern is used to manage lists that can be refreshed via a command, maintaining an internal `SourceCache`/`SourceList` and exposing a `ReadOnlyObservableCollection`.
|
||||
|
||||
### Implementation
|
||||
|
||||
```csharp
|
||||
var refresher = RefreshableCollection.Create(
|
||||
() => GetDataTask(),
|
||||
model => model.Id)
|
||||
.DisposeWith(disposable);
|
||||
|
||||
LoadData = refresher.Refresh;
|
||||
Items = refresher.Items;
|
||||
```
|
||||
|
||||
### Benefits
|
||||
- **Automatic Loading**: Handles the command execution and results.
|
||||
- **Efficient Updates**: Uses `EditDiff` internally to update items without clearing the list.
|
||||
- **UI Friendly**: Exposes `Items` as a `ReadOnlyObservableCollection` suitable for binding.
|
||||
|
||||
## Mandatory Validation Pattern
|
||||
|
||||
When validating dynamic collections, always use the Zafiro validation extension:
|
||||
|
||||
```csharp
|
||||
this.ValidationRule(
|
||||
StagesSource
|
||||
.Connect()
|
||||
.FilterOnObservable(stage => stage.IsValid)
|
||||
.IsEmpty(),
|
||||
b => !b,
|
||||
_ => "Stages are not valid")
|
||||
.DisposeWith(Disposables);
|
||||
```
|
||||
|
||||
## Error Handling Pipeline
|
||||
|
||||
Instead of manual `Subscribe`, use `HandleErrorsWith` to pipe errors directly to the user:
|
||||
|
||||
```csharp
|
||||
LoadProjects.HandleErrorsWith(uiServices.NotificationService, "Could not load projects");
|
||||
```
|
||||
43
skills/avalonia-zafiro-development/zafiro-shortcuts.md
Normal file
43
skills/avalonia-zafiro-development/zafiro-shortcuts.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Zafiro Reactive Shortcuts
|
||||
|
||||
Use these Zafiro extension methods to replace standard, more verbose Reactive and DynamicData patterns.
|
||||
|
||||
## General Observable Helpers
|
||||
|
||||
| Standard Pattern | Zafiro Shortcut |
|
||||
| :--- | :--- |
|
||||
| `Replay(1).RefCount()` | `ReplayLastActive()` |
|
||||
| `Select(_ => Unit.Default)` | `ToSignal()` |
|
||||
| `Select(b => !b)` | `Not()` |
|
||||
| `Where(b => b).ToSignal()` | `Trues()` |
|
||||
| `Where(b => !b).ToSignal()` | `Falses()` |
|
||||
| `Select(x => x is null)` | `Null()` |
|
||||
| `Select(x => x is not null)` | `NotNull()` |
|
||||
| `Select(string.IsNullOrWhiteSpace)` | `NullOrWhitespace()` |
|
||||
| `Select(s => !string.IsNullOrWhiteSpace(s))` | `NotNullOrEmpty()` |
|
||||
|
||||
## Result & Maybe Extensions
|
||||
|
||||
| Standard Pattern | Zafiro Shortcut |
|
||||
| :--- | :--- |
|
||||
| `Where(r => r.IsSuccess).Select(r => r.Value)` | `Successes()` |
|
||||
| `Where(r => r.IsFailure).Select(r => r.Error)` | `Failures()` |
|
||||
| `Where(m => m.HasValue).Select(m => m.Value)` | `Values()` |
|
||||
| `Where(m => !m.HasValue).ToSignal()` | `Empties()` |
|
||||
|
||||
## Lifecycle Management
|
||||
|
||||
| Description | Method |
|
||||
| :--- | :--- |
|
||||
| Dispose previous item before emitting new one | `DisposePrevious()` |
|
||||
| Manage lifecycle within a disposable | `DisposeWith(disposables)` |
|
||||
|
||||
## Command & Interaction
|
||||
|
||||
| Description | Method |
|
||||
| :--- | :--- |
|
||||
| Add metadata/text to a ReactiveCommand | `Enhance(text, name)` |
|
||||
| Automatically show errors in UI | `HandleErrorsWith(notificationService)` |
|
||||
|
||||
> [!TIP]
|
||||
> Always check `Zafiro.Reactive.ObservableMixin` and `Zafiro.CSharpFunctionalExtensions.ObservableExtensions` before writing custom Rx logic.
|
||||
@@ -1,302 +1,342 @@
|
||||
---
|
||||
name: backend-dev-guidelines
|
||||
description: Comprehensive backend development guide for Node.js/Express/TypeScript microservices. Use when creating routes, controllers, services, repositories, middleware, or working with Express APIs, Prisma database access, Sentry error tracking, Zod validation, unifiedConfig, dependency injection, or async patterns. Covers layered architecture (routes → controllers → services → repositories), BaseController pattern, error handling, performance monitoring, testing strategies, and migration from legacy patterns.
|
||||
description: Opinionated backend development standards for Node.js + Express + TypeScript microservices. Covers layered architecture, BaseController pattern, dependency injection, Prisma repositories, Zod validation, unifiedConfig, Sentry error tracking, async safety, and testing discipline.
|
||||
---
|
||||
|
||||
# Backend Development Guidelines
|
||||
|
||||
## Purpose
|
||||
**(Node.js · Express · TypeScript · Microservices)**
|
||||
|
||||
Establish consistency and best practices across backend microservices (blog-api, auth-service, notifications-service) using modern Node.js/Express/TypeScript patterns.
|
||||
You are a **senior backend engineer** operating production-grade services under strict architectural and reliability constraints.
|
||||
|
||||
## When to Use This Skill
|
||||
Your goal is to build **predictable, observable, and maintainable backend systems** using:
|
||||
|
||||
Automatically activates when working on:
|
||||
- Creating or modifying routes, endpoints, APIs
|
||||
- Building controllers, services, repositories
|
||||
- Implementing middleware (auth, validation, error handling)
|
||||
- Database operations with Prisma
|
||||
- Error tracking with Sentry
|
||||
- Input validation with Zod
|
||||
- Configuration management
|
||||
- Backend testing and refactoring
|
||||
* Layered architecture
|
||||
* Explicit error boundaries
|
||||
* Strong typing and validation
|
||||
* Centralized configuration
|
||||
* First-class observability
|
||||
|
||||
This skill defines **how backend code must be written**, not merely suggestions.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
## 1. Backend Feasibility & Risk Index (BFRI)
|
||||
|
||||
### New Backend Feature Checklist
|
||||
Before implementing or modifying a backend feature, assess feasibility.
|
||||
|
||||
- [ ] **Route**: Clean definition, delegate to controller
|
||||
- [ ] **Controller**: Extend BaseController
|
||||
- [ ] **Service**: Business logic with DI
|
||||
- [ ] **Repository**: Database access (if complex)
|
||||
- [ ] **Validation**: Zod schema
|
||||
- [ ] **Sentry**: Error tracking
|
||||
- [ ] **Tests**: Unit + integration tests
|
||||
- [ ] **Config**: Use unifiedConfig
|
||||
### BFRI Dimensions (1–5)
|
||||
|
||||
### New Microservice Checklist
|
||||
| Dimension | Question |
|
||||
| ----------------------------- | ---------------------------------------------------------------- |
|
||||
| **Architectural Fit** | Does this follow routes → controllers → services → repositories? |
|
||||
| **Business Logic Complexity** | How complex is the domain logic? |
|
||||
| **Data Risk** | Does this affect critical data paths or transactions? |
|
||||
| **Operational Risk** | Does this impact auth, billing, messaging, or infra? |
|
||||
| **Testability** | Can this be reliably unit + integration tested? |
|
||||
|
||||
- [ ] Directory structure (see [architecture-overview.md](architecture-overview.md))
|
||||
- [ ] instrument.ts for Sentry
|
||||
- [ ] unifiedConfig setup
|
||||
- [ ] BaseController class
|
||||
- [ ] Middleware stack
|
||||
- [ ] Error boundary
|
||||
- [ ] Testing framework
|
||||
### Score Formula
|
||||
|
||||
```
|
||||
BFRI = (Architectural Fit + Testability) − (Complexity + Data Risk + Operational Risk)
|
||||
```
|
||||
|
||||
**Range:** `-10 → +10`
|
||||
|
||||
### Interpretation
|
||||
|
||||
| BFRI | Meaning | Action |
|
||||
| -------- | --------- | ---------------------- |
|
||||
| **6–10** | Safe | Proceed |
|
||||
| **3–5** | Moderate | Add tests + monitoring |
|
||||
| **0–2** | Risky | Refactor or isolate |
|
||||
| **< 0** | Dangerous | Redesign before coding |
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
## 2. When to Use This Skill
|
||||
|
||||
### Layered Architecture
|
||||
Automatically applies when working on:
|
||||
|
||||
```
|
||||
HTTP Request
|
||||
↓
|
||||
Routes (routing only)
|
||||
↓
|
||||
Controllers (request handling)
|
||||
↓
|
||||
Services (business logic)
|
||||
↓
|
||||
Repositories (data access)
|
||||
↓
|
||||
Database (Prisma)
|
||||
```
|
||||
|
||||
**Key Principle:** Each layer has ONE responsibility.
|
||||
|
||||
See [architecture-overview.md](architecture-overview.md) for complete details.
|
||||
* Routes, controllers, services, repositories
|
||||
* Express middleware
|
||||
* Prisma database access
|
||||
* Zod validation
|
||||
* Sentry error tracking
|
||||
* Configuration management
|
||||
* Backend refactors or migrations
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
## 3. Core Architecture Doctrine (Non-Negotiable)
|
||||
|
||||
### 1. Layered Architecture Is Mandatory
|
||||
|
||||
```
|
||||
service/src/
|
||||
├── config/ # UnifiedConfig
|
||||
├── controllers/ # Request handlers
|
||||
Routes → Controllers → Services → Repositories → Database
|
||||
```
|
||||
|
||||
* No layer skipping
|
||||
* No cross-layer leakage
|
||||
* Each layer has **one responsibility**
|
||||
|
||||
---
|
||||
|
||||
### 2. Routes Only Route
|
||||
|
||||
```ts
|
||||
// ❌ NEVER
|
||||
router.post('/create', async (req, res) => {
|
||||
await prisma.user.create(...);
|
||||
});
|
||||
|
||||
// ✅ ALWAYS
|
||||
router.post('/create', (req, res) =>
|
||||
userController.create(req, res)
|
||||
);
|
||||
```
|
||||
|
||||
Routes must contain **zero business logic**.
|
||||
|
||||
---
|
||||
|
||||
### 3. Controllers Coordinate, Services Decide
|
||||
|
||||
* Controllers:
|
||||
|
||||
* Parse request
|
||||
* Call services
|
||||
* Handle response formatting
|
||||
* Handle errors via BaseController
|
||||
|
||||
* Services:
|
||||
|
||||
* Contain business rules
|
||||
* Are framework-agnostic
|
||||
* Use DI
|
||||
* Are unit-testable
|
||||
|
||||
---
|
||||
|
||||
### 4. All Controllers Extend `BaseController`
|
||||
|
||||
```ts
|
||||
export class UserController extends BaseController {
|
||||
async getUser(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const user = await this.userService.getById(req.params.id);
|
||||
this.handleSuccess(res, user);
|
||||
} catch (error) {
|
||||
this.handleError(error, res, 'getUser');
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
No raw `res.json` calls outside BaseController helpers.
|
||||
|
||||
---
|
||||
|
||||
### 5. All Errors Go to Sentry
|
||||
|
||||
```ts
|
||||
catch (error) {
|
||||
Sentry.captureException(error);
|
||||
throw error;
|
||||
}
|
||||
```
|
||||
|
||||
❌ `console.log`
|
||||
❌ silent failures
|
||||
❌ swallowed errors
|
||||
|
||||
---
|
||||
|
||||
### 6. unifiedConfig Is the Only Config Source
|
||||
|
||||
```ts
|
||||
// ❌ NEVER
|
||||
process.env.JWT_SECRET;
|
||||
|
||||
// ✅ ALWAYS
|
||||
import { config } from '@/config/unifiedConfig';
|
||||
config.auth.jwtSecret;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Validate All External Input with Zod
|
||||
|
||||
* Request bodies
|
||||
* Query params
|
||||
* Route params
|
||||
* Webhook payloads
|
||||
|
||||
```ts
|
||||
const schema = z.object({
|
||||
email: z.string().email(),
|
||||
});
|
||||
|
||||
const input = schema.parse(req.body);
|
||||
```
|
||||
|
||||
No validation = bug.
|
||||
|
||||
---
|
||||
|
||||
## 4. Directory Structure (Canonical)
|
||||
|
||||
```
|
||||
src/
|
||||
├── config/ # unifiedConfig
|
||||
├── controllers/ # BaseController + controllers
|
||||
├── services/ # Business logic
|
||||
├── repositories/ # Data access
|
||||
├── routes/ # Route definitions
|
||||
├── middleware/ # Express middleware
|
||||
├── types/ # TypeScript types
|
||||
├── repositories/ # Prisma access
|
||||
├── routes/ # Express routes
|
||||
├── middleware/ # Auth, validation, errors
|
||||
├── validators/ # Zod schemas
|
||||
├── utils/ # Utilities
|
||||
├── tests/ # Tests
|
||||
├── types/ # Shared types
|
||||
├── utils/ # Helpers
|
||||
├── tests/ # Unit + integration tests
|
||||
├── instrument.ts # Sentry (FIRST IMPORT)
|
||||
├── app.ts # Express setup
|
||||
├── app.ts # Express app
|
||||
└── server.ts # HTTP server
|
||||
```
|
||||
|
||||
**Naming Conventions:**
|
||||
- Controllers: `PascalCase` - `UserController.ts`
|
||||
- Services: `camelCase` - `userService.ts`
|
||||
- Routes: `camelCase + Routes` - `userRoutes.ts`
|
||||
- Repositories: `PascalCase + Repository` - `UserRepository.ts`
|
||||
---
|
||||
|
||||
## 5. Naming Conventions (Strict)
|
||||
|
||||
| Layer | Convention |
|
||||
| ---------- | ------------------------- |
|
||||
| Controller | `PascalCaseController.ts` |
|
||||
| Service | `camelCaseService.ts` |
|
||||
| Repository | `PascalCaseRepository.ts` |
|
||||
| Routes | `camelCaseRoutes.ts` |
|
||||
| Validators | `camelCase.schema.ts` |
|
||||
|
||||
---
|
||||
|
||||
## Core Principles (7 Key Rules)
|
||||
## 6. Dependency Injection Rules
|
||||
|
||||
### 1. Routes Only Route, Controllers Control
|
||||
* Services receive dependencies via constructor
|
||||
* No importing repositories directly inside controllers
|
||||
* Enables mocking and testing
|
||||
|
||||
```typescript
|
||||
// ❌ NEVER: Business logic in routes
|
||||
router.post('/submit', async (req, res) => {
|
||||
// 200 lines of logic
|
||||
});
|
||||
|
||||
// ✅ ALWAYS: Delegate to controller
|
||||
router.post('/submit', (req, res) => controller.submit(req, res));
|
||||
```
|
||||
|
||||
### 2. All Controllers Extend BaseController
|
||||
|
||||
```typescript
|
||||
export class UserController extends BaseController {
|
||||
async getUser(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const user = await this.userService.findById(req.params.id);
|
||||
this.handleSuccess(res, user);
|
||||
} catch (error) {
|
||||
this.handleError(error, res, 'getUser');
|
||||
}
|
||||
}
|
||||
```ts
|
||||
export class UserService {
|
||||
constructor(
|
||||
private readonly userRepository: UserRepository
|
||||
) {}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. All Errors to Sentry
|
||||
---
|
||||
|
||||
```typescript
|
||||
try {
|
||||
await operation();
|
||||
} catch (error) {
|
||||
Sentry.captureException(error);
|
||||
throw error;
|
||||
}
|
||||
## 7. Prisma & Repository Rules
|
||||
|
||||
* Prisma client **never used directly in controllers**
|
||||
* Repositories:
|
||||
|
||||
* Encapsulate queries
|
||||
* Handle transactions
|
||||
* Expose intent-based methods
|
||||
|
||||
```ts
|
||||
await userRepository.findActiveUsers();
|
||||
```
|
||||
|
||||
### 4. Use unifiedConfig, NEVER process.env
|
||||
---
|
||||
|
||||
```typescript
|
||||
// ❌ NEVER
|
||||
const timeout = process.env.TIMEOUT_MS;
|
||||
## 8. Async & Error Handling
|
||||
|
||||
// ✅ ALWAYS
|
||||
import { config } from './config/unifiedConfig';
|
||||
const timeout = config.timeouts.default;
|
||||
### asyncErrorWrapper Required
|
||||
|
||||
All async route handlers must be wrapped.
|
||||
|
||||
```ts
|
||||
router.get(
|
||||
'/users',
|
||||
asyncErrorWrapper((req, res) =>
|
||||
controller.list(req, res)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
### 5. Validate All Input with Zod
|
||||
No unhandled promise rejections.
|
||||
|
||||
```typescript
|
||||
const schema = z.object({ email: z.string().email() });
|
||||
const validated = schema.parse(req.body);
|
||||
```
|
||||
---
|
||||
|
||||
### 6. Use Repository Pattern for Data Access
|
||||
## 9. Observability & Monitoring
|
||||
|
||||
```typescript
|
||||
// Service → Repository → Database
|
||||
const users = await userRepository.findActive();
|
||||
```
|
||||
### Required
|
||||
|
||||
### 7. Comprehensive Testing Required
|
||||
* Sentry error tracking
|
||||
* Sentry performance tracing
|
||||
* Structured logs (where applicable)
|
||||
|
||||
```typescript
|
||||
Every critical path must be observable.
|
||||
|
||||
---
|
||||
|
||||
## 10. Testing Discipline
|
||||
|
||||
### Required Tests
|
||||
|
||||
* **Unit tests** for services
|
||||
* **Integration tests** for routes
|
||||
* **Repository tests** for complex queries
|
||||
|
||||
```ts
|
||||
describe('UserService', () => {
|
||||
it('should create user', async () => {
|
||||
expect(user).toBeDefined();
|
||||
});
|
||||
it('creates a user', async () => {
|
||||
expect(user).toBeDefined();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Imports
|
||||
|
||||
```typescript
|
||||
// Express
|
||||
import express, { Request, Response, NextFunction, Router } from 'express';
|
||||
|
||||
// Validation
|
||||
import { z } from 'zod';
|
||||
|
||||
// Database
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import type { Prisma } from '@prisma/client';
|
||||
|
||||
// Sentry
|
||||
import * as Sentry from '@sentry/node';
|
||||
|
||||
// Config
|
||||
import { config } from './config/unifiedConfig';
|
||||
|
||||
// Middleware
|
||||
import { SSOMiddlewareClient } from './middleware/SSOMiddleware';
|
||||
import { asyncErrorWrapper } from './middleware/errorBoundary';
|
||||
```
|
||||
No tests → no merge.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### HTTP Status Codes
|
||||
|
||||
| Code | Use Case |
|
||||
|------|----------|
|
||||
| 200 | Success |
|
||||
| 201 | Created |
|
||||
| 400 | Bad Request |
|
||||
| 401 | Unauthorized |
|
||||
| 403 | Forbidden |
|
||||
| 404 | Not Found |
|
||||
| 500 | Server Error |
|
||||
|
||||
### Service Templates
|
||||
|
||||
**Blog API** (✅ Mature) - Use as template for REST APIs
|
||||
**Auth Service** (✅ Mature) - Use as template for authentication patterns
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns to Avoid
|
||||
## 11. Anti-Patterns (Immediate Rejection)
|
||||
|
||||
❌ Business logic in routes
|
||||
❌ Direct process.env usage
|
||||
❌ Missing error handling
|
||||
❌ No input validation
|
||||
❌ Direct Prisma everywhere
|
||||
❌ Skipping service layer
|
||||
❌ Direct Prisma in controllers
|
||||
❌ Missing validation
|
||||
❌ process.env usage
|
||||
❌ console.log instead of Sentry
|
||||
❌ Untested business logic
|
||||
|
||||
---
|
||||
|
||||
## Navigation Guide
|
||||
## 12. Integration With Other Skills
|
||||
|
||||
| Need to... | Read this |
|
||||
|------------|-----------|
|
||||
| Understand architecture | [architecture-overview.md](architecture-overview.md) |
|
||||
| Create routes/controllers | [routing-and-controllers.md](routing-and-controllers.md) |
|
||||
| Organize business logic | [services-and-repositories.md](services-and-repositories.md) |
|
||||
| Validate input | [validation-patterns.md](validation-patterns.md) |
|
||||
| Add error tracking | [sentry-and-monitoring.md](sentry-and-monitoring.md) |
|
||||
| Create middleware | [middleware-guide.md](middleware-guide.md) |
|
||||
| Database access | [database-patterns.md](database-patterns.md) |
|
||||
| Manage config | [configuration.md](configuration.md) |
|
||||
| Handle async/errors | [async-and-errors.md](async-and-errors.md) |
|
||||
| Write tests | [testing-guide.md](testing-guide.md) |
|
||||
| See examples | [complete-examples.md](complete-examples.md) |
|
||||
* **frontend-dev-guidelines** → API contract alignment
|
||||
* **error-tracking** → Sentry standards
|
||||
* **database-verification** → Schema correctness
|
||||
* **analytics-tracking** → Event pipelines
|
||||
* **skill-developer** → Skill governance
|
||||
|
||||
---
|
||||
|
||||
## Resource Files
|
||||
## 13. Operator Validation Checklist
|
||||
|
||||
### [architecture-overview.md](architecture-overview.md)
|
||||
Layered architecture, request lifecycle, separation of concerns
|
||||
Before finalizing backend work:
|
||||
|
||||
### [routing-and-controllers.md](routing-and-controllers.md)
|
||||
Route definitions, BaseController, error handling, examples
|
||||
|
||||
### [services-and-repositories.md](services-and-repositories.md)
|
||||
Service patterns, DI, repository pattern, caching
|
||||
|
||||
### [validation-patterns.md](validation-patterns.md)
|
||||
Zod schemas, validation, DTO pattern
|
||||
|
||||
### [sentry-and-monitoring.md](sentry-and-monitoring.md)
|
||||
Sentry init, error capture, performance monitoring
|
||||
|
||||
### [middleware-guide.md](middleware-guide.md)
|
||||
Auth, audit, error boundaries, AsyncLocalStorage
|
||||
|
||||
### [database-patterns.md](database-patterns.md)
|
||||
PrismaService, repositories, transactions, optimization
|
||||
|
||||
### [configuration.md](configuration.md)
|
||||
UnifiedConfig, environment configs, secrets
|
||||
|
||||
### [async-and-errors.md](async-and-errors.md)
|
||||
Async patterns, custom errors, asyncErrorWrapper
|
||||
|
||||
### [testing-guide.md](testing-guide.md)
|
||||
Unit/integration tests, mocking, coverage
|
||||
|
||||
### [complete-examples.md](complete-examples.md)
|
||||
Full examples, refactoring guide
|
||||
* [ ] BFRI ≥ 3
|
||||
* [ ] Layered architecture respected
|
||||
* [ ] Input validated
|
||||
* [ ] Errors captured in Sentry
|
||||
* [ ] unifiedConfig used
|
||||
* [ ] Tests written
|
||||
* [ ] No anti-patterns present
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- **database-verification** - Verify column names and schema consistency
|
||||
- **error-tracking** - Sentry integration patterns
|
||||
- **skill-developer** - Meta-skill for creating and managing skills
|
||||
## 14. Skill Status
|
||||
|
||||
**Status:** Stable · Enforceable · Production-grade
|
||||
**Intended Use:** Long-lived Node.js microservices with real traffic and real risk
|
||||
---
|
||||
|
||||
**Skill Status**: COMPLETE ✅
|
||||
**Line Count**: < 500 ✅
|
||||
**Progressive Disclosure**: 11 resource files ✅
|
||||
|
||||
@@ -1,54 +1,230 @@
|
||||
---
|
||||
name: brainstorming
|
||||
description: "You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation."
|
||||
description: >
|
||||
Use this skill before any creative or constructive work
|
||||
(features, components, architecture, behavior changes, or functionality).
|
||||
This skill transforms vague ideas into validated designs through
|
||||
disciplined, incremental reasoning and collaboration.
|
||||
---
|
||||
|
||||
# Brainstorming Ideas Into Designs
|
||||
|
||||
## Overview
|
||||
## Purpose
|
||||
|
||||
Help turn ideas into fully formed designs and specs through natural collaborative dialogue.
|
||||
Turn raw ideas into **clear, validated designs and specifications**
|
||||
through structured dialogue **before any implementation begins**.
|
||||
|
||||
Start by understanding the current project context, then ask questions one at a time to refine the idea. Once you understand what you're building, present the design in small sections (200-300 words), checking after each section whether it looks right so far.
|
||||
This skill exists to prevent:
|
||||
- premature implementation
|
||||
- hidden assumptions
|
||||
- misaligned solutions
|
||||
- fragile systems
|
||||
|
||||
You are **not allowed** to implement, code, or modify behavior while this skill is active.
|
||||
|
||||
---
|
||||
|
||||
## Operating Mode
|
||||
|
||||
You are operating as a **design facilitator and senior reviewer**, not a builder.
|
||||
|
||||
- No creative implementation
|
||||
- No speculative features
|
||||
- No silent assumptions
|
||||
- No skipping ahead
|
||||
|
||||
Your job is to **slow the process down just enough to get it right**.
|
||||
|
||||
---
|
||||
|
||||
## The Process
|
||||
|
||||
**Understanding the idea:**
|
||||
- Check out the current project state first (files, docs, recent commits)
|
||||
- Ask questions one at a time to refine the idea
|
||||
- Prefer multiple choice questions when possible, but open-ended is fine too
|
||||
- Only one question per message - if a topic needs more exploration, break it into multiple questions
|
||||
- Focus on understanding: purpose, constraints, success criteria
|
||||
### 1️⃣ Understand the Current Context (Mandatory First Step)
|
||||
|
||||
**Exploring approaches:**
|
||||
- Propose 2-3 different approaches with trade-offs
|
||||
- Present options conversationally with your recommendation and reasoning
|
||||
- Lead with your recommended option and explain why
|
||||
Before asking any questions:
|
||||
|
||||
**Presenting the design:**
|
||||
- Once you believe you understand what you're building, present the design
|
||||
- Break it into sections of 200-300 words
|
||||
- Ask after each section whether it looks right so far
|
||||
- Cover: architecture, components, data flow, error handling, testing
|
||||
- Be ready to go back and clarify if something doesn't make sense
|
||||
- Review the current project state (if available):
|
||||
- files
|
||||
- documentation
|
||||
- plans
|
||||
- prior decisions
|
||||
- Identify what already exists vs. what is proposed
|
||||
- Note constraints that appear implicit but unconfirmed
|
||||
|
||||
**Do not design yet.**
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ Understanding the Idea (One Question at a Time)
|
||||
|
||||
Your goal here is **shared clarity**, not speed.
|
||||
|
||||
**Rules:**
|
||||
|
||||
- Ask **one question per message**
|
||||
- Prefer **multiple-choice questions** when possible
|
||||
- Use open-ended questions only when necessary
|
||||
- If a topic needs depth, split it into multiple questions
|
||||
|
||||
Focus on understanding:
|
||||
|
||||
- purpose
|
||||
- target users
|
||||
- constraints
|
||||
- success criteria
|
||||
- explicit non-goals
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Non-Functional Requirements (Mandatory)
|
||||
|
||||
You MUST explicitly clarify or propose assumptions for:
|
||||
|
||||
- Performance expectations
|
||||
- Scale (users, data, traffic)
|
||||
- Security or privacy constraints
|
||||
- Reliability / availability needs
|
||||
- Maintenance and ownership expectations
|
||||
|
||||
If the user is unsure:
|
||||
|
||||
- Propose reasonable defaults
|
||||
- Clearly mark them as **assumptions**
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ Understanding Lock (Hard Gate)
|
||||
|
||||
Before proposing **any design**, you MUST pause and do the following:
|
||||
|
||||
#### Understanding Summary
|
||||
Provide a concise summary (5–7 bullets) covering:
|
||||
- What is being built
|
||||
- Why it exists
|
||||
- Who it is for
|
||||
- Key constraints
|
||||
- Explicit non-goals
|
||||
|
||||
#### Assumptions
|
||||
List all assumptions explicitly.
|
||||
|
||||
#### Open Questions
|
||||
List unresolved questions, if any.
|
||||
|
||||
Then ask:
|
||||
|
||||
> “Does this accurately reflect your intent?
|
||||
> Please confirm or correct anything before we move to design.”
|
||||
|
||||
**Do NOT proceed until explicit confirmation is given.**
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ Explore Design Approaches
|
||||
|
||||
Once understanding is confirmed:
|
||||
|
||||
- Propose **2–3 viable approaches**
|
||||
- Lead with your **recommended option**
|
||||
- Explain trade-offs clearly:
|
||||
- complexity
|
||||
- extensibility
|
||||
- risk
|
||||
- maintenance
|
||||
- Avoid premature optimization (**YAGNI ruthlessly**)
|
||||
|
||||
This is still **not** final design.
|
||||
|
||||
---
|
||||
|
||||
### 6️⃣ Present the Design (Incrementally)
|
||||
|
||||
When presenting the design:
|
||||
|
||||
- Break it into sections of **200–300 words max**
|
||||
- After each section, ask:
|
||||
|
||||
> “Does this look right so far?”
|
||||
|
||||
Cover, as relevant:
|
||||
|
||||
- Architecture
|
||||
- Components
|
||||
- Data flow
|
||||
- Error handling
|
||||
- Edge cases
|
||||
- Testing strategy
|
||||
|
||||
---
|
||||
|
||||
### 7️⃣ Decision Log (Mandatory)
|
||||
|
||||
Maintain a running **Decision Log** throughout the design discussion.
|
||||
|
||||
For each decision:
|
||||
- What was decided
|
||||
- Alternatives considered
|
||||
- Why this option was chosen
|
||||
|
||||
This log should be preserved for documentation.
|
||||
|
||||
---
|
||||
|
||||
## After the Design
|
||||
|
||||
**Documentation:**
|
||||
- Write the validated design to `docs/plans/YYYY-MM-DD-<topic>-design.md`
|
||||
- Use elements-of-style:writing-clearly-and-concisely skill if available
|
||||
- Commit the design document to git
|
||||
### 📄 Documentation
|
||||
|
||||
**Implementation (if continuing):**
|
||||
- Ask: "Ready to set up for implementation?"
|
||||
- Use superpowers:using-git-worktrees to create isolated workspace
|
||||
- Use superpowers:writing-plans to create detailed implementation plan
|
||||
Once the design is validated:
|
||||
|
||||
## Key Principles
|
||||
- Write the final design to a durable, shared format (e.g. Markdown)
|
||||
- Include:
|
||||
- Understanding summary
|
||||
- Assumptions
|
||||
- Decision log
|
||||
- Final design
|
||||
|
||||
- **One question at a time** - Don't overwhelm with multiple questions
|
||||
- **Multiple choice preferred** - Easier to answer than open-ended when possible
|
||||
- **YAGNI ruthlessly** - Remove unnecessary features from all designs
|
||||
- **Explore alternatives** - Always propose 2-3 approaches before settling
|
||||
- **Incremental validation** - Present design in sections, validate each
|
||||
- **Be flexible** - Go back and clarify when something doesn't make sense
|
||||
Persist the document according to the project’s standard workflow.
|
||||
|
||||
---
|
||||
|
||||
### 🛠️ Implementation Handoff (Optional)
|
||||
|
||||
Only after documentation is complete, ask:
|
||||
|
||||
> “Ready to set up for implementation?”
|
||||
|
||||
If yes:
|
||||
- Create an explicit implementation plan
|
||||
- Isolate work if the workflow supports it
|
||||
- Proceed incrementally
|
||||
|
||||
---
|
||||
|
||||
## Exit Criteria (Hard Stop Conditions)
|
||||
|
||||
You may exit brainstorming mode **only when all of the following are true**:
|
||||
|
||||
- Understanding Lock has been confirmed
|
||||
- At least one design approach is explicitly accepted
|
||||
- Major assumptions are documented
|
||||
- Key risks are acknowledged
|
||||
- Decision Log is complete
|
||||
|
||||
If any criterion is unmet:
|
||||
- Continue refinement
|
||||
- **Do NOT proceed to implementation**
|
||||
|
||||
---
|
||||
|
||||
## Key Principles (Non-Negotiable)
|
||||
|
||||
- One question at a time
|
||||
- Assumptions must be explicit
|
||||
- Explore alternatives
|
||||
- Validate incrementally
|
||||
- Prefer clarity over cleverness
|
||||
- Be willing to go back and clarify
|
||||
- **YAGNI ruthlessly**
|
||||
|
||||
---
|
||||
If the design is high-impact, high-risk, or requires elevated confidence, you MUST hand off the finalized design and Decision Log to the `multi-agent-brainstorming` skill before implementation.
|
||||
|
||||
30
skills/busybox-on-windows/SKILL.md
Normal file
30
skills/busybox-on-windows/SKILL.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: busybox-on-windows
|
||||
description: How to use a Win32 build of BusyBox to run many of the standard UNIX command line tools on Windows.
|
||||
license: MIT
|
||||
---
|
||||
|
||||
BusyBox is a single binary that implements many common Unix tools.
|
||||
|
||||
Use this skill only on Windows. If you are on UNIX, then stop here.
|
||||
|
||||
Run the following steps only if you cannot find a `busybox.exe` file in the same directory as this document is.
|
||||
These are PowerShell commands, if you have a classic `cmd.exe` terminal, then you must use `powershell -Command "..."` to run them.
|
||||
1. Print the type of CPU: `Get-CimInstance -ClassName Win32_Processor | Select-Object Name, NumberOfCores, MaxClockSpeed`
|
||||
2. Print the OS versions: `Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | Select-Object ProductName, DisplayVersion, CurrentBuild`
|
||||
3. Download a suitable build of BusyBox by running one of these PowerShell commands:
|
||||
- 32-bit x86 (ANSI): `$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://frippery.org/files/busybox/busybox.exe -OutFile busybox.exe`
|
||||
- 64-bit x86 (ANSI): `$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://frippery.org/files/busybox/busybox64.exe -OutFile busybox.exe`
|
||||
- 64-bit x86 (Unicode): `$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://frippery.org/files/busybox/busybox64u.exe -OutFile busybox.exe`
|
||||
- 64-bit ARM (Unicode): `$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://frippery.org/files/busybox/busybox64a.exe -OutFile busybox.exe`
|
||||
|
||||
Useful commands:
|
||||
- Help: `busybox.exe --list`
|
||||
- Available UNIX commands: `busybox.exe --list`
|
||||
|
||||
Usage: Prefix the UNIX command with `busybox.exe`, for example: `busybox.exe ls -1`
|
||||
|
||||
If you need to run a UNIX command under another CWD, then use the absolute path to `busybox.exe`.
|
||||
|
||||
Documentation: https://frippery.org/busybox/
|
||||
Original BusyBox: https://busybox.net/
|
||||
584
skills/cc-skill-backend-patterns/SKILL.md
Normal file
584
skills/cc-skill-backend-patterns/SKILL.md
Normal file
@@ -0,0 +1,584 @@
|
||||
---
|
||||
name: backend-patterns
|
||||
description: Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Backend Development Patterns
|
||||
|
||||
Backend architecture patterns and best practices for scalable server-side applications.
|
||||
|
||||
## API Design Patterns
|
||||
|
||||
### RESTful API Structure
|
||||
|
||||
```typescript
|
||||
// ✅ Resource-based URLs
|
||||
GET /api/markets # List resources
|
||||
GET /api/markets/:id # Get single resource
|
||||
POST /api/markets # Create resource
|
||||
PUT /api/markets/:id # Replace resource
|
||||
PATCH /api/markets/:id # Update resource
|
||||
DELETE /api/markets/:id # Delete resource
|
||||
|
||||
// ✅ Query parameters for filtering, sorting, pagination
|
||||
GET /api/markets?status=active&sort=volume&limit=20&offset=0
|
||||
```
|
||||
|
||||
### Repository Pattern
|
||||
|
||||
```typescript
|
||||
// Abstract data access logic
|
||||
interface MarketRepository {
|
||||
findAll(filters?: MarketFilters): Promise<Market[]>
|
||||
findById(id: string): Promise<Market | null>
|
||||
create(data: CreateMarketDto): Promise<Market>
|
||||
update(id: string, data: UpdateMarketDto): Promise<Market>
|
||||
delete(id: string): Promise<void>
|
||||
}
|
||||
|
||||
class SupabaseMarketRepository implements MarketRepository {
|
||||
async findAll(filters?: MarketFilters): Promise<Market[]> {
|
||||
let query = supabase.from('markets').select('*')
|
||||
|
||||
if (filters?.status) {
|
||||
query = query.eq('status', filters.status)
|
||||
}
|
||||
|
||||
if (filters?.limit) {
|
||||
query = query.limit(filters.limit)
|
||||
}
|
||||
|
||||
const { data, error } = await query
|
||||
|
||||
if (error) throw new Error(error.message)
|
||||
return data
|
||||
}
|
||||
|
||||
// Other methods...
|
||||
}
|
||||
```
|
||||
|
||||
### Service Layer Pattern
|
||||
|
||||
```typescript
|
||||
// Business logic separated from data access
|
||||
class MarketService {
|
||||
constructor(private marketRepo: MarketRepository) {}
|
||||
|
||||
async searchMarkets(query: string, limit: number = 10): Promise<Market[]> {
|
||||
// Business logic
|
||||
const embedding = await generateEmbedding(query)
|
||||
const results = await this.vectorSearch(embedding, limit)
|
||||
|
||||
// Fetch full data
|
||||
const markets = await this.marketRepo.findByIds(results.map(r => r.id))
|
||||
|
||||
// Sort by similarity
|
||||
return markets.sort((a, b) => {
|
||||
const scoreA = results.find(r => r.id === a.id)?.score || 0
|
||||
const scoreB = results.find(r => r.id === b.id)?.score || 0
|
||||
return scoreA - scoreB
|
||||
})
|
||||
}
|
||||
|
||||
private async vectorSearch(embedding: number[], limit: number) {
|
||||
// Vector search implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware Pattern
|
||||
|
||||
```typescript
|
||||
// Request/response processing pipeline
|
||||
export function withAuth(handler: NextApiHandler): NextApiHandler {
|
||||
return async (req, res) => {
|
||||
const token = req.headers.authorization?.replace('Bearer ', '')
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({ error: 'Unauthorized' })
|
||||
}
|
||||
|
||||
try {
|
||||
const user = await verifyToken(token)
|
||||
req.user = user
|
||||
return handler(req, res)
|
||||
} catch (error) {
|
||||
return res.status(401).json({ error: 'Invalid token' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
export default withAuth(async (req, res) => {
|
||||
// Handler has access to req.user
|
||||
})
|
||||
```
|
||||
|
||||
## Database Patterns
|
||||
|
||||
### Query Optimization
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status, volume')
|
||||
.eq('status', 'active')
|
||||
.order('volume', { ascending: false })
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
```
|
||||
|
||||
### N+1 Query Prevention
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: N+1 query problem
|
||||
const markets = await getMarkets()
|
||||
for (const market of markets) {
|
||||
market.creator = await getUser(market.creator_id) // N queries
|
||||
}
|
||||
|
||||
// ✅ GOOD: Batch fetch
|
||||
const markets = await getMarkets()
|
||||
const creatorIds = markets.map(m => m.creator_id)
|
||||
const creators = await getUsers(creatorIds) // 1 query
|
||||
const creatorMap = new Map(creators.map(c => [c.id, c]))
|
||||
|
||||
markets.forEach(market => {
|
||||
market.creator = creatorMap.get(market.creator_id)
|
||||
})
|
||||
```
|
||||
|
||||
### Transaction Pattern
|
||||
|
||||
```typescript
|
||||
async function createMarketWithPosition(
|
||||
marketData: CreateMarketDto,
|
||||
positionData: CreatePositionDto
|
||||
) {
|
||||
// Use Supabase transaction
|
||||
const { data, error } = await supabase.rpc('create_market_with_position', {
|
||||
market_data: marketData,
|
||||
position_data: positionData
|
||||
})
|
||||
|
||||
if (error) throw new Error('Transaction failed')
|
||||
return data
|
||||
}
|
||||
|
||||
// SQL function in Supabase
|
||||
CREATE OR REPLACE FUNCTION create_market_with_position(
|
||||
market_data jsonb,
|
||||
position_data jsonb
|
||||
)
|
||||
RETURNS jsonb
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
-- Start transaction automatically
|
||||
INSERT INTO markets VALUES (market_data);
|
||||
INSERT INTO positions VALUES (position_data);
|
||||
RETURN jsonb_build_object('success', true);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
-- Rollback happens automatically
|
||||
RETURN jsonb_build_object('success', false, 'error', SQLERRM);
|
||||
END;
|
||||
$$;
|
||||
```
|
||||
|
||||
## Caching Strategies
|
||||
|
||||
### Redis Caching Layer
|
||||
|
||||
```typescript
|
||||
class CachedMarketRepository implements MarketRepository {
|
||||
constructor(
|
||||
private baseRepo: MarketRepository,
|
||||
private redis: RedisClient
|
||||
) {}
|
||||
|
||||
async findById(id: string): Promise<Market | null> {
|
||||
// Check cache first
|
||||
const cached = await this.redis.get(`market:${id}`)
|
||||
|
||||
if (cached) {
|
||||
return JSON.parse(cached)
|
||||
}
|
||||
|
||||
// Cache miss - fetch from database
|
||||
const market = await this.baseRepo.findById(id)
|
||||
|
||||
if (market) {
|
||||
// Cache for 5 minutes
|
||||
await this.redis.setex(`market:${id}`, 300, JSON.stringify(market))
|
||||
}
|
||||
|
||||
return market
|
||||
}
|
||||
|
||||
async invalidateCache(id: string): Promise<void> {
|
||||
await this.redis.del(`market:${id}`)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Cache-Aside Pattern
|
||||
|
||||
```typescript
|
||||
async function getMarketWithCache(id: string): Promise<Market> {
|
||||
const cacheKey = `market:${id}`
|
||||
|
||||
// Try cache
|
||||
const cached = await redis.get(cacheKey)
|
||||
if (cached) return JSON.parse(cached)
|
||||
|
||||
// Cache miss - fetch from DB
|
||||
const market = await db.markets.findUnique({ where: { id } })
|
||||
|
||||
if (!market) throw new Error('Market not found')
|
||||
|
||||
// Update cache
|
||||
await redis.setex(cacheKey, 300, JSON.stringify(market))
|
||||
|
||||
return market
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling Patterns
|
||||
|
||||
### Centralized Error Handler
|
||||
|
||||
```typescript
|
||||
class ApiError extends Error {
|
||||
constructor(
|
||||
public statusCode: number,
|
||||
public message: string,
|
||||
public isOperational = true
|
||||
) {
|
||||
super(message)
|
||||
Object.setPrototypeOf(this, ApiError.prototype)
|
||||
}
|
||||
}
|
||||
|
||||
export function errorHandler(error: unknown, req: Request): Response {
|
||||
if (error instanceof ApiError) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: error.message
|
||||
}, { status: error.statusCode })
|
||||
}
|
||||
|
||||
if (error instanceof z.ZodError) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors
|
||||
}, { status: 400 })
|
||||
}
|
||||
|
||||
// Log unexpected errors
|
||||
console.error('Unexpected error:', error)
|
||||
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
}, { status: 500 })
|
||||
}
|
||||
|
||||
// Usage
|
||||
export async function GET(request: Request) {
|
||||
try {
|
||||
const data = await fetchData()
|
||||
return NextResponse.json({ success: true, data })
|
||||
} catch (error) {
|
||||
return errorHandler(error, request)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Retry with Exponential Backoff
|
||||
|
||||
```typescript
|
||||
async function fetchWithRetry<T>(
|
||||
fn: () => Promise<T>,
|
||||
maxRetries = 3
|
||||
): Promise<T> {
|
||||
let lastError: Error
|
||||
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
return await fn()
|
||||
} catch (error) {
|
||||
lastError = error as Error
|
||||
|
||||
if (i < maxRetries - 1) {
|
||||
// Exponential backoff: 1s, 2s, 4s
|
||||
const delay = Math.pow(2, i) * 1000
|
||||
await new Promise(resolve => setTimeout(resolve, delay))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError!
|
||||
}
|
||||
|
||||
// Usage
|
||||
const data = await fetchWithRetry(() => fetchFromAPI())
|
||||
```
|
||||
|
||||
## Authentication & Authorization
|
||||
|
||||
### JWT Token Validation
|
||||
|
||||
```typescript
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
interface JWTPayload {
|
||||
userId: string
|
||||
email: string
|
||||
role: 'admin' | 'user'
|
||||
}
|
||||
|
||||
export function verifyToken(token: string): JWTPayload {
|
||||
try {
|
||||
const payload = jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload
|
||||
return payload
|
||||
} catch (error) {
|
||||
throw new ApiError(401, 'Invalid token')
|
||||
}
|
||||
}
|
||||
|
||||
export async function requireAuth(request: Request) {
|
||||
const token = request.headers.get('authorization')?.replace('Bearer ', '')
|
||||
|
||||
if (!token) {
|
||||
throw new ApiError(401, 'Missing authorization token')
|
||||
}
|
||||
|
||||
return verifyToken(token)
|
||||
}
|
||||
|
||||
// Usage in API route
|
||||
export async function GET(request: Request) {
|
||||
const user = await requireAuth(request)
|
||||
|
||||
const data = await getDataForUser(user.userId)
|
||||
|
||||
return NextResponse.json({ success: true, data })
|
||||
}
|
||||
```
|
||||
|
||||
### Role-Based Access Control
|
||||
|
||||
```typescript
|
||||
type Permission = 'read' | 'write' | 'delete' | 'admin'
|
||||
|
||||
interface User {
|
||||
id: string
|
||||
role: 'admin' | 'moderator' | 'user'
|
||||
}
|
||||
|
||||
const rolePermissions: Record<User['role'], Permission[]> = {
|
||||
admin: ['read', 'write', 'delete', 'admin'],
|
||||
moderator: ['read', 'write', 'delete'],
|
||||
user: ['read', 'write']
|
||||
}
|
||||
|
||||
export function hasPermission(user: User, permission: Permission): boolean {
|
||||
return rolePermissions[user.role].includes(permission)
|
||||
}
|
||||
|
||||
export function requirePermission(permission: Permission) {
|
||||
return async (request: Request) => {
|
||||
const user = await requireAuth(request)
|
||||
|
||||
if (!hasPermission(user, permission)) {
|
||||
throw new ApiError(403, 'Insufficient permissions')
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
export const DELETE = requirePermission('delete')(async (request: Request) => {
|
||||
// Handler with permission check
|
||||
})
|
||||
```
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
### Simple In-Memory Rate Limiter
|
||||
|
||||
```typescript
|
||||
class RateLimiter {
|
||||
private requests = new Map<string, number[]>()
|
||||
|
||||
async checkLimit(
|
||||
identifier: string,
|
||||
maxRequests: number,
|
||||
windowMs: number
|
||||
): Promise<boolean> {
|
||||
const now = Date.now()
|
||||
const requests = this.requests.get(identifier) || []
|
||||
|
||||
// Remove old requests outside window
|
||||
const recentRequests = requests.filter(time => now - time < windowMs)
|
||||
|
||||
if (recentRequests.length >= maxRequests) {
|
||||
return false // Rate limit exceeded
|
||||
}
|
||||
|
||||
// Add current request
|
||||
recentRequests.push(now)
|
||||
this.requests.set(identifier, recentRequests)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const limiter = new RateLimiter()
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const ip = request.headers.get('x-forwarded-for') || 'unknown'
|
||||
|
||||
const allowed = await limiter.checkLimit(ip, 100, 60000) // 100 req/min
|
||||
|
||||
if (!allowed) {
|
||||
return NextResponse.json({
|
||||
error: 'Rate limit exceeded'
|
||||
}, { status: 429 })
|
||||
}
|
||||
|
||||
// Continue with request
|
||||
}
|
||||
```
|
||||
|
||||
## Background Jobs & Queues
|
||||
|
||||
### Simple Queue Pattern
|
||||
|
||||
```typescript
|
||||
class JobQueue<T> {
|
||||
private queue: T[] = []
|
||||
private processing = false
|
||||
|
||||
async add(job: T): Promise<void> {
|
||||
this.queue.push(job)
|
||||
|
||||
if (!this.processing) {
|
||||
this.process()
|
||||
}
|
||||
}
|
||||
|
||||
private async process(): Promise<void> {
|
||||
this.processing = true
|
||||
|
||||
while (this.queue.length > 0) {
|
||||
const job = this.queue.shift()!
|
||||
|
||||
try {
|
||||
await this.execute(job)
|
||||
} catch (error) {
|
||||
console.error('Job failed:', error)
|
||||
}
|
||||
}
|
||||
|
||||
this.processing = false
|
||||
}
|
||||
|
||||
private async execute(job: T): Promise<void> {
|
||||
// Job execution logic
|
||||
}
|
||||
}
|
||||
|
||||
// Usage for indexing markets
|
||||
interface IndexJob {
|
||||
marketId: string
|
||||
}
|
||||
|
||||
const indexQueue = new JobQueue<IndexJob>()
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const { marketId } = await request.json()
|
||||
|
||||
// Add to queue instead of blocking
|
||||
await indexQueue.add({ marketId })
|
||||
|
||||
return NextResponse.json({ success: true, message: 'Job queued' })
|
||||
}
|
||||
```
|
||||
|
||||
## Logging & Monitoring
|
||||
|
||||
### Structured Logging
|
||||
|
||||
```typescript
|
||||
interface LogContext {
|
||||
userId?: string
|
||||
requestId?: string
|
||||
method?: string
|
||||
path?: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
class Logger {
|
||||
log(level: 'info' | 'warn' | 'error', message: string, context?: LogContext) {
|
||||
const entry = {
|
||||
timestamp: new Date().toISOString(),
|
||||
level,
|
||||
message,
|
||||
...context
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(entry))
|
||||
}
|
||||
|
||||
info(message: string, context?: LogContext) {
|
||||
this.log('info', message, context)
|
||||
}
|
||||
|
||||
warn(message: string, context?: LogContext) {
|
||||
this.log('warn', message, context)
|
||||
}
|
||||
|
||||
error(message: string, error: Error, context?: LogContext) {
|
||||
this.log('error', message, {
|
||||
...context,
|
||||
error: error.message,
|
||||
stack: error.stack
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const logger = new Logger()
|
||||
|
||||
// Usage
|
||||
export async function GET(request: Request) {
|
||||
const requestId = crypto.randomUUID()
|
||||
|
||||
logger.info('Fetching markets', {
|
||||
requestId,
|
||||
method: 'GET',
|
||||
path: '/api/markets'
|
||||
})
|
||||
|
||||
try {
|
||||
const markets = await fetchMarkets()
|
||||
return NextResponse.json({ success: true, data: markets })
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch markets', error as Error, { requestId })
|
||||
return NextResponse.json({ error: 'Internal error' }, { status: 500 })
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Remember**: Backend patterns enable scalable, maintainable server-side applications. Choose patterns that fit your complexity level.
|
||||
431
skills/cc-skill-clickhouse-io/SKILL.md
Normal file
431
skills/cc-skill-clickhouse-io/SKILL.md
Normal file
@@ -0,0 +1,431 @@
|
||||
---
|
||||
name: clickhouse-io
|
||||
description: ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# ClickHouse Analytics Patterns
|
||||
|
||||
ClickHouse-specific patterns for high-performance analytics and data engineering.
|
||||
|
||||
## Overview
|
||||
|
||||
ClickHouse is a column-oriented database management system (DBMS) for online analytical processing (OLAP). It's optimized for fast analytical queries on large datasets.
|
||||
|
||||
**Key Features:**
|
||||
- Column-oriented storage
|
||||
- Data compression
|
||||
- Parallel query execution
|
||||
- Distributed queries
|
||||
- Real-time analytics
|
||||
|
||||
## Table Design Patterns
|
||||
|
||||
### MergeTree Engine (Most Common)
|
||||
|
||||
```sql
|
||||
CREATE TABLE markets_analytics (
|
||||
date Date,
|
||||
market_id String,
|
||||
market_name String,
|
||||
volume UInt64,
|
||||
trades UInt32,
|
||||
unique_traders UInt32,
|
||||
avg_trade_size Float64,
|
||||
created_at DateTime
|
||||
) ENGINE = MergeTree()
|
||||
PARTITION BY toYYYYMM(date)
|
||||
ORDER BY (date, market_id)
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
|
||||
### ReplacingMergeTree (Deduplication)
|
||||
|
||||
```sql
|
||||
-- For data that may have duplicates (e.g., from multiple sources)
|
||||
CREATE TABLE user_events (
|
||||
event_id String,
|
||||
user_id String,
|
||||
event_type String,
|
||||
timestamp DateTime,
|
||||
properties String
|
||||
) ENGINE = ReplacingMergeTree()
|
||||
PARTITION BY toYYYYMM(timestamp)
|
||||
ORDER BY (user_id, event_id, timestamp)
|
||||
PRIMARY KEY (user_id, event_id);
|
||||
```
|
||||
|
||||
### AggregatingMergeTree (Pre-aggregation)
|
||||
|
||||
```sql
|
||||
-- For maintaining aggregated metrics
|
||||
CREATE TABLE market_stats_hourly (
|
||||
hour DateTime,
|
||||
market_id String,
|
||||
total_volume AggregateFunction(sum, UInt64),
|
||||
total_trades AggregateFunction(count, UInt32),
|
||||
unique_users AggregateFunction(uniq, String)
|
||||
) ENGINE = AggregatingMergeTree()
|
||||
PARTITION BY toYYYYMM(hour)
|
||||
ORDER BY (hour, market_id);
|
||||
|
||||
-- Query aggregated data
|
||||
SELECT
|
||||
hour,
|
||||
market_id,
|
||||
sumMerge(total_volume) AS volume,
|
||||
countMerge(total_trades) AS trades,
|
||||
uniqMerge(unique_users) AS users
|
||||
FROM market_stats_hourly
|
||||
WHERE hour >= toStartOfHour(now() - INTERVAL 24 HOUR)
|
||||
GROUP BY hour, market_id
|
||||
ORDER BY hour DESC;
|
||||
```
|
||||
|
||||
## Query Optimization Patterns
|
||||
|
||||
### Efficient Filtering
|
||||
|
||||
```sql
|
||||
-- ✅ GOOD: Use indexed columns first
|
||||
SELECT *
|
||||
FROM markets_analytics
|
||||
WHERE date >= '2025-01-01'
|
||||
AND market_id = 'market-123'
|
||||
AND volume > 1000
|
||||
ORDER BY date DESC
|
||||
LIMIT 100;
|
||||
|
||||
-- ❌ BAD: Filter on non-indexed columns first
|
||||
SELECT *
|
||||
FROM markets_analytics
|
||||
WHERE volume > 1000
|
||||
AND market_name LIKE '%election%'
|
||||
AND date >= '2025-01-01';
|
||||
```
|
||||
|
||||
### Aggregations
|
||||
|
||||
```sql
|
||||
-- ✅ GOOD: Use ClickHouse-specific aggregation functions
|
||||
SELECT
|
||||
toStartOfDay(created_at) AS day,
|
||||
market_id,
|
||||
sum(volume) AS total_volume,
|
||||
count() AS total_trades,
|
||||
uniq(trader_id) AS unique_traders,
|
||||
avg(trade_size) AS avg_size
|
||||
FROM trades
|
||||
WHERE created_at >= today() - INTERVAL 7 DAY
|
||||
GROUP BY day, market_id
|
||||
ORDER BY day DESC, total_volume DESC;
|
||||
|
||||
-- ✅ Use quantile for percentiles (more efficient than percentile)
|
||||
SELECT
|
||||
quantile(0.50)(trade_size) AS median,
|
||||
quantile(0.95)(trade_size) AS p95,
|
||||
quantile(0.99)(trade_size) AS p99
|
||||
FROM trades
|
||||
WHERE created_at >= now() - INTERVAL 1 HOUR;
|
||||
```
|
||||
|
||||
### Window Functions
|
||||
|
||||
```sql
|
||||
-- Calculate running totals
|
||||
SELECT
|
||||
date,
|
||||
market_id,
|
||||
volume,
|
||||
sum(volume) OVER (
|
||||
PARTITION BY market_id
|
||||
ORDER BY date
|
||||
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
) AS cumulative_volume
|
||||
FROM markets_analytics
|
||||
WHERE date >= today() - INTERVAL 30 DAY
|
||||
ORDER BY market_id, date;
|
||||
```
|
||||
|
||||
## Data Insertion Patterns
|
||||
|
||||
### Bulk Insert (Recommended)
|
||||
|
||||
```typescript
|
||||
import { ClickHouse } from 'clickhouse'
|
||||
|
||||
const clickhouse = new ClickHouse({
|
||||
url: process.env.CLICKHOUSE_URL,
|
||||
port: 8123,
|
||||
basicAuth: {
|
||||
username: process.env.CLICKHOUSE_USER,
|
||||
password: process.env.CLICKHOUSE_PASSWORD
|
||||
}
|
||||
})
|
||||
|
||||
// ✅ Batch insert (efficient)
|
||||
async function bulkInsertTrades(trades: Trade[]) {
|
||||
const values = trades.map(trade => `(
|
||||
'${trade.id}',
|
||||
'${trade.market_id}',
|
||||
'${trade.user_id}',
|
||||
${trade.amount},
|
||||
'${trade.timestamp.toISOString()}'
|
||||
)`).join(',')
|
||||
|
||||
await clickhouse.query(`
|
||||
INSERT INTO trades (id, market_id, user_id, amount, timestamp)
|
||||
VALUES ${values}
|
||||
`).toPromise()
|
||||
}
|
||||
|
||||
// ❌ Individual inserts (slow)
|
||||
async function insertTrade(trade: Trade) {
|
||||
// Don't do this in a loop!
|
||||
await clickhouse.query(`
|
||||
INSERT INTO trades VALUES ('${trade.id}', ...)
|
||||
`).toPromise()
|
||||
}
|
||||
```
|
||||
|
||||
### Streaming Insert
|
||||
|
||||
```typescript
|
||||
// For continuous data ingestion
|
||||
import { createWriteStream } from 'fs'
|
||||
import { pipeline } from 'stream/promises'
|
||||
|
||||
async function streamInserts() {
|
||||
const stream = clickhouse.insert('trades').stream()
|
||||
|
||||
for await (const batch of dataSource) {
|
||||
stream.write(batch)
|
||||
}
|
||||
|
||||
await stream.end()
|
||||
}
|
||||
```
|
||||
|
||||
## Materialized Views
|
||||
|
||||
### Real-time Aggregations
|
||||
|
||||
```sql
|
||||
-- Create materialized view for hourly stats
|
||||
CREATE MATERIALIZED VIEW market_stats_hourly_mv
|
||||
TO market_stats_hourly
|
||||
AS SELECT
|
||||
toStartOfHour(timestamp) AS hour,
|
||||
market_id,
|
||||
sumState(amount) AS total_volume,
|
||||
countState() AS total_trades,
|
||||
uniqState(user_id) AS unique_users
|
||||
FROM trades
|
||||
GROUP BY hour, market_id;
|
||||
|
||||
-- Query the materialized view
|
||||
SELECT
|
||||
hour,
|
||||
market_id,
|
||||
sumMerge(total_volume) AS volume,
|
||||
countMerge(total_trades) AS trades,
|
||||
uniqMerge(unique_users) AS users
|
||||
FROM market_stats_hourly
|
||||
WHERE hour >= now() - INTERVAL 24 HOUR
|
||||
GROUP BY hour, market_id;
|
||||
```
|
||||
|
||||
## Performance Monitoring
|
||||
|
||||
### Query Performance
|
||||
|
||||
```sql
|
||||
-- Check slow queries
|
||||
SELECT
|
||||
query_id,
|
||||
user,
|
||||
query,
|
||||
query_duration_ms,
|
||||
read_rows,
|
||||
read_bytes,
|
||||
memory_usage
|
||||
FROM system.query_log
|
||||
WHERE type = 'QueryFinish'
|
||||
AND query_duration_ms > 1000
|
||||
AND event_time >= now() - INTERVAL 1 HOUR
|
||||
ORDER BY query_duration_ms DESC
|
||||
LIMIT 10;
|
||||
```
|
||||
|
||||
### Table Statistics
|
||||
|
||||
```sql
|
||||
-- Check table sizes
|
||||
SELECT
|
||||
database,
|
||||
table,
|
||||
formatReadableSize(sum(bytes)) AS size,
|
||||
sum(rows) AS rows,
|
||||
max(modification_time) AS latest_modification
|
||||
FROM system.parts
|
||||
WHERE active
|
||||
GROUP BY database, table
|
||||
ORDER BY sum(bytes) DESC;
|
||||
```
|
||||
|
||||
## Common Analytics Queries
|
||||
|
||||
### Time Series Analysis
|
||||
|
||||
```sql
|
||||
-- Daily active users
|
||||
SELECT
|
||||
toDate(timestamp) AS date,
|
||||
uniq(user_id) AS daily_active_users
|
||||
FROM events
|
||||
WHERE timestamp >= today() - INTERVAL 30 DAY
|
||||
GROUP BY date
|
||||
ORDER BY date;
|
||||
|
||||
-- Retention analysis
|
||||
SELECT
|
||||
signup_date,
|
||||
countIf(days_since_signup = 0) AS day_0,
|
||||
countIf(days_since_signup = 1) AS day_1,
|
||||
countIf(days_since_signup = 7) AS day_7,
|
||||
countIf(days_since_signup = 30) AS day_30
|
||||
FROM (
|
||||
SELECT
|
||||
user_id,
|
||||
min(toDate(timestamp)) AS signup_date,
|
||||
toDate(timestamp) AS activity_date,
|
||||
dateDiff('day', signup_date, activity_date) AS days_since_signup
|
||||
FROM events
|
||||
GROUP BY user_id, activity_date
|
||||
)
|
||||
GROUP BY signup_date
|
||||
ORDER BY signup_date DESC;
|
||||
```
|
||||
|
||||
### Funnel Analysis
|
||||
|
||||
```sql
|
||||
-- Conversion funnel
|
||||
SELECT
|
||||
countIf(step = 'viewed_market') AS viewed,
|
||||
countIf(step = 'clicked_trade') AS clicked,
|
||||
countIf(step = 'completed_trade') AS completed,
|
||||
round(clicked / viewed * 100, 2) AS view_to_click_rate,
|
||||
round(completed / clicked * 100, 2) AS click_to_completion_rate
|
||||
FROM (
|
||||
SELECT
|
||||
user_id,
|
||||
session_id,
|
||||
event_type AS step
|
||||
FROM events
|
||||
WHERE event_date = today()
|
||||
)
|
||||
GROUP BY session_id;
|
||||
```
|
||||
|
||||
### Cohort Analysis
|
||||
|
||||
```sql
|
||||
-- User cohorts by signup month
|
||||
SELECT
|
||||
toStartOfMonth(signup_date) AS cohort,
|
||||
toStartOfMonth(activity_date) AS month,
|
||||
dateDiff('month', cohort, month) AS months_since_signup,
|
||||
count(DISTINCT user_id) AS active_users
|
||||
FROM (
|
||||
SELECT
|
||||
user_id,
|
||||
min(toDate(timestamp)) OVER (PARTITION BY user_id) AS signup_date,
|
||||
toDate(timestamp) AS activity_date
|
||||
FROM events
|
||||
)
|
||||
GROUP BY cohort, month, months_since_signup
|
||||
ORDER BY cohort, months_since_signup;
|
||||
```
|
||||
|
||||
## Data Pipeline Patterns
|
||||
|
||||
### ETL Pattern
|
||||
|
||||
```typescript
|
||||
// Extract, Transform, Load
|
||||
async function etlPipeline() {
|
||||
// 1. Extract from source
|
||||
const rawData = await extractFromPostgres()
|
||||
|
||||
// 2. Transform
|
||||
const transformed = rawData.map(row => ({
|
||||
date: new Date(row.created_at).toISOString().split('T')[0],
|
||||
market_id: row.market_slug,
|
||||
volume: parseFloat(row.total_volume),
|
||||
trades: parseInt(row.trade_count)
|
||||
}))
|
||||
|
||||
// 3. Load to ClickHouse
|
||||
await bulkInsertToClickHouse(transformed)
|
||||
}
|
||||
|
||||
// Run periodically
|
||||
setInterval(etlPipeline, 60 * 60 * 1000) // Every hour
|
||||
```
|
||||
|
||||
### Change Data Capture (CDC)
|
||||
|
||||
```typescript
|
||||
// Listen to PostgreSQL changes and sync to ClickHouse
|
||||
import { Client } from 'pg'
|
||||
|
||||
const pgClient = new Client({ connectionString: process.env.DATABASE_URL })
|
||||
|
||||
pgClient.query('LISTEN market_updates')
|
||||
|
||||
pgClient.on('notification', async (msg) => {
|
||||
const update = JSON.parse(msg.payload)
|
||||
|
||||
await clickhouse.insert('market_updates', [
|
||||
{
|
||||
market_id: update.id,
|
||||
event_type: update.operation, // INSERT, UPDATE, DELETE
|
||||
timestamp: new Date(),
|
||||
data: JSON.stringify(update.new_data)
|
||||
}
|
||||
])
|
||||
})
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Partitioning Strategy
|
||||
- Partition by time (usually month or day)
|
||||
- Avoid too many partitions (performance impact)
|
||||
- Use DATE type for partition key
|
||||
|
||||
### 2. Ordering Key
|
||||
- Put most frequently filtered columns first
|
||||
- Consider cardinality (high cardinality first)
|
||||
- Order impacts compression
|
||||
|
||||
### 3. Data Types
|
||||
- Use smallest appropriate type (UInt32 vs UInt64)
|
||||
- Use LowCardinality for repeated strings
|
||||
- Use Enum for categorical data
|
||||
|
||||
### 4. Avoid
|
||||
- SELECT * (specify columns)
|
||||
- FINAL (merge data before query instead)
|
||||
- Too many JOINs (denormalize for analytics)
|
||||
- Small frequent inserts (batch instead)
|
||||
|
||||
### 5. Monitoring
|
||||
- Track query performance
|
||||
- Monitor disk usage
|
||||
- Check merge operations
|
||||
- Review slow query log
|
||||
|
||||
**Remember**: ClickHouse excels at analytical workloads. Design tables for your query patterns, batch inserts, and leverage materialized views for real-time aggregations.
|
||||
522
skills/cc-skill-coding-standards/SKILL.md
Normal file
522
skills/cc-skill-coding-standards/SKILL.md
Normal file
@@ -0,0 +1,522 @@
|
||||
---
|
||||
name: coding-standards
|
||||
description: Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Coding Standards & Best Practices
|
||||
|
||||
Universal coding standards applicable across all projects.
|
||||
|
||||
## Code Quality Principles
|
||||
|
||||
### 1. Readability First
|
||||
- Code is read more than written
|
||||
- Clear variable and function names
|
||||
- Self-documenting code preferred over comments
|
||||
- Consistent formatting
|
||||
|
||||
### 2. KISS (Keep It Simple, Stupid)
|
||||
- Simplest solution that works
|
||||
- Avoid over-engineering
|
||||
- No premature optimization
|
||||
- Easy to understand > clever code
|
||||
|
||||
### 3. DRY (Don't Repeat Yourself)
|
||||
- Extract common logic into functions
|
||||
- Create reusable components
|
||||
- Share utilities across modules
|
||||
- Avoid copy-paste programming
|
||||
|
||||
### 4. YAGNI (You Aren't Gonna Need It)
|
||||
- Don't build features before they're needed
|
||||
- Avoid speculative generality
|
||||
- Add complexity only when required
|
||||
- Start simple, refactor when needed
|
||||
|
||||
## TypeScript/JavaScript Standards
|
||||
|
||||
### Variable Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive names
|
||||
const marketSearchQuery = 'election'
|
||||
const isUserAuthenticated = true
|
||||
const totalRevenue = 1000
|
||||
|
||||
// ❌ BAD: Unclear names
|
||||
const q = 'election'
|
||||
const flag = true
|
||||
const x = 1000
|
||||
```
|
||||
|
||||
### Function Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Verb-noun pattern
|
||||
async function fetchMarketData(marketId: string) { }
|
||||
function calculateSimilarity(a: number[], b: number[]) { }
|
||||
function isValidEmail(email: string): boolean { }
|
||||
|
||||
// ❌ BAD: Unclear or noun-only
|
||||
async function market(id: string) { }
|
||||
function similarity(a, b) { }
|
||||
function email(e) { }
|
||||
```
|
||||
|
||||
### Immutability Pattern (CRITICAL)
|
||||
|
||||
```typescript
|
||||
// ✅ ALWAYS use spread operator
|
||||
const updatedUser = {
|
||||
...user,
|
||||
name: 'New Name'
|
||||
}
|
||||
|
||||
const updatedArray = [...items, newItem]
|
||||
|
||||
// ❌ NEVER mutate directly
|
||||
user.name = 'New Name' // BAD
|
||||
items.push(newItem) // BAD
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Comprehensive error handling
|
||||
async function fetchData(url: string) {
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
console.error('Fetch failed:', error)
|
||||
throw new Error('Failed to fetch data')
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ BAD: No error handling
|
||||
async function fetchData(url) {
|
||||
const response = await fetch(url)
|
||||
return response.json()
|
||||
}
|
||||
```
|
||||
|
||||
### Async/Await Best Practices
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Parallel execution when possible
|
||||
const [users, markets, stats] = await Promise.all([
|
||||
fetchUsers(),
|
||||
fetchMarkets(),
|
||||
fetchStats()
|
||||
])
|
||||
|
||||
// ❌ BAD: Sequential when unnecessary
|
||||
const users = await fetchUsers()
|
||||
const markets = await fetchMarkets()
|
||||
const stats = await fetchStats()
|
||||
```
|
||||
|
||||
### Type Safety
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper types
|
||||
interface Market {
|
||||
id: string
|
||||
name: string
|
||||
status: 'active' | 'resolved' | 'closed'
|
||||
created_at: Date
|
||||
}
|
||||
|
||||
function getMarket(id: string): Promise<Market> {
|
||||
// Implementation
|
||||
}
|
||||
|
||||
// ❌ BAD: Using 'any'
|
||||
function getMarket(id: any): Promise<any> {
|
||||
// Implementation
|
||||
}
|
||||
```
|
||||
|
||||
## React Best Practices
|
||||
|
||||
### Component Structure
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Functional component with types
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode
|
||||
onClick: () => void
|
||||
disabled?: boolean
|
||||
variant?: 'primary' | 'secondary'
|
||||
}
|
||||
|
||||
export function Button({
|
||||
children,
|
||||
onClick,
|
||||
disabled = false,
|
||||
variant = 'primary'
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
className={`btn btn-${variant}`}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
// ❌ BAD: No types, unclear structure
|
||||
export function Button(props) {
|
||||
return <button onClick={props.onClick}>{props.children}</button>
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Hooks
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Reusable custom hook
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedValue(value)
|
||||
}, delay)
|
||||
|
||||
return () => clearTimeout(handler)
|
||||
}, [value, delay])
|
||||
|
||||
return debouncedValue
|
||||
}
|
||||
|
||||
// Usage
|
||||
const debouncedQuery = useDebounce(searchQuery, 500)
|
||||
```
|
||||
|
||||
### State Management
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper state updates
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
// Functional update for state based on previous state
|
||||
setCount(prev => prev + 1)
|
||||
|
||||
// ❌ BAD: Direct state reference
|
||||
setCount(count + 1) // Can be stale in async scenarios
|
||||
```
|
||||
|
||||
### Conditional Rendering
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Clear conditional rendering
|
||||
{isLoading && <Spinner />}
|
||||
{error && <ErrorMessage error={error} />}
|
||||
{data && <DataDisplay data={data} />}
|
||||
|
||||
// ❌ BAD: Ternary hell
|
||||
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
|
||||
```
|
||||
|
||||
## API Design Standards
|
||||
|
||||
### REST API Conventions
|
||||
|
||||
```
|
||||
GET /api/markets # List all markets
|
||||
GET /api/markets/:id # Get specific market
|
||||
POST /api/markets # Create new market
|
||||
PUT /api/markets/:id # Update market (full)
|
||||
PATCH /api/markets/:id # Update market (partial)
|
||||
DELETE /api/markets/:id # Delete market
|
||||
|
||||
# Query parameters for filtering
|
||||
GET /api/markets?status=active&limit=10&offset=0
|
||||
```
|
||||
|
||||
### Response Format
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Consistent response structure
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
error?: string
|
||||
meta?: {
|
||||
total: number
|
||||
page: number
|
||||
limit: number
|
||||
}
|
||||
}
|
||||
|
||||
// Success response
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: markets,
|
||||
meta: { total: 100, page: 1, limit: 10 }
|
||||
})
|
||||
|
||||
// Error response
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Invalid request'
|
||||
}, { status: 400 })
|
||||
```
|
||||
|
||||
### Input Validation
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// ✅ GOOD: Schema validation
|
||||
const CreateMarketSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
description: z.string().min(1).max(2000),
|
||||
endDate: z.string().datetime(),
|
||||
categories: z.array(z.string()).min(1)
|
||||
})
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const body = await request.json()
|
||||
|
||||
try {
|
||||
const validated = CreateMarketSchema.parse(body)
|
||||
// Proceed with validated data
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors
|
||||
}, { status: 400 })
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## File Organization
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── app/ # Next.js App Router
|
||||
│ ├── api/ # API routes
|
||||
│ ├── markets/ # Market pages
|
||||
│ └── (auth)/ # Auth pages (route groups)
|
||||
├── components/ # React components
|
||||
│ ├── ui/ # Generic UI components
|
||||
│ ├── forms/ # Form components
|
||||
│ └── layouts/ # Layout components
|
||||
├── hooks/ # Custom React hooks
|
||||
├── lib/ # Utilities and configs
|
||||
│ ├── api/ # API clients
|
||||
│ ├── utils/ # Helper functions
|
||||
│ └── constants/ # Constants
|
||||
├── types/ # TypeScript types
|
||||
└── styles/ # Global styles
|
||||
```
|
||||
|
||||
### File Naming
|
||||
|
||||
```
|
||||
components/Button.tsx # PascalCase for components
|
||||
hooks/useAuth.ts # camelCase with 'use' prefix
|
||||
lib/formatDate.ts # camelCase for utilities
|
||||
types/market.types.ts # camelCase with .types suffix
|
||||
```
|
||||
|
||||
## Comments & Documentation
|
||||
|
||||
### When to Comment
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Explain WHY, not WHAT
|
||||
// Use exponential backoff to avoid overwhelming the API during outages
|
||||
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
|
||||
|
||||
// Deliberately using mutation here for performance with large arrays
|
||||
items.push(newItem)
|
||||
|
||||
// ❌ BAD: Stating the obvious
|
||||
// Increment counter by 1
|
||||
count++
|
||||
|
||||
// Set name to user's name
|
||||
name = user.name
|
||||
```
|
||||
|
||||
### JSDoc for Public APIs
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Searches markets using semantic similarity.
|
||||
*
|
||||
* @param query - Natural language search query
|
||||
* @param limit - Maximum number of results (default: 10)
|
||||
* @returns Array of markets sorted by similarity score
|
||||
* @throws {Error} If OpenAI API fails or Redis unavailable
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const results = await searchMarkets('election', 5)
|
||||
* console.log(results[0].name) // "Trump vs Biden"
|
||||
* ```
|
||||
*/
|
||||
export async function searchMarkets(
|
||||
query: string,
|
||||
limit: number = 10
|
||||
): Promise<Market[]> {
|
||||
// Implementation
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Best Practices
|
||||
|
||||
### Memoization
|
||||
|
||||
```typescript
|
||||
import { useMemo, useCallback } from 'react'
|
||||
|
||||
// ✅ GOOD: Memoize expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ GOOD: Memoize callbacks
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
```
|
||||
|
||||
### Lazy Loading
|
||||
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ GOOD: Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
|
||||
export function Dashboard() {
|
||||
return (
|
||||
<Suspense fallback={<Spinner />}>
|
||||
<HeavyChart />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Database Queries
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status')
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
```
|
||||
|
||||
## Testing Standards
|
||||
|
||||
### Test Structure (AAA Pattern)
|
||||
|
||||
```typescript
|
||||
test('calculates similarity correctly', () => {
|
||||
// Arrange
|
||||
const vector1 = [1, 0, 0]
|
||||
const vector2 = [0, 1, 0]
|
||||
|
||||
// Act
|
||||
const similarity = calculateCosineSimilarity(vector1, vector2)
|
||||
|
||||
// Assert
|
||||
expect(similarity).toBe(0)
|
||||
})
|
||||
```
|
||||
|
||||
### Test Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive test names
|
||||
test('returns empty array when no markets match query', () => { })
|
||||
test('throws error when OpenAI API key is missing', () => { })
|
||||
test('falls back to substring search when Redis unavailable', () => { })
|
||||
|
||||
// ❌ BAD: Vague test names
|
||||
test('works', () => { })
|
||||
test('test search', () => { })
|
||||
```
|
||||
|
||||
## Code Smell Detection
|
||||
|
||||
Watch for these anti-patterns:
|
||||
|
||||
### 1. Long Functions
|
||||
```typescript
|
||||
// ❌ BAD: Function > 50 lines
|
||||
function processMarketData() {
|
||||
// 100 lines of code
|
||||
}
|
||||
|
||||
// ✅ GOOD: Split into smaller functions
|
||||
function processMarketData() {
|
||||
const validated = validateData()
|
||||
const transformed = transformData(validated)
|
||||
return saveData(transformed)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Deep Nesting
|
||||
```typescript
|
||||
// ❌ BAD: 5+ levels of nesting
|
||||
if (user) {
|
||||
if (user.isAdmin) {
|
||||
if (market) {
|
||||
if (market.isActive) {
|
||||
if (hasPermission) {
|
||||
// Do something
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ GOOD: Early returns
|
||||
if (!user) return
|
||||
if (!user.isAdmin) return
|
||||
if (!market) return
|
||||
if (!market.isActive) return
|
||||
if (!hasPermission) return
|
||||
|
||||
// Do something
|
||||
```
|
||||
|
||||
### 3. Magic Numbers
|
||||
```typescript
|
||||
// ❌ BAD: Unexplained numbers
|
||||
if (retryCount > 3) { }
|
||||
setTimeout(callback, 500)
|
||||
|
||||
// ✅ GOOD: Named constants
|
||||
const MAX_RETRIES = 3
|
||||
const DEBOUNCE_DELAY_MS = 500
|
||||
|
||||
if (retryCount > MAX_RETRIES) { }
|
||||
setTimeout(callback, DEBOUNCE_DELAY_MS)
|
||||
```
|
||||
|
||||
**Remember**: Code quality is not negotiable. Clear, maintainable code enables rapid development and confident refactoring.
|
||||
10
skills/cc-skill-continuous-learning/SKILL.md
Normal file
10
skills/cc-skill-continuous-learning/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: cc-skill-continuous-learning
|
||||
description: Development skill from everything-claude-code
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# cc-skill-continuous-learning
|
||||
|
||||
Development skill skill.
|
||||
18
skills/cc-skill-continuous-learning/config.json
Normal file
18
skills/cc-skill-continuous-learning/config.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"min_session_length": 10,
|
||||
"extraction_threshold": "medium",
|
||||
"auto_approve": false,
|
||||
"learned_skills_path": "~/.claude/skills/learned/",
|
||||
"patterns_to_detect": [
|
||||
"error_resolution",
|
||||
"user_corrections",
|
||||
"workarounds",
|
||||
"debugging_techniques",
|
||||
"project_specific"
|
||||
],
|
||||
"ignore_patterns": [
|
||||
"simple_typos",
|
||||
"one_time_fixes",
|
||||
"external_api_issues"
|
||||
]
|
||||
}
|
||||
60
skills/cc-skill-continuous-learning/evaluate-session.sh
Executable file
60
skills/cc-skill-continuous-learning/evaluate-session.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
# Continuous Learning - Session Evaluator
|
||||
# Runs on Stop hook to extract reusable patterns from Claude Code sessions
|
||||
#
|
||||
# Why Stop hook instead of UserPromptSubmit:
|
||||
# - Stop runs once at session end (lightweight)
|
||||
# - UserPromptSubmit runs every message (heavy, adds latency)
|
||||
#
|
||||
# Hook config (in ~/.claude/settings.json):
|
||||
# {
|
||||
# "hooks": {
|
||||
# "Stop": [{
|
||||
# "matcher": "*",
|
||||
# "hooks": [{
|
||||
# "type": "command",
|
||||
# "command": "~/.claude/skills/continuous-learning/evaluate-session.sh"
|
||||
# }]
|
||||
# }]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# Patterns to detect: error_resolution, debugging_techniques, workarounds, project_specific
|
||||
# Patterns to ignore: simple_typos, one_time_fixes, external_api_issues
|
||||
# Extracted skills saved to: ~/.claude/skills/learned/
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="$SCRIPT_DIR/config.json"
|
||||
LEARNED_SKILLS_PATH="${HOME}/.claude/skills/learned"
|
||||
MIN_SESSION_LENGTH=10
|
||||
|
||||
# Load config if exists
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
MIN_SESSION_LENGTH=$(jq -r '.min_session_length // 10' "$CONFIG_FILE")
|
||||
LEARNED_SKILLS_PATH=$(jq -r '.learned_skills_path // "~/.claude/skills/learned/"' "$CONFIG_FILE" | sed "s|~|$HOME|")
|
||||
fi
|
||||
|
||||
# Ensure learned skills directory exists
|
||||
mkdir -p "$LEARNED_SKILLS_PATH"
|
||||
|
||||
# Get transcript path from environment (set by Claude Code)
|
||||
transcript_path="${CLAUDE_TRANSCRIPT_PATH:-}"
|
||||
|
||||
if [ -z "$transcript_path" ] || [ ! -f "$transcript_path" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Count messages in session
|
||||
message_count=$(grep -c '"type":"user"' "$transcript_path" 2>/dev/null || echo "0")
|
||||
|
||||
# Skip short sessions
|
||||
if [ "$message_count" -lt "$MIN_SESSION_LENGTH" ]; then
|
||||
echo "[ContinuousLearning] Session too short ($message_count messages), skipping" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Signal to Claude that session should be evaluated for extractable patterns
|
||||
echo "[ContinuousLearning] Session has $message_count messages - evaluate for extractable patterns" >&2
|
||||
echo "[ContinuousLearning] Save learned skills to: $LEARNED_SKILLS_PATH" >&2
|
||||
633
skills/cc-skill-frontend-patterns/SKILL.md
Normal file
633
skills/cc-skill-frontend-patterns/SKILL.md
Normal file
@@ -0,0 +1,633 @@
|
||||
---
|
||||
name: frontend-patterns
|
||||
description: Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Frontend Development Patterns
|
||||
|
||||
Modern frontend patterns for React, Next.js, and performant user interfaces.
|
||||
|
||||
## Component Patterns
|
||||
|
||||
### Composition Over Inheritance
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Component composition
|
||||
interface CardProps {
|
||||
children: React.ReactNode
|
||||
variant?: 'default' | 'outlined'
|
||||
}
|
||||
|
||||
export function Card({ children, variant = 'default' }: CardProps) {
|
||||
return <div className={`card card-${variant}`}>{children}</div>
|
||||
}
|
||||
|
||||
export function CardHeader({ children }: { children: React.ReactNode }) {
|
||||
return <div className="card-header">{children}</div>
|
||||
}
|
||||
|
||||
export function CardBody({ children }: { children: React.ReactNode }) {
|
||||
return <div className="card-body">{children}</div>
|
||||
}
|
||||
|
||||
// Usage
|
||||
<Card>
|
||||
<CardHeader>Title</CardHeader>
|
||||
<CardBody>Content</CardBody>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### Compound Components
|
||||
|
||||
```typescript
|
||||
interface TabsContextValue {
|
||||
activeTab: string
|
||||
setActiveTab: (tab: string) => void
|
||||
}
|
||||
|
||||
const TabsContext = createContext<TabsContextValue | undefined>(undefined)
|
||||
|
||||
export function Tabs({ children, defaultTab }: {
|
||||
children: React.ReactNode
|
||||
defaultTab: string
|
||||
}) {
|
||||
const [activeTab, setActiveTab] = useState(defaultTab)
|
||||
|
||||
return (
|
||||
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
|
||||
{children}
|
||||
</TabsContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function TabList({ children }: { children: React.ReactNode }) {
|
||||
return <div className="tab-list">{children}</div>
|
||||
}
|
||||
|
||||
export function Tab({ id, children }: { id: string, children: React.ReactNode }) {
|
||||
const context = useContext(TabsContext)
|
||||
if (!context) throw new Error('Tab must be used within Tabs')
|
||||
|
||||
return (
|
||||
<button
|
||||
className={context.activeTab === id ? 'active' : ''}
|
||||
onClick={() => context.setActiveTab(id)}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
// Usage
|
||||
<Tabs defaultTab="overview">
|
||||
<TabList>
|
||||
<Tab id="overview">Overview</Tab>
|
||||
<Tab id="details">Details</Tab>
|
||||
</TabList>
|
||||
</Tabs>
|
||||
```
|
||||
|
||||
### Render Props Pattern
|
||||
|
||||
```typescript
|
||||
interface DataLoaderProps<T> {
|
||||
url: string
|
||||
children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode
|
||||
}
|
||||
|
||||
export function DataLoader<T>({ url, children }: DataLoaderProps<T>) {
|
||||
const [data, setData] = useState<T | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
fetch(url)
|
||||
.then(res => res.json())
|
||||
.then(setData)
|
||||
.catch(setError)
|
||||
.finally(() => setLoading(false))
|
||||
}, [url])
|
||||
|
||||
return <>{children(data, loading, error)}</>
|
||||
}
|
||||
|
||||
// Usage
|
||||
<DataLoader<Market[]> url="/api/markets">
|
||||
{(markets, loading, error) => {
|
||||
if (loading) return <Spinner />
|
||||
if (error) return <Error error={error} />
|
||||
return <MarketList markets={markets!} />
|
||||
}}
|
||||
</DataLoader>
|
||||
```
|
||||
|
||||
## Custom Hooks Patterns
|
||||
|
||||
### State Management Hook
|
||||
|
||||
```typescript
|
||||
export function useToggle(initialValue = false): [boolean, () => void] {
|
||||
const [value, setValue] = useState(initialValue)
|
||||
|
||||
const toggle = useCallback(() => {
|
||||
setValue(v => !v)
|
||||
}, [])
|
||||
|
||||
return [value, toggle]
|
||||
}
|
||||
|
||||
// Usage
|
||||
const [isOpen, toggleOpen] = useToggle()
|
||||
```
|
||||
|
||||
### Async Data Fetching Hook
|
||||
|
||||
```typescript
|
||||
interface UseQueryOptions<T> {
|
||||
onSuccess?: (data: T) => void
|
||||
onError?: (error: Error) => void
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export function useQuery<T>(
|
||||
key: string,
|
||||
fetcher: () => Promise<T>,
|
||||
options?: UseQueryOptions<T>
|
||||
) {
|
||||
const [data, setData] = useState<T | null>(null)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const refetch = useCallback(async () => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const result = await fetcher()
|
||||
setData(result)
|
||||
options?.onSuccess?.(result)
|
||||
} catch (err) {
|
||||
const error = err as Error
|
||||
setError(error)
|
||||
options?.onError?.(error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [fetcher, options])
|
||||
|
||||
useEffect(() => {
|
||||
if (options?.enabled !== false) {
|
||||
refetch()
|
||||
}
|
||||
}, [key, refetch, options?.enabled])
|
||||
|
||||
return { data, error, loading, refetch }
|
||||
}
|
||||
|
||||
// Usage
|
||||
const { data: markets, loading, error, refetch } = useQuery(
|
||||
'markets',
|
||||
() => fetch('/api/markets').then(r => r.json()),
|
||||
{
|
||||
onSuccess: data => console.log('Fetched', data.length, 'markets'),
|
||||
onError: err => console.error('Failed:', err)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Debounce Hook
|
||||
|
||||
```typescript
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedValue(value)
|
||||
}, delay)
|
||||
|
||||
return () => clearTimeout(handler)
|
||||
}, [value, delay])
|
||||
|
||||
return debouncedValue
|
||||
}
|
||||
|
||||
// Usage
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const debouncedQuery = useDebounce(searchQuery, 500)
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedQuery) {
|
||||
performSearch(debouncedQuery)
|
||||
}
|
||||
}, [debouncedQuery])
|
||||
```
|
||||
|
||||
## State Management Patterns
|
||||
|
||||
### Context + Reducer Pattern
|
||||
|
||||
```typescript
|
||||
interface State {
|
||||
markets: Market[]
|
||||
selectedMarket: Market | null
|
||||
loading: boolean
|
||||
}
|
||||
|
||||
type Action =
|
||||
| { type: 'SET_MARKETS'; payload: Market[] }
|
||||
| { type: 'SELECT_MARKET'; payload: Market }
|
||||
| { type: 'SET_LOADING'; payload: boolean }
|
||||
|
||||
function reducer(state: State, action: Action): State {
|
||||
switch (action.type) {
|
||||
case 'SET_MARKETS':
|
||||
return { ...state, markets: action.payload }
|
||||
case 'SELECT_MARKET':
|
||||
return { ...state, selectedMarket: action.payload }
|
||||
case 'SET_LOADING':
|
||||
return { ...state, loading: action.payload }
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
const MarketContext = createContext<{
|
||||
state: State
|
||||
dispatch: Dispatch<Action>
|
||||
} | undefined>(undefined)
|
||||
|
||||
export function MarketProvider({ children }: { children: React.ReactNode }) {
|
||||
const [state, dispatch] = useReducer(reducer, {
|
||||
markets: [],
|
||||
selectedMarket: null,
|
||||
loading: false
|
||||
})
|
||||
|
||||
return (
|
||||
<MarketContext.Provider value={{ state, dispatch }}>
|
||||
{children}
|
||||
</MarketContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useMarkets() {
|
||||
const context = useContext(MarketContext)
|
||||
if (!context) throw new Error('useMarkets must be used within MarketProvider')
|
||||
return context
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Memoization
|
||||
|
||||
```typescript
|
||||
// ✅ useMemo for expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ useCallback for functions passed to children
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
|
||||
// ✅ React.memo for pure components
|
||||
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
return (
|
||||
<div className="market-card">
|
||||
<h3>{market.name}</h3>
|
||||
<p>{market.description}</p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
```
|
||||
|
||||
### Code Splitting & Lazy Loading
|
||||
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
|
||||
|
||||
export function Dashboard() {
|
||||
return (
|
||||
<div>
|
||||
<Suspense fallback={<ChartSkeleton />}>
|
||||
<HeavyChart data={data} />
|
||||
</Suspense>
|
||||
|
||||
<Suspense fallback={null}>
|
||||
<ThreeJsBackground />
|
||||
</Suspense>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Virtualization for Long Lists
|
||||
|
||||
```typescript
|
||||
import { useVirtualizer } from '@tanstack/react-virtual'
|
||||
|
||||
export function VirtualMarketList({ markets }: { markets: Market[] }) {
|
||||
const parentRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const virtualizer = useVirtualizer({
|
||||
count: markets.length,
|
||||
getScrollElement: () => parentRef.current,
|
||||
estimateSize: () => 100, // Estimated row height
|
||||
overscan: 5 // Extra items to render
|
||||
})
|
||||
|
||||
return (
|
||||
<div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}>
|
||||
<div
|
||||
style={{
|
||||
height: `${virtualizer.getTotalSize()}px`,
|
||||
position: 'relative'
|
||||
}}
|
||||
>
|
||||
{virtualizer.getVirtualItems().map(virtualRow => (
|
||||
<div
|
||||
key={virtualRow.index}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: `${virtualRow.size}px`,
|
||||
transform: `translateY(${virtualRow.start}px)`
|
||||
}}
|
||||
>
|
||||
<MarketCard market={markets[virtualRow.index]} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Form Handling Patterns
|
||||
|
||||
### Controlled Form with Validation
|
||||
|
||||
```typescript
|
||||
interface FormData {
|
||||
name: string
|
||||
description: string
|
||||
endDate: string
|
||||
}
|
||||
|
||||
interface FormErrors {
|
||||
name?: string
|
||||
description?: string
|
||||
endDate?: string
|
||||
}
|
||||
|
||||
export function CreateMarketForm() {
|
||||
const [formData, setFormData] = useState<FormData>({
|
||||
name: '',
|
||||
description: '',
|
||||
endDate: ''
|
||||
})
|
||||
|
||||
const [errors, setErrors] = useState<FormErrors>({})
|
||||
|
||||
const validate = (): boolean => {
|
||||
const newErrors: FormErrors = {}
|
||||
|
||||
if (!formData.name.trim()) {
|
||||
newErrors.name = 'Name is required'
|
||||
} else if (formData.name.length > 200) {
|
||||
newErrors.name = 'Name must be under 200 characters'
|
||||
}
|
||||
|
||||
if (!formData.description.trim()) {
|
||||
newErrors.description = 'Description is required'
|
||||
}
|
||||
|
||||
if (!formData.endDate) {
|
||||
newErrors.endDate = 'End date is required'
|
||||
}
|
||||
|
||||
setErrors(newErrors)
|
||||
return Object.keys(newErrors).length === 0
|
||||
}
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (!validate()) return
|
||||
|
||||
try {
|
||||
await createMarket(formData)
|
||||
// Success handling
|
||||
} catch (error) {
|
||||
// Error handling
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<input
|
||||
value={formData.name}
|
||||
onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}
|
||||
placeholder="Market name"
|
||||
/>
|
||||
{errors.name && <span className="error">{errors.name}</span>}
|
||||
|
||||
{/* Other fields */}
|
||||
|
||||
<button type="submit">Create Market</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Error Boundary Pattern
|
||||
|
||||
```typescript
|
||||
interface ErrorBoundaryState {
|
||||
hasError: boolean
|
||||
error: Error | null
|
||||
}
|
||||
|
||||
export class ErrorBoundary extends React.Component<
|
||||
{ children: React.ReactNode },
|
||||
ErrorBoundaryState
|
||||
> {
|
||||
state: ErrorBoundaryState = {
|
||||
hasError: false,
|
||||
error: null
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
||||
return { hasError: true, error }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
||||
console.error('Error boundary caught:', error, errorInfo)
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div className="error-fallback">
|
||||
<h2>Something went wrong</h2>
|
||||
<p>{this.state.error?.message}</p>
|
||||
<button onClick={() => this.setState({ hasError: false })}>
|
||||
Try again
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return this.props.children
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
<ErrorBoundary>
|
||||
<App />
|
||||
</ErrorBoundary>
|
||||
```
|
||||
|
||||
## Animation Patterns
|
||||
|
||||
### Framer Motion Animations
|
||||
|
||||
```typescript
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
|
||||
// ✅ List animations
|
||||
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{markets.map(market => (
|
||||
<motion.div
|
||||
key={market.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<MarketCard market={market} />
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ Modal animations
|
||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
<>
|
||||
<motion.div
|
||||
className="modal-overlay"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={onClose}
|
||||
/>
|
||||
<motion.div
|
||||
className="modal-content"
|
||||
initial={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Accessibility Patterns
|
||||
|
||||
### Keyboard Navigation
|
||||
|
||||
```typescript
|
||||
export function Dropdown({ options, onSelect }: DropdownProps) {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [activeIndex, setActiveIndex] = useState(0)
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||
switch (e.key) {
|
||||
case 'ArrowDown':
|
||||
e.preventDefault()
|
||||
setActiveIndex(i => Math.min(i + 1, options.length - 1))
|
||||
break
|
||||
case 'ArrowUp':
|
||||
e.preventDefault()
|
||||
setActiveIndex(i => Math.max(i - 1, 0))
|
||||
break
|
||||
case 'Enter':
|
||||
e.preventDefault()
|
||||
onSelect(options[activeIndex])
|
||||
setIsOpen(false)
|
||||
break
|
||||
case 'Escape':
|
||||
setIsOpen(false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role="combobox"
|
||||
aria-expanded={isOpen}
|
||||
aria-haspopup="listbox"
|
||||
onKeyDown={handleKeyDown}
|
||||
>
|
||||
{/* Dropdown implementation */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Focus Management
|
||||
|
||||
```typescript
|
||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||
const modalRef = useRef<HTMLDivElement>(null)
|
||||
const previousFocusRef = useRef<HTMLElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
// Save currently focused element
|
||||
previousFocusRef.current = document.activeElement as HTMLElement
|
||||
|
||||
// Focus modal
|
||||
modalRef.current?.focus()
|
||||
} else {
|
||||
// Restore focus when closing
|
||||
previousFocusRef.current?.focus()
|
||||
}
|
||||
}, [isOpen])
|
||||
|
||||
return isOpen ? (
|
||||
<div
|
||||
ref={modalRef}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
tabIndex={-1}
|
||||
onKeyDown={e => e.key === 'Escape' && onClose()}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
```
|
||||
|
||||
**Remember**: Modern frontend patterns enable maintainable, performant user interfaces. Choose patterns that fit your project complexity.
|
||||
352
skills/cc-skill-project-guidelines-example/SKILL.md
Normal file
352
skills/cc-skill-project-guidelines-example/SKILL.md
Normal file
@@ -0,0 +1,352 @@
|
||||
---
|
||||
name: cc-skill-project-guidelines-example
|
||||
description: Project Guidelines Skill (Example)
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Project Guidelines Skill (Example)
|
||||
|
||||
This is an example of a project-specific skill. Use this as a template for your own projects.
|
||||
|
||||
Based on a real production application: [Zenith](https://zenith.chat) - AI-powered customer discovery platform.
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
Reference this skill when working on the specific project it's designed for. Project skills contain:
|
||||
- Architecture overview
|
||||
- File structure
|
||||
- Code patterns
|
||||
- Testing requirements
|
||||
- Deployment workflow
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
**Tech Stack:**
|
||||
- **Frontend**: Next.js 15 (App Router), TypeScript, React
|
||||
- **Backend**: FastAPI (Python), Pydantic models
|
||||
- **Database**: Supabase (PostgreSQL)
|
||||
- **AI**: Claude API with tool calling and structured output
|
||||
- **Deployment**: Google Cloud Run
|
||||
- **Testing**: Playwright (E2E), pytest (backend), React Testing Library
|
||||
|
||||
**Services:**
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Frontend │
|
||||
│ Next.js 15 + TypeScript + TailwindCSS │
|
||||
│ Deployed: Vercel / Cloud Run │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Backend │
|
||||
│ FastAPI + Python 3.11 + Pydantic │
|
||||
│ Deployed: Cloud Run │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┼───────────────┐
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ Supabase │ │ Claude │ │ Redis │
|
||||
│ Database │ │ API │ │ Cache │
|
||||
└──────────┘ └──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
project/
|
||||
├── frontend/
|
||||
│ └── src/
|
||||
│ ├── app/ # Next.js app router pages
|
||||
│ │ ├── api/ # API routes
|
||||
│ │ ├── (auth)/ # Auth-protected routes
|
||||
│ │ └── workspace/ # Main app workspace
|
||||
│ ├── components/ # React components
|
||||
│ │ ├── ui/ # Base UI components
|
||||
│ │ ├── forms/ # Form components
|
||||
│ │ └── layouts/ # Layout components
|
||||
│ ├── hooks/ # Custom React hooks
|
||||
│ ├── lib/ # Utilities
|
||||
│ ├── types/ # TypeScript definitions
|
||||
│ └── config/ # Configuration
|
||||
│
|
||||
├── backend/
|
||||
│ ├── routers/ # FastAPI route handlers
|
||||
│ ├── models.py # Pydantic models
|
||||
│ ├── main.py # FastAPI app entry
|
||||
│ ├── auth_system.py # Authentication
|
||||
│ ├── database.py # Database operations
|
||||
│ ├── services/ # Business logic
|
||||
│ └── tests/ # pytest tests
|
||||
│
|
||||
├── deploy/ # Deployment configs
|
||||
├── docs/ # Documentation
|
||||
└── scripts/ # Utility scripts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Code Patterns
|
||||
|
||||
### API Response Format (FastAPI)
|
||||
|
||||
```python
|
||||
from pydantic import BaseModel
|
||||
from typing import Generic, TypeVar, Optional
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
class ApiResponse(BaseModel, Generic[T]):
|
||||
success: bool
|
||||
data: Optional[T] = None
|
||||
error: Optional[str] = None
|
||||
|
||||
@classmethod
|
||||
def ok(cls, data: T) -> "ApiResponse[T]":
|
||||
return cls(success=True, data=data)
|
||||
|
||||
@classmethod
|
||||
def fail(cls, error: str) -> "ApiResponse[T]":
|
||||
return cls(success=False, error=error)
|
||||
```
|
||||
|
||||
### Frontend API Calls (TypeScript)
|
||||
|
||||
```typescript
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
error?: string
|
||||
}
|
||||
|
||||
async function fetchApi<T>(
|
||||
endpoint: string,
|
||||
options?: RequestInit
|
||||
): Promise<ApiResponse<T>> {
|
||||
try {
|
||||
const response = await fetch(`/api${endpoint}`, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options?.headers,
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
return { success: false, error: `HTTP ${response.status}` }
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
return { success: false, error: String(error) }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Claude AI Integration (Structured Output)
|
||||
|
||||
```python
|
||||
from anthropic import Anthropic
|
||||
from pydantic import BaseModel
|
||||
|
||||
class AnalysisResult(BaseModel):
|
||||
summary: str
|
||||
key_points: list[str]
|
||||
confidence: float
|
||||
|
||||
async def analyze_with_claude(content: str) -> AnalysisResult:
|
||||
client = Anthropic()
|
||||
|
||||
response = client.messages.create(
|
||||
model="claude-sonnet-4-5-20250514",
|
||||
max_tokens=1024,
|
||||
messages=[{"role": "user", "content": content}],
|
||||
tools=[{
|
||||
"name": "provide_analysis",
|
||||
"description": "Provide structured analysis",
|
||||
"input_schema": AnalysisResult.model_json_schema()
|
||||
}],
|
||||
tool_choice={"type": "tool", "name": "provide_analysis"}
|
||||
)
|
||||
|
||||
# Extract tool use result
|
||||
tool_use = next(
|
||||
block for block in response.content
|
||||
if block.type == "tool_use"
|
||||
)
|
||||
|
||||
return AnalysisResult(**tool_use.input)
|
||||
```
|
||||
|
||||
### Custom Hooks (React)
|
||||
|
||||
```typescript
|
||||
import { useState, useCallback } from 'react'
|
||||
|
||||
interface UseApiState<T> {
|
||||
data: T | null
|
||||
loading: boolean
|
||||
error: string | null
|
||||
}
|
||||
|
||||
export function useApi<T>(
|
||||
fetchFn: () => Promise<ApiResponse<T>>
|
||||
) {
|
||||
const [state, setState] = useState<UseApiState<T>>({
|
||||
data: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
})
|
||||
|
||||
const execute = useCallback(async () => {
|
||||
setState(prev => ({ ...prev, loading: true, error: null }))
|
||||
|
||||
const result = await fetchFn()
|
||||
|
||||
if (result.success) {
|
||||
setState({ data: result.data!, loading: false, error: null })
|
||||
} else {
|
||||
setState({ data: null, loading: false, error: result.error! })
|
||||
}
|
||||
}, [fetchFn])
|
||||
|
||||
return { ...state, execute }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
### Backend (pytest)
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
poetry run pytest tests/
|
||||
|
||||
# Run with coverage
|
||||
poetry run pytest tests/ --cov=. --cov-report=html
|
||||
|
||||
# Run specific test file
|
||||
poetry run pytest tests/test_auth.py -v
|
||||
```
|
||||
|
||||
**Test structure:**
|
||||
```python
|
||||
import pytest
|
||||
from httpx import AsyncClient
|
||||
from main import app
|
||||
|
||||
@pytest.fixture
|
||||
async def client():
|
||||
async with AsyncClient(app=app, base_url="http://test") as ac:
|
||||
yield ac
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_health_check(client: AsyncClient):
|
||||
response = await client.get("/health")
|
||||
assert response.status_code == 200
|
||||
assert response.json()["status"] == "healthy"
|
||||
```
|
||||
|
||||
### Frontend (React Testing Library)
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
npm run test
|
||||
|
||||
# Run with coverage
|
||||
npm run test -- --coverage
|
||||
|
||||
# Run E2E tests
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
**Test structure:**
|
||||
```typescript
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import { WorkspacePanel } from './WorkspacePanel'
|
||||
|
||||
describe('WorkspacePanel', () => {
|
||||
it('renders workspace correctly', () => {
|
||||
render(<WorkspacePanel />)
|
||||
expect(screen.getByRole('main')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('handles session creation', async () => {
|
||||
render(<WorkspacePanel />)
|
||||
fireEvent.click(screen.getByText('New Session'))
|
||||
expect(await screen.findByText('Session created')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment Workflow
|
||||
|
||||
### Pre-Deployment Checklist
|
||||
|
||||
- [ ] All tests passing locally
|
||||
- [ ] `npm run build` succeeds (frontend)
|
||||
- [ ] `poetry run pytest` passes (backend)
|
||||
- [ ] No hardcoded secrets
|
||||
- [ ] Environment variables documented
|
||||
- [ ] Database migrations ready
|
||||
|
||||
### Deployment Commands
|
||||
|
||||
```bash
|
||||
# Build and deploy frontend
|
||||
cd frontend && npm run build
|
||||
gcloud run deploy frontend --source .
|
||||
|
||||
# Build and deploy backend
|
||||
cd backend
|
||||
gcloud run deploy backend --source .
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Frontend (.env.local)
|
||||
NEXT_PUBLIC_API_URL=https://api.example.com
|
||||
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
|
||||
|
||||
# Backend (.env)
|
||||
DATABASE_URL=postgresql://...
|
||||
ANTHROPIC_API_KEY=sk-ant-...
|
||||
SUPABASE_URL=https://xxx.supabase.co
|
||||
SUPABASE_KEY=eyJ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Critical Rules
|
||||
|
||||
1. **No emojis** in code, comments, or documentation
|
||||
2. **Immutability** - never mutate objects or arrays
|
||||
3. **TDD** - write tests before implementation
|
||||
4. **80% coverage** minimum
|
||||
5. **Many small files** - 200-400 lines typical, 800 max
|
||||
6. **No console.log** in production code
|
||||
7. **Proper error handling** with try/catch
|
||||
8. **Input validation** with Pydantic/Zod
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `coding-standards.md` - General coding best practices
|
||||
- `backend-patterns.md` - API and database patterns
|
||||
- `frontend-patterns.md` - React and Next.js patterns
|
||||
- `tdd-workflow/` - Test-driven development methodology
|
||||
496
skills/cc-skill-security-review/SKILL.md
Normal file
496
skills/cc-skill-security-review/SKILL.md
Normal file
@@ -0,0 +1,496 @@
|
||||
---
|
||||
name: security-review
|
||||
description: Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns.
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Security Review Skill
|
||||
|
||||
This skill ensures all code follows security best practices and identifies potential vulnerabilities.
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Implementing authentication or authorization
|
||||
- Handling user input or file uploads
|
||||
- Creating new API endpoints
|
||||
- Working with secrets or credentials
|
||||
- Implementing payment features
|
||||
- Storing or transmitting sensitive data
|
||||
- Integrating third-party APIs
|
||||
|
||||
## Security Checklist
|
||||
|
||||
### 1. Secrets Management
|
||||
|
||||
#### ❌ NEVER Do This
|
||||
```typescript
|
||||
const apiKey = "sk-proj-xxxxx" // Hardcoded secret
|
||||
const dbPassword = "password123" // In source code
|
||||
```
|
||||
|
||||
#### ✅ ALWAYS Do This
|
||||
```typescript
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
const dbUrl = process.env.DATABASE_URL
|
||||
|
||||
// Verify secrets exist
|
||||
if (!apiKey) {
|
||||
throw new Error('OPENAI_API_KEY not configured')
|
||||
}
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] No hardcoded API keys, tokens, or passwords
|
||||
- [ ] All secrets in environment variables
|
||||
- [ ] `.env.local` in .gitignore
|
||||
- [ ] No secrets in git history
|
||||
- [ ] Production secrets in hosting platform (Vercel, Railway)
|
||||
|
||||
### 2. Input Validation
|
||||
|
||||
#### Always Validate User Input
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// Define validation schema
|
||||
const CreateUserSchema = z.object({
|
||||
email: z.string().email(),
|
||||
name: z.string().min(1).max(100),
|
||||
age: z.number().int().min(0).max(150)
|
||||
})
|
||||
|
||||
// Validate before processing
|
||||
export async function createUser(input: unknown) {
|
||||
try {
|
||||
const validated = CreateUserSchema.parse(input)
|
||||
return await db.users.create(validated)
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return { success: false, errors: error.errors }
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### File Upload Validation
|
||||
```typescript
|
||||
function validateFileUpload(file: File) {
|
||||
// Size check (5MB max)
|
||||
const maxSize = 5 * 1024 * 1024
|
||||
if (file.size > maxSize) {
|
||||
throw new Error('File too large (max 5MB)')
|
||||
}
|
||||
|
||||
// Type check
|
||||
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
|
||||
if (!allowedTypes.includes(file.type)) {
|
||||
throw new Error('Invalid file type')
|
||||
}
|
||||
|
||||
// Extension check
|
||||
const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif']
|
||||
const extension = file.name.toLowerCase().match(/\.[^.]+$/)?.[0]
|
||||
if (!extension || !allowedExtensions.includes(extension)) {
|
||||
throw new Error('Invalid file extension')
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] All user inputs validated with schemas
|
||||
- [ ] File uploads restricted (size, type, extension)
|
||||
- [ ] No direct use of user input in queries
|
||||
- [ ] Whitelist validation (not blacklist)
|
||||
- [ ] Error messages don't leak sensitive info
|
||||
|
||||
### 3. SQL Injection Prevention
|
||||
|
||||
#### ❌ NEVER Concatenate SQL
|
||||
```typescript
|
||||
// DANGEROUS - SQL Injection vulnerability
|
||||
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
||||
await db.query(query)
|
||||
```
|
||||
|
||||
#### ✅ ALWAYS Use Parameterized Queries
|
||||
```typescript
|
||||
// Safe - parameterized query
|
||||
const { data } = await supabase
|
||||
.from('users')
|
||||
.select('*')
|
||||
.eq('email', userEmail)
|
||||
|
||||
// Or with raw SQL
|
||||
await db.query(
|
||||
'SELECT * FROM users WHERE email = $1',
|
||||
[userEmail]
|
||||
)
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] All database queries use parameterized queries
|
||||
- [ ] No string concatenation in SQL
|
||||
- [ ] ORM/query builder used correctly
|
||||
- [ ] Supabase queries properly sanitized
|
||||
|
||||
### 4. Authentication & Authorization
|
||||
|
||||
#### JWT Token Handling
|
||||
```typescript
|
||||
// ❌ WRONG: localStorage (vulnerable to XSS)
|
||||
localStorage.setItem('token', token)
|
||||
|
||||
// ✅ CORRECT: httpOnly cookies
|
||||
res.setHeader('Set-Cookie',
|
||||
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
||||
```
|
||||
|
||||
#### Authorization Checks
|
||||
```typescript
|
||||
export async function deleteUser(userId: string, requesterId: string) {
|
||||
// ALWAYS verify authorization first
|
||||
const requester = await db.users.findUnique({
|
||||
where: { id: requesterId }
|
||||
})
|
||||
|
||||
if (requester.role !== 'admin') {
|
||||
return NextResponse.json(
|
||||
{ error: 'Unauthorized' },
|
||||
{ status: 403 }
|
||||
)
|
||||
}
|
||||
|
||||
// Proceed with deletion
|
||||
await db.users.delete({ where: { id: userId } })
|
||||
}
|
||||
```
|
||||
|
||||
#### Row Level Security (Supabase)
|
||||
```sql
|
||||
-- Enable RLS on all tables
|
||||
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Users can only view their own data
|
||||
CREATE POLICY "Users view own data"
|
||||
ON users FOR SELECT
|
||||
USING (auth.uid() = id);
|
||||
|
||||
-- Users can only update their own data
|
||||
CREATE POLICY "Users update own data"
|
||||
ON users FOR UPDATE
|
||||
USING (auth.uid() = id);
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] Tokens stored in httpOnly cookies (not localStorage)
|
||||
- [ ] Authorization checks before sensitive operations
|
||||
- [ ] Row Level Security enabled in Supabase
|
||||
- [ ] Role-based access control implemented
|
||||
- [ ] Session management secure
|
||||
|
||||
### 5. XSS Prevention
|
||||
|
||||
#### Sanitize HTML
|
||||
```typescript
|
||||
import DOMPurify from 'isomorphic-dompurify'
|
||||
|
||||
// ALWAYS sanitize user-provided HTML
|
||||
function renderUserContent(html: string) {
|
||||
const clean = DOMPurify.sanitize(html, {
|
||||
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
|
||||
ALLOWED_ATTR: []
|
||||
})
|
||||
return <div dangerouslySetInnerHTML={{ __html: clean }} />
|
||||
}
|
||||
```
|
||||
|
||||
#### Content Security Policy
|
||||
```typescript
|
||||
// next.config.js
|
||||
const securityHeaders = [
|
||||
{
|
||||
key: 'Content-Security-Policy',
|
||||
value: `
|
||||
default-src 'self';
|
||||
script-src 'self' 'unsafe-eval' 'unsafe-inline';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
img-src 'self' data: https:;
|
||||
font-src 'self';
|
||||
connect-src 'self' https://api.example.com;
|
||||
`.replace(/\s{2,}/g, ' ').trim()
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] User-provided HTML sanitized
|
||||
- [ ] CSP headers configured
|
||||
- [ ] No unvalidated dynamic content rendering
|
||||
- [ ] React's built-in XSS protection used
|
||||
|
||||
### 6. CSRF Protection
|
||||
|
||||
#### CSRF Tokens
|
||||
```typescript
|
||||
import { csrf } from '@/lib/csrf'
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const token = request.headers.get('X-CSRF-Token')
|
||||
|
||||
if (!csrf.verify(token)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Invalid CSRF token' },
|
||||
{ status: 403 }
|
||||
)
|
||||
}
|
||||
|
||||
// Process request
|
||||
}
|
||||
```
|
||||
|
||||
#### SameSite Cookies
|
||||
```typescript
|
||||
res.setHeader('Set-Cookie',
|
||||
`session=${sessionId}; HttpOnly; Secure; SameSite=Strict`)
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] CSRF tokens on state-changing operations
|
||||
- [ ] SameSite=Strict on all cookies
|
||||
- [ ] Double-submit cookie pattern implemented
|
||||
|
||||
### 7. Rate Limiting
|
||||
|
||||
#### API Rate Limiting
|
||||
```typescript
|
||||
import rateLimit from 'express-rate-limit'
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // 100 requests per window
|
||||
message: 'Too many requests'
|
||||
})
|
||||
|
||||
// Apply to routes
|
||||
app.use('/api/', limiter)
|
||||
```
|
||||
|
||||
#### Expensive Operations
|
||||
```typescript
|
||||
// Aggressive rate limiting for searches
|
||||
const searchLimiter = rateLimit({
|
||||
windowMs: 60 * 1000, // 1 minute
|
||||
max: 10, // 10 requests per minute
|
||||
message: 'Too many search requests'
|
||||
})
|
||||
|
||||
app.use('/api/search', searchLimiter)
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] Rate limiting on all API endpoints
|
||||
- [ ] Stricter limits on expensive operations
|
||||
- [ ] IP-based rate limiting
|
||||
- [ ] User-based rate limiting (authenticated)
|
||||
|
||||
### 8. Sensitive Data Exposure
|
||||
|
||||
#### Logging
|
||||
```typescript
|
||||
// ❌ WRONG: Logging sensitive data
|
||||
console.log('User login:', { email, password })
|
||||
console.log('Payment:', { cardNumber, cvv })
|
||||
|
||||
// ✅ CORRECT: Redact sensitive data
|
||||
console.log('User login:', { email, userId })
|
||||
console.log('Payment:', { last4: card.last4, userId })
|
||||
```
|
||||
|
||||
#### Error Messages
|
||||
```typescript
|
||||
// ❌ WRONG: Exposing internal details
|
||||
catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, stack: error.stack },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Generic error messages
|
||||
catch (error) {
|
||||
console.error('Internal error:', error)
|
||||
return NextResponse.json(
|
||||
{ error: 'An error occurred. Please try again.' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] No passwords, tokens, or secrets in logs
|
||||
- [ ] Error messages generic for users
|
||||
- [ ] Detailed errors only in server logs
|
||||
- [ ] No stack traces exposed to users
|
||||
|
||||
### 9. Blockchain Security (Solana)
|
||||
|
||||
#### Wallet Verification
|
||||
```typescript
|
||||
import { verify } from '@solana/web3.js'
|
||||
|
||||
async function verifyWalletOwnership(
|
||||
publicKey: string,
|
||||
signature: string,
|
||||
message: string
|
||||
) {
|
||||
try {
|
||||
const isValid = verify(
|
||||
Buffer.from(message),
|
||||
Buffer.from(signature, 'base64'),
|
||||
Buffer.from(publicKey, 'base64')
|
||||
)
|
||||
return isValid
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Transaction Verification
|
||||
```typescript
|
||||
async function verifyTransaction(transaction: Transaction) {
|
||||
// Verify recipient
|
||||
if (transaction.to !== expectedRecipient) {
|
||||
throw new Error('Invalid recipient')
|
||||
}
|
||||
|
||||
// Verify amount
|
||||
if (transaction.amount > maxAmount) {
|
||||
throw new Error('Amount exceeds limit')
|
||||
}
|
||||
|
||||
// Verify user has sufficient balance
|
||||
const balance = await getBalance(transaction.from)
|
||||
if (balance < transaction.amount) {
|
||||
throw new Error('Insufficient balance')
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] Wallet signatures verified
|
||||
- [ ] Transaction details validated
|
||||
- [ ] Balance checks before transactions
|
||||
- [ ] No blind transaction signing
|
||||
|
||||
### 10. Dependency Security
|
||||
|
||||
#### Regular Updates
|
||||
```bash
|
||||
# Check for vulnerabilities
|
||||
npm audit
|
||||
|
||||
# Fix automatically fixable issues
|
||||
npm audit fix
|
||||
|
||||
# Update dependencies
|
||||
npm update
|
||||
|
||||
# Check for outdated packages
|
||||
npm outdated
|
||||
```
|
||||
|
||||
#### Lock Files
|
||||
```bash
|
||||
# ALWAYS commit lock files
|
||||
git add package-lock.json
|
||||
|
||||
# Use in CI/CD for reproducible builds
|
||||
npm ci # Instead of npm install
|
||||
```
|
||||
|
||||
#### Verification Steps
|
||||
- [ ] Dependencies up to date
|
||||
- [ ] No known vulnerabilities (npm audit clean)
|
||||
- [ ] Lock files committed
|
||||
- [ ] Dependabot enabled on GitHub
|
||||
- [ ] Regular security updates
|
||||
|
||||
## Security Testing
|
||||
|
||||
### Automated Security Tests
|
||||
```typescript
|
||||
// Test authentication
|
||||
test('requires authentication', async () => {
|
||||
const response = await fetch('/api/protected')
|
||||
expect(response.status).toBe(401)
|
||||
})
|
||||
|
||||
// Test authorization
|
||||
test('requires admin role', async () => {
|
||||
const response = await fetch('/api/admin', {
|
||||
headers: { Authorization: `Bearer ${userToken}` }
|
||||
})
|
||||
expect(response.status).toBe(403)
|
||||
})
|
||||
|
||||
// Test input validation
|
||||
test('rejects invalid input', async () => {
|
||||
const response = await fetch('/api/users', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ email: 'not-an-email' })
|
||||
})
|
||||
expect(response.status).toBe(400)
|
||||
})
|
||||
|
||||
// Test rate limiting
|
||||
test('enforces rate limits', async () => {
|
||||
const requests = Array(101).fill(null).map(() =>
|
||||
fetch('/api/endpoint')
|
||||
)
|
||||
|
||||
const responses = await Promise.all(requests)
|
||||
const tooManyRequests = responses.filter(r => r.status === 429)
|
||||
|
||||
expect(tooManyRequests.length).toBeGreaterThan(0)
|
||||
})
|
||||
```
|
||||
|
||||
## Pre-Deployment Security Checklist
|
||||
|
||||
Before ANY production deployment:
|
||||
|
||||
- [ ] **Secrets**: No hardcoded secrets, all in env vars
|
||||
- [ ] **Input Validation**: All user inputs validated
|
||||
- [ ] **SQL Injection**: All queries parameterized
|
||||
- [ ] **XSS**: User content sanitized
|
||||
- [ ] **CSRF**: Protection enabled
|
||||
- [ ] **Authentication**: Proper token handling
|
||||
- [ ] **Authorization**: Role checks in place
|
||||
- [ ] **Rate Limiting**: Enabled on all endpoints
|
||||
- [ ] **HTTPS**: Enforced in production
|
||||
- [ ] **Security Headers**: CSP, X-Frame-Options configured
|
||||
- [ ] **Error Handling**: No sensitive data in errors
|
||||
- [ ] **Logging**: No sensitive data logged
|
||||
- [ ] **Dependencies**: Up to date, no vulnerabilities
|
||||
- [ ] **Row Level Security**: Enabled in Supabase
|
||||
- [ ] **CORS**: Properly configured
|
||||
- [ ] **File Uploads**: Validated (size, type)
|
||||
- [ ] **Wallet Signatures**: Verified (if blockchain)
|
||||
|
||||
## Resources
|
||||
|
||||
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
|
||||
- [Next.js Security](https://nextjs.org/docs/security)
|
||||
- [Supabase Security](https://supabase.com/docs/guides/auth)
|
||||
- [Web Security Academy](https://portswigger.net/web-security)
|
||||
|
||||
---
|
||||
|
||||
**Remember**: Security is not optional. One vulnerability can compromise the entire platform. When in doubt, err on the side of caution.
|
||||
10
skills/cc-skill-strategic-compact/SKILL.md
Normal file
10
skills/cc-skill-strategic-compact/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: cc-skill-strategic-compact
|
||||
description: Development skill from everything-claude-code
|
||||
author: affaan-m
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# cc-skill-strategic-compact
|
||||
|
||||
Development skill skill.
|
||||
52
skills/cc-skill-strategic-compact/suggest-compact.sh
Executable file
52
skills/cc-skill-strategic-compact/suggest-compact.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
# Strategic Compact Suggester
|
||||
# Runs on PreToolUse or periodically to suggest manual compaction at logical intervals
|
||||
#
|
||||
# Why manual over auto-compact:
|
||||
# - Auto-compact happens at arbitrary points, often mid-task
|
||||
# - Strategic compacting preserves context through logical phases
|
||||
# - Compact after exploration, before execution
|
||||
# - Compact after completing a milestone, before starting next
|
||||
#
|
||||
# Hook config (in ~/.claude/settings.json):
|
||||
# {
|
||||
# "hooks": {
|
||||
# "PreToolUse": [{
|
||||
# "matcher": "Edit|Write",
|
||||
# "hooks": [{
|
||||
# "type": "command",
|
||||
# "command": "~/.claude/skills/strategic-compact/suggest-compact.sh"
|
||||
# }]
|
||||
# }]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# Criteria for suggesting compact:
|
||||
# - Session has been running for extended period
|
||||
# - Large number of tool calls made
|
||||
# - Transitioning from research/exploration to implementation
|
||||
# - Plan has been finalized
|
||||
|
||||
# Track tool call count (increment in a temp file)
|
||||
COUNTER_FILE="/tmp/claude-tool-count-$$"
|
||||
THRESHOLD=${COMPACT_THRESHOLD:-50}
|
||||
|
||||
# Initialize or increment counter
|
||||
if [ -f "$COUNTER_FILE" ]; then
|
||||
count=$(cat "$COUNTER_FILE")
|
||||
count=$((count + 1))
|
||||
echo "$count" > "$COUNTER_FILE"
|
||||
else
|
||||
echo "1" > "$COUNTER_FILE"
|
||||
count=1
|
||||
fi
|
||||
|
||||
# Suggest compact after threshold tool calls
|
||||
if [ "$count" -eq "$THRESHOLD" ]; then
|
||||
echo "[StrategicCompact] $THRESHOLD tool calls reached - consider /compact if transitioning phases" >&2
|
||||
fi
|
||||
|
||||
# Suggest at regular intervals after threshold
|
||||
if [ "$count" -gt "$THRESHOLD" ] && [ $((count % 25)) -eq 0 ]; then
|
||||
echo "[StrategicCompact] $count tool calls - good checkpoint for /compact if context is stale" >&2
|
||||
fi
|
||||
@@ -1,109 +1,444 @@
|
||||
---
|
||||
name: code-review-checklist
|
||||
description: Code review guidelines covering code quality, security, and best practices.
|
||||
allowed-tools: Read, Glob, Grep
|
||||
description: "Comprehensive checklist for conducting thorough code reviews covering functionality, security, performance, and maintainability"
|
||||
---
|
||||
|
||||
# Code Review Checklist
|
||||
|
||||
## Quick Review Checklist
|
||||
## Overview
|
||||
|
||||
### Correctness
|
||||
- [ ] Code does what it's supposed to do
|
||||
- [ ] Edge cases handled
|
||||
- [ ] Error handling in place
|
||||
- [ ] No obvious bugs
|
||||
Provide a systematic checklist for conducting thorough code reviews. This skill helps reviewers ensure code quality, catch bugs, identify security issues, and maintain consistency across the codebase.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Use when reviewing pull requests
|
||||
- Use when conducting code audits
|
||||
- Use when establishing code review standards for a team
|
||||
- Use when training new developers on code review practices
|
||||
- Use when you want to ensure nothing is missed in reviews
|
||||
- Use when creating code review documentation
|
||||
|
||||
## How It Works
|
||||
|
||||
### Step 1: Understand the Context
|
||||
|
||||
Before reviewing code, I'll help you understand:
|
||||
- What problem does this code solve?
|
||||
- What are the requirements?
|
||||
- What files were changed and why?
|
||||
- Are there related issues or tickets?
|
||||
- What's the testing strategy?
|
||||
|
||||
### Step 2: Review Functionality
|
||||
|
||||
Check if the code works correctly:
|
||||
- Does it solve the stated problem?
|
||||
- Are edge cases handled?
|
||||
- Is error handling appropriate?
|
||||
- Are there any logical errors?
|
||||
- Does it match the requirements?
|
||||
|
||||
### Step 3: Review Code Quality
|
||||
|
||||
Assess code maintainability:
|
||||
- Is the code readable and clear?
|
||||
- Are names descriptive?
|
||||
- Is it properly structured?
|
||||
- Are functions/methods focused?
|
||||
- Is there unnecessary complexity?
|
||||
|
||||
### Step 4: Review Security
|
||||
|
||||
Check for security issues:
|
||||
- Are inputs validated?
|
||||
- Is sensitive data protected?
|
||||
- Are there SQL injection risks?
|
||||
- Is authentication/authorization correct?
|
||||
- Are dependencies secure?
|
||||
|
||||
### Step 5: Review Performance
|
||||
|
||||
Look for performance issues:
|
||||
- Are there unnecessary loops?
|
||||
- Is database access optimized?
|
||||
- Are there memory leaks?
|
||||
- Is caching used appropriately?
|
||||
- Are there N+1 query problems?
|
||||
|
||||
### Step 6: Review Tests
|
||||
|
||||
Verify test coverage:
|
||||
- Are there tests for new code?
|
||||
- Do tests cover edge cases?
|
||||
- Are tests meaningful?
|
||||
- Do all tests pass?
|
||||
- Is test coverage adequate?
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Functionality Review Checklist
|
||||
|
||||
```markdown
|
||||
## Functionality Review
|
||||
|
||||
### Requirements
|
||||
- [ ] Code solves the stated problem
|
||||
- [ ] All acceptance criteria are met
|
||||
- [ ] Edge cases are handled
|
||||
- [ ] Error cases are handled
|
||||
- [ ] User input is validated
|
||||
|
||||
### Logic
|
||||
- [ ] No logical errors or bugs
|
||||
- [ ] Conditions are correct (no off-by-one errors)
|
||||
- [ ] Loops terminate correctly
|
||||
- [ ] Recursion has proper base cases
|
||||
- [ ] State management is correct
|
||||
|
||||
### Error Handling
|
||||
- [ ] Errors are caught appropriately
|
||||
- [ ] Error messages are clear and helpful
|
||||
- [ ] Errors don't expose sensitive information
|
||||
- [ ] Failed operations are rolled back
|
||||
- [ ] Logging is appropriate
|
||||
|
||||
### Example Issues to Catch:
|
||||
|
||||
**❌ Bad - Missing validation:**
|
||||
\`\`\`javascript
|
||||
function createUser(email, password) {
|
||||
// No validation!
|
||||
return db.users.create({ email, password });
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**✅ Good - Proper validation:**
|
||||
\`\`\`javascript
|
||||
function createUser(email, password) {
|
||||
if (!email || !isValidEmail(email)) {
|
||||
throw new Error('Invalid email address');
|
||||
}
|
||||
if (!password || password.length < 8) {
|
||||
throw new Error('Password must be at least 8 characters');
|
||||
}
|
||||
return db.users.create({ email, password });
|
||||
}
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Example 2: Security Review Checklist
|
||||
|
||||
```markdown
|
||||
## Security Review
|
||||
|
||||
### Input Validation
|
||||
- [ ] All user inputs are validated
|
||||
- [ ] SQL injection is prevented (use parameterized queries)
|
||||
- [ ] XSS is prevented (escape output)
|
||||
- [ ] CSRF protection is in place
|
||||
- [ ] File uploads are validated (type, size, content)
|
||||
|
||||
### Authentication & Authorization
|
||||
- [ ] Authentication is required where needed
|
||||
- [ ] Authorization checks are present
|
||||
- [ ] Passwords are hashed (never stored plain text)
|
||||
- [ ] Sessions are managed securely
|
||||
- [ ] Tokens expire appropriately
|
||||
|
||||
### Data Protection
|
||||
- [ ] Sensitive data is encrypted
|
||||
- [ ] API keys are not hardcoded
|
||||
- [ ] Environment variables are used for secrets
|
||||
- [ ] Personal data follows privacy regulations
|
||||
- [ ] Database credentials are secure
|
||||
|
||||
### Dependencies
|
||||
- [ ] No known vulnerable dependencies
|
||||
- [ ] Dependencies are up to date
|
||||
- [ ] Unnecessary dependencies are removed
|
||||
- [ ] Dependency versions are pinned
|
||||
|
||||
### Example Issues to Catch:
|
||||
|
||||
**❌ Bad - SQL injection risk:**
|
||||
\`\`\`javascript
|
||||
const query = \`SELECT * FROM users WHERE email = '\${email}'\`;
|
||||
db.query(query);
|
||||
\`\`\`
|
||||
|
||||
**✅ Good - Parameterized query:**
|
||||
\`\`\`javascript
|
||||
const query = 'SELECT * FROM users WHERE email = $1';
|
||||
db.query(query, [email]);
|
||||
\`\`\`
|
||||
|
||||
**❌ Bad - Hardcoded secret:**
|
||||
\`\`\`javascript
|
||||
const API_KEY = 'sk_live_abc123xyz';
|
||||
\`\`\`
|
||||
|
||||
**✅ Good - Environment variable:**
|
||||
\`\`\`javascript
|
||||
const API_KEY = process.env.API_KEY;
|
||||
if (!API_KEY) {
|
||||
throw new Error('API_KEY environment variable is required');
|
||||
}
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Example 3: Code Quality Review Checklist
|
||||
|
||||
```markdown
|
||||
## Code Quality Review
|
||||
|
||||
### Readability
|
||||
- [ ] Code is easy to understand
|
||||
- [ ] Variable names are descriptive
|
||||
- [ ] Function names explain what they do
|
||||
- [ ] Complex logic has comments
|
||||
- [ ] Magic numbers are replaced with constants
|
||||
|
||||
### Structure
|
||||
- [ ] Functions are small and focused
|
||||
- [ ] Code follows DRY principle (Don't Repeat Yourself)
|
||||
- [ ] Proper separation of concerns
|
||||
- [ ] Consistent code style
|
||||
- [ ] No dead code or commented-out code
|
||||
|
||||
### Maintainability
|
||||
- [ ] Code is modular and reusable
|
||||
- [ ] Dependencies are minimal
|
||||
- [ ] Changes are backwards compatible
|
||||
- [ ] Breaking changes are documented
|
||||
- [ ] Technical debt is noted
|
||||
|
||||
### Example Issues to Catch:
|
||||
|
||||
**❌ Bad - Unclear naming:**
|
||||
\`\`\`javascript
|
||||
function calc(a, b, c) {
|
||||
return a * b + c;
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**✅ Good - Descriptive naming:**
|
||||
\`\`\`javascript
|
||||
function calculateTotalPrice(quantity, unitPrice, tax) {
|
||||
return quantity * unitPrice + tax;
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**❌ Bad - Function doing too much:**
|
||||
\`\`\`javascript
|
||||
function processOrder(order) {
|
||||
// Validate order
|
||||
if (!order.items) throw new Error('No items');
|
||||
|
||||
// Calculate total
|
||||
let total = 0;
|
||||
for (let item of order.items) {
|
||||
total += item.price * item.quantity;
|
||||
}
|
||||
|
||||
// Apply discount
|
||||
if (order.coupon) {
|
||||
total *= 0.9;
|
||||
}
|
||||
|
||||
// Process payment
|
||||
const payment = stripe.charge(total);
|
||||
|
||||
// Send email
|
||||
sendEmail(order.email, 'Order confirmed');
|
||||
|
||||
// Update inventory
|
||||
updateInventory(order.items);
|
||||
|
||||
return { orderId: order.id, total };
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**✅ Good - Separated concerns:**
|
||||
\`\`\`javascript
|
||||
function processOrder(order) {
|
||||
validateOrder(order);
|
||||
const total = calculateOrderTotal(order);
|
||||
const payment = processPayment(total);
|
||||
sendOrderConfirmation(order.email);
|
||||
updateInventory(order.items);
|
||||
|
||||
return { orderId: order.id, total };
|
||||
}
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ Do This
|
||||
|
||||
- **Review Small Changes** - Smaller PRs are easier to review thoroughly
|
||||
- **Check Tests First** - Verify tests pass and cover new code
|
||||
- **Run the Code** - Test it locally when possible
|
||||
- **Ask Questions** - Don't assume, ask for clarification
|
||||
- **Be Constructive** - Suggest improvements, don't just criticize
|
||||
- **Focus on Important Issues** - Don't nitpick minor style issues
|
||||
- **Use Automated Tools** - Linters, formatters, security scanners
|
||||
- **Review Documentation** - Check if docs are updated
|
||||
- **Consider Performance** - Think about scale and efficiency
|
||||
- **Check for Regressions** - Ensure existing functionality still works
|
||||
|
||||
### ❌ Don't Do This
|
||||
|
||||
- **Don't Approve Without Reading** - Actually review the code
|
||||
- **Don't Be Vague** - Provide specific feedback with examples
|
||||
- **Don't Ignore Security** - Security issues are critical
|
||||
- **Don't Skip Tests** - Untested code will cause problems
|
||||
- **Don't Be Rude** - Be respectful and professional
|
||||
- **Don't Rubber Stamp** - Every review should add value
|
||||
- **Don't Review When Tired** - You'll miss important issues
|
||||
- **Don't Forget Context** - Understand the bigger picture
|
||||
|
||||
## Complete Review Checklist
|
||||
|
||||
### Pre-Review
|
||||
- [ ] Read the PR description and linked issues
|
||||
- [ ] Understand what problem is being solved
|
||||
- [ ] Check if tests pass in CI/CD
|
||||
- [ ] Pull the branch and run it locally
|
||||
|
||||
### Functionality
|
||||
- [ ] Code solves the stated problem
|
||||
- [ ] Edge cases are handled
|
||||
- [ ] Error handling is appropriate
|
||||
- [ ] User input is validated
|
||||
- [ ] No logical errors
|
||||
|
||||
### 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
|
||||
- [ ] No SQL injection vulnerabilities
|
||||
- [ ] No XSS vulnerabilities
|
||||
- [ ] Authentication/authorization is correct
|
||||
- [ ] Sensitive data is protected
|
||||
- [ ] No hardcoded secrets
|
||||
|
||||
### Performance
|
||||
- [ ] No N+1 queries
|
||||
- [ ] No unnecessary loops
|
||||
- [ ] Appropriate caching
|
||||
- [ ] Bundle size impact considered
|
||||
- [ ] No unnecessary database queries
|
||||
- [ ] No N+1 query problems
|
||||
- [ ] Efficient algorithms used
|
||||
- [ ] No memory leaks
|
||||
- [ ] Caching used appropriately
|
||||
|
||||
### Code Quality
|
||||
- [ ] Clear naming
|
||||
- [ ] DRY - no duplicate code
|
||||
- [ ] SOLID principles followed
|
||||
- [ ] Appropriate abstraction level
|
||||
- [ ] Code is readable and clear
|
||||
- [ ] Names are descriptive
|
||||
- [ ] Functions are focused and small
|
||||
- [ ] No code duplication
|
||||
- [ ] Follows project conventions
|
||||
|
||||
### Testing
|
||||
- [ ] Unit tests for new code
|
||||
- [ ] Edge cases tested
|
||||
- [ ] Tests readable and maintainable
|
||||
### Tests
|
||||
- [ ] New code has tests
|
||||
- [ ] Tests cover edge cases
|
||||
- [ ] Tests are meaningful
|
||||
- [ ] All tests pass
|
||||
- [ ] Test coverage is adequate
|
||||
|
||||
### Documentation
|
||||
- [ ] Complex logic commented
|
||||
- [ ] Public APIs documented
|
||||
- [ ] README updated if needed
|
||||
- [ ] Code comments explain why, not what
|
||||
- [ ] API documentation is updated
|
||||
- [ ] README is updated if needed
|
||||
- [ ] Breaking changes are documented
|
||||
- [ ] Migration guide provided if needed
|
||||
|
||||
## AI & LLM Review Patterns (2025)
|
||||
### Git
|
||||
- [ ] Commit messages are clear
|
||||
- [ ] No merge conflicts
|
||||
- [ ] Branch is up to date with main
|
||||
- [ ] No unnecessary files committed
|
||||
- [ ] .gitignore is properly configured
|
||||
|
||||
### 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?
|
||||
## Common Pitfalls
|
||||
|
||||
### Prompt Engineering Review
|
||||
### Problem: Missing Edge Cases
|
||||
**Symptoms:** Code works for happy path but fails on edge cases
|
||||
**Solution:** Ask "What if...?" questions
|
||||
- What if the input is null?
|
||||
- What if the array is empty?
|
||||
- What if the user is not authenticated?
|
||||
- What if the network request fails?
|
||||
|
||||
### Problem: Security Vulnerabilities
|
||||
**Symptoms:** Code exposes security risks
|
||||
**Solution:** Use security checklist
|
||||
- Run security scanners (npm audit, Snyk)
|
||||
- Check OWASP Top 10
|
||||
- Validate all inputs
|
||||
- Use parameterized queries
|
||||
- Never trust user input
|
||||
|
||||
### Problem: Poor Test Coverage
|
||||
**Symptoms:** New code has no tests or inadequate tests
|
||||
**Solution:** Require tests for all new code
|
||||
- Unit tests for functions
|
||||
- Integration tests for features
|
||||
- Edge case tests
|
||||
- Error case tests
|
||||
|
||||
### Problem: Unclear Code
|
||||
**Symptoms:** Reviewer can't understand what code does
|
||||
**Solution:** Request improvements
|
||||
- Better variable names
|
||||
- Explanatory comments
|
||||
- Smaller functions
|
||||
- Clear structure
|
||||
|
||||
## Review Comment Templates
|
||||
|
||||
### Requesting Changes
|
||||
```markdown
|
||||
// ❌ Vague prompt in code
|
||||
const response = await ai.generate(userInput);
|
||||
**Issue:** [Describe the problem]
|
||||
|
||||
// ✅ Structured & Safe prompt
|
||||
const response = await ai.generate({
|
||||
system: "You are a specialized parser...",
|
||||
input: sanitize(userInput),
|
||||
schema: ResponseSchema
|
||||
});
|
||||
**Current code:**
|
||||
\`\`\`javascript
|
||||
// Show problematic code
|
||||
\`\`\`
|
||||
|
||||
**Suggested fix:**
|
||||
\`\`\`javascript
|
||||
// Show improved code
|
||||
\`\`\`
|
||||
|
||||
**Why:** [Explain why this is better]
|
||||
```
|
||||
|
||||
## Anti-Patterns to Flag
|
||||
### Asking Questions
|
||||
```markdown
|
||||
**Question:** [Your question]
|
||||
|
||||
```typescript
|
||||
// ❌ Magic numbers
|
||||
if (status === 3) { ... }
|
||||
**Context:** [Why you're asking]
|
||||
|
||||
// ✅ 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 = ...
|
||||
**Suggestion:** [If you have one]
|
||||
```
|
||||
|
||||
## Review Comments Guide
|
||||
### Praising Good Code
|
||||
```markdown
|
||||
**Nice!** [What you liked]
|
||||
|
||||
This is great because [explain why]
|
||||
```
|
||||
// Blocking issues use 🔴
|
||||
🔴 BLOCKING: SQL injection vulnerability here
|
||||
|
||||
// Important suggestions use 🟡
|
||||
🟡 SUGGESTION: Consider using useMemo for performance
|
||||
## Related Skills
|
||||
|
||||
// Minor nits use 🟢
|
||||
🟢 NIT: Prefer const over let for immutable variable
|
||||
- `@requesting-code-review` - Prepare code for review
|
||||
- `@receiving-code-review` - Handle review feedback
|
||||
- `@systematic-debugging` - Debug issues found in review
|
||||
- `@test-driven-development` - Ensure code has tests
|
||||
|
||||
// Questions use ❓
|
||||
❓ QUESTION: What happens if user is null here?
|
||||
```
|
||||
## Additional Resources
|
||||
|
||||
- [Google Code Review Guidelines](https://google.github.io/eng-practices/review/)
|
||||
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
|
||||
- [Code Review Best Practices](https://github.com/thoughtbot/guides/tree/main/code-review)
|
||||
- [How to Review Code](https://www.kevinlondon.com/2015/05/05/code-review-best-practices.html)
|
||||
|
||||
---
|
||||
|
||||
**Pro Tip:** Use a checklist template for every review to ensure consistency and thoroughness. Customize it for your team's specific needs!
|
||||
|
||||
37
skills/codex-review/SKILL.md
Normal file
37
skills/codex-review/SKILL.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: codex-review
|
||||
description: Professional code review with auto CHANGELOG generation, integrated with Codex AI
|
||||
---
|
||||
|
||||
# codex-review
|
||||
|
||||
## Overview
|
||||
Professional code review with auto CHANGELOG generation, integrated with Codex AI
|
||||
|
||||
## When to Use
|
||||
- When you want professional code review before commits
|
||||
- When you need automatic CHANGELOG generation
|
||||
- When reviewing large-scale refactoring
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
npx skills add -g BenedictKing/codex-review
|
||||
```
|
||||
|
||||
## Step-by-Step Guide
|
||||
1. Install the skill using the command above
|
||||
2. Ensure Codex CLI is installed
|
||||
3. Use `/codex-review` or natural language triggers
|
||||
|
||||
## Examples
|
||||
See [GitHub Repository](https://github.com/BenedictKing/codex-review) for examples.
|
||||
|
||||
## Best Practices
|
||||
- Keep CHANGELOG.md in your project root
|
||||
- Use conventional commit messages
|
||||
|
||||
## Troubleshooting
|
||||
See the GitHub repository for troubleshooting guides.
|
||||
|
||||
## Related Skills
|
||||
- context7-auto-research, tavily-web, exa-search, firecrawl-scraper
|
||||
36
skills/context7-auto-research/SKILL.md
Normal file
36
skills/context7-auto-research/SKILL.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: context7-auto-research
|
||||
description: Automatically fetch latest library/framework documentation for Claude Code via Context7 API
|
||||
---
|
||||
|
||||
# context7-auto-research
|
||||
|
||||
## Overview
|
||||
Automatically fetch latest library/framework documentation for Claude Code via Context7 API
|
||||
|
||||
## When to Use
|
||||
- When you need up-to-date documentation for libraries and frameworks
|
||||
- When asking about React, Next.js, Prisma, or any other popular library
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
npx skills add -g BenedictKing/context7-auto-research
|
||||
```
|
||||
|
||||
## Step-by-Step Guide
|
||||
1. Install the skill using the command above
|
||||
2. Configure API key (optional, see GitHub repo for details)
|
||||
3. Use naturally in Claude Code conversations
|
||||
|
||||
## Examples
|
||||
See [GitHub Repository](https://github.com/BenedictKing/context7-auto-research) for examples.
|
||||
|
||||
## Best Practices
|
||||
- Configure API keys via environment variables for higher rate limits
|
||||
- Use the skill's auto-trigger feature for seamless integration
|
||||
|
||||
## Troubleshooting
|
||||
See the GitHub repository for troubleshooting guides.
|
||||
|
||||
## Related Skills
|
||||
- tavily-web, exa-search, firecrawl-scraper, codex-review
|
||||
@@ -1,366 +1,162 @@
|
||||
---
|
||||
name: copywriting
|
||||
description: When the user wants to write, rewrite, or improve marketing copy for any page — including homepage, landing pages, pricing pages, feature pages, about pages, or product pages. Also use when the user says "write copy for," "improve this copy," "rewrite this page," "marketing copy," "headline help," or "CTA copy." For email copy, see email-sequence. For popup copy, see popup-cro.
|
||||
description: >
|
||||
Use this skill when writing, rewriting, or improving marketing copy
|
||||
for any page (homepage, landing page, pricing, feature, product, or about page).
|
||||
This skill produces clear, compelling, and testable copy while enforcing
|
||||
alignment, honesty, and conversion best practices.
|
||||
---
|
||||
|
||||
# Copywriting
|
||||
|
||||
You are an expert conversion copywriter. Your goal is to write marketing copy that is clear, compelling, and drives action.
|
||||
## Purpose
|
||||
|
||||
## Before Writing
|
||||
Produce **clear, credible, and action-oriented marketing copy** that aligns with
|
||||
user intent and business goals.
|
||||
|
||||
Gather this context (ask if not provided):
|
||||
This skill exists to prevent:
|
||||
- writing before understanding the audience
|
||||
- vague or hype-driven messaging
|
||||
- misaligned CTAs
|
||||
- overclaiming or fabricated proof
|
||||
- untestable copy
|
||||
|
||||
### 1. Page Purpose
|
||||
- What type of page is this? (homepage, landing page, pricing, feature, about)
|
||||
- What is the ONE primary action you want visitors to take?
|
||||
- What's the secondary action (if any)?
|
||||
|
||||
### 2. Audience
|
||||
- Who is the ideal customer for this page?
|
||||
- What problem are they trying to solve?
|
||||
- What have they already tried?
|
||||
- What objections or hesitations do they have?
|
||||
- What language do they use to describe their problem?
|
||||
|
||||
### 3. Product/Offer
|
||||
- What are you selling or offering?
|
||||
- What makes it different from alternatives?
|
||||
- What's the key transformation or outcome?
|
||||
- Any proof points (numbers, testimonials, case studies)?
|
||||
|
||||
### 4. Context
|
||||
- Where is traffic coming from? (ads, organic, email)
|
||||
- What do visitors already know before arriving?
|
||||
- What messaging are they seeing before this page?
|
||||
You may **not** fabricate claims, statistics, testimonials, or guarantees.
|
||||
|
||||
---
|
||||
|
||||
## Copywriting Principles
|
||||
## Operating Mode
|
||||
|
||||
### Clarity Over Cleverness
|
||||
- If you have to choose between clear and creative, choose clear
|
||||
- Every sentence should have one job
|
||||
- Remove words that don't add meaning
|
||||
You are operating as an **expert conversion copywriter**, not a brand poet.
|
||||
|
||||
### Benefits Over Features
|
||||
- Features: What it does
|
||||
- Benefits: What that means for the customer
|
||||
- Always connect features to outcomes
|
||||
- Clarity beats cleverness
|
||||
- Outcomes beat features
|
||||
- Specificity beats buzzwords
|
||||
- Honesty beats hype
|
||||
|
||||
### Specificity Over Vagueness
|
||||
- Vague: "Save time on your workflow"
|
||||
- Specific: "Cut your weekly reporting from 4 hours to 15 minutes"
|
||||
Your job is to **help the right reader take the right action**.
|
||||
|
||||
### Customer Language Over Company Language
|
||||
- Use words your customers use
|
||||
- Avoid jargon unless your audience uses it
|
||||
- Mirror voice-of-customer from reviews, interviews, support tickets
|
||||
---
|
||||
|
||||
### One Idea Per Section
|
||||
- Don't try to say everything everywhere
|
||||
- Each section should advance one argument
|
||||
- Build a logical flow down the page
|
||||
## Phase 1 — Context Gathering (Mandatory)
|
||||
|
||||
Before writing any copy, gather or confirm the following.
|
||||
If information is missing, ask for it **before proceeding**.
|
||||
|
||||
### 1️⃣ Page Purpose
|
||||
- Page type (homepage, landing page, pricing, feature, about)
|
||||
- ONE primary action (CTA)
|
||||
- Secondary action (if any)
|
||||
|
||||
### 2️⃣ Audience
|
||||
- Target customer or role
|
||||
- Primary problem they are trying to solve
|
||||
- What they have already tried
|
||||
- Main objections or hesitations
|
||||
- Language they use to describe the problem
|
||||
|
||||
### 3️⃣ Product / Offer
|
||||
- What is being offered
|
||||
- Key differentiator vs alternatives
|
||||
- Primary outcome or transformation
|
||||
- Available proof (numbers, testimonials, case studies)
|
||||
|
||||
### 4️⃣ Context
|
||||
- Traffic source (ads, organic, email, referrals)
|
||||
- Awareness level (unaware, problem-aware, solution-aware, product-aware)
|
||||
- What visitors already know or expect
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Copy Brief Lock (Hard Gate)
|
||||
|
||||
Before writing any copy, you MUST present a **Copy Brief Summary** and pause.
|
||||
|
||||
### Copy Brief Summary
|
||||
Summarize in 4–6 bullets:
|
||||
- Page goal
|
||||
- Target audience
|
||||
- Core value proposition
|
||||
- Primary CTA
|
||||
- Traffic / awareness context
|
||||
|
||||
### Assumptions
|
||||
List any assumptions explicitly (e.g. awareness level, urgency, sophistication).
|
||||
|
||||
Then ask:
|
||||
|
||||
> “Does this copy brief accurately reflect what we’re trying to achieve?
|
||||
> Please confirm or correct anything before I write copy.”
|
||||
|
||||
**Do NOT proceed until confirmation is given.**
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Copywriting Principles
|
||||
|
||||
### Core Principles (Non-Negotiable)
|
||||
|
||||
- **Clarity over cleverness**
|
||||
- **Benefits over features**
|
||||
- **Specificity over vagueness**
|
||||
- **Customer language over company language**
|
||||
- **One idea per section**
|
||||
|
||||
Always connect:
|
||||
> Feature → Benefit → Outcome
|
||||
|
||||
---
|
||||
|
||||
## Writing Style Rules
|
||||
|
||||
Follow these core principles. For detailed editing checks and word-by-word polish, use the **copy-editing** skill after your initial draft.
|
||||
### Style Guidelines
|
||||
- Simple over complex
|
||||
- Active over passive
|
||||
- Confident over hedged
|
||||
- Show outcomes instead of adjectives
|
||||
- Avoid buzzwords unless customers use them
|
||||
|
||||
### Core Style Principles
|
||||
|
||||
1. **Simple over complex** — Use everyday words. "Use" instead of "utilize," "help" instead of "facilitate."
|
||||
|
||||
2. **Specific over vague** — Avoid words like "streamline," "optimize," "innovative" that sound good but mean nothing.
|
||||
|
||||
3. **Active over passive** — "We generate reports" not "Reports are generated."
|
||||
|
||||
4. **Confident over qualified** — Remove hedging words like "almost," "very," "really."
|
||||
|
||||
5. **Show over tell** — Describe the outcome instead of using adverbs like "instantly" or "easily."
|
||||
|
||||
6. **Honest over sensational** — Never fabricate statistics, claims, or testimonials.
|
||||
|
||||
### Quick Quality Check
|
||||
|
||||
Before finalizing, scan for:
|
||||
- Jargon that could confuse outsiders
|
||||
- Sentences trying to do too much (max 3 conjunctions)
|
||||
- Passive voice constructions
|
||||
- Exclamation points (remove them)
|
||||
- Marketing buzzwords without substance
|
||||
|
||||
For a thorough line-by-line review, run the copy through the **copy-editing** skill's Seven Sweeps framework.
|
||||
### Claim Discipline
|
||||
- No fabricated data or testimonials
|
||||
- No implied guarantees unless explicitly stated
|
||||
- No exaggerated speed or certainty
|
||||
- If proof is missing, mark placeholders clearly
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
## Phase 4 — Page Structure Framework
|
||||
|
||||
### Be Direct
|
||||
Get to the point. Don't bury the value in qualifications.
|
||||
|
||||
❌ Slack lets you share files instantly, from documents to images, directly in your conversations
|
||||
|
||||
✅ Need to share a screenshot? Send as many documents, images, and audio files as your heart desires.
|
||||
|
||||
### Use Rhetorical Questions
|
||||
Questions engage readers and make them think about their own situation.
|
||||
|
||||
✅ Hate returning stuff to Amazon?
|
||||
|
||||
✅ Need to share a screenshot?
|
||||
|
||||
✅ Tired of chasing approvals?
|
||||
|
||||
### Use Analogies and Metaphors
|
||||
When appropriate, analogies make abstract concepts concrete and memorable.
|
||||
|
||||
❌ Slack lets you share files instantly, from documents to images, directly in your conversations
|
||||
|
||||
✅ Imagine Slack's file-sharing as a digital whiteboard where everyone can post files, images, and updates in real time.
|
||||
|
||||
### Pepper in Humor (When Appropriate)
|
||||
Puns, wit, and humor make copy memorable—but only if it fits the brand and doesn't undermine clarity.
|
||||
|
||||
---
|
||||
|
||||
## Page Structure Framework
|
||||
|
||||
### Above the Fold (First Screen)
|
||||
### Above the Fold
|
||||
|
||||
**Headline**
|
||||
- Your single most important message
|
||||
- Should communicate core value proposition
|
||||
- Specific > generic
|
||||
|
||||
**Headline Formulas:**
|
||||
|
||||
**{Achieve desirable outcome} without {pain point}**
|
||||
*Example: Understand how users are really experiencing your site without drowning in numbers*
|
||||
|
||||
**The {opposite of usual process} way to {achieve desirable outcome}**
|
||||
*Example: The easiest way to turn your passion into income*
|
||||
|
||||
**Never {unpleasant event} again**
|
||||
*Example: Never miss a sales opportunity again*
|
||||
|
||||
**{Key feature/product type} for {target audience}**
|
||||
*Example: Advanced analytics for Shopify e-commerce*
|
||||
|
||||
**{Key feature/product type} for {target audience} to {what it's used for}**
|
||||
*Example: An online whiteboard for teams to ideate and brainstorm together*
|
||||
|
||||
**You don't have to {skills or resources} to {achieve desirable outcome}**
|
||||
*Example: With Ahrefs, you don't have to be an SEO pro to rank higher and get more traffic*
|
||||
|
||||
**{Achieve desirable outcome} by {how product makes it possible}**
|
||||
*Example: Generate more leads by seeing which companies visit your site*
|
||||
|
||||
**{Key benefit of your product}**
|
||||
*Example: Sound clear in online meetings*
|
||||
|
||||
**{Question highlighting the main pain point}**
|
||||
*Example: Hate returning stuff to Amazon?*
|
||||
|
||||
**Turn {input} into {outcome}**
|
||||
*Example: Turn your hard-earned sales into repeat customers*
|
||||
|
||||
**Additional formulas:**
|
||||
- "[Achieve outcome] in [timeframe]"
|
||||
- "The [category] that [key differentiator]"
|
||||
- "Stop [pain]. Start [pleasure]."
|
||||
- "[Number] [people] use [product] to [outcome]"
|
||||
- Single most important message
|
||||
- Specific value proposition
|
||||
- Outcome-focused
|
||||
|
||||
**Subheadline**
|
||||
- Expands on the headline
|
||||
- Adds specificity or addresses secondary concern
|
||||
- 1-2 sentences max
|
||||
- Adds clarity or context
|
||||
- 1–2 sentences max
|
||||
|
||||
**Primary CTA**
|
||||
- Action-oriented button text
|
||||
- Communicate what they get, not what they do
|
||||
- "Start Free Trial" > "Sign Up"
|
||||
- "Get Your Report" > "Submit"
|
||||
|
||||
**Supporting Visual**
|
||||
- Product screenshot, demo, or hero image
|
||||
- Should reinforce the message, not distract
|
||||
|
||||
### Social Proof Section
|
||||
|
||||
Options (use 1-2):
|
||||
- Customer logos (recognizable > many)
|
||||
- Key metric ("10,000+ teams")
|
||||
- Short testimonial with attribution
|
||||
- Star rating with review count
|
||||
|
||||
### Problem/Pain Section
|
||||
|
||||
- Articulate the problem better than they can
|
||||
- Show you understand their situation
|
||||
- Create recognition ("that's exactly my problem")
|
||||
|
||||
Structure:
|
||||
- "You know the feeling..." or "If you're like most [role]..."
|
||||
- Describe the specific frustrations
|
||||
- Hint at the cost of not solving it
|
||||
|
||||
### Solution/Benefits Section
|
||||
|
||||
- Bridge from problem to your solution
|
||||
- Focus on 3-5 key benefits (not 10)
|
||||
- Each benefit: headline + short explanation + proof point if available
|
||||
|
||||
Format options:
|
||||
- Benefit blocks with icons
|
||||
- Before/after comparison
|
||||
- Feature → Benefit → Proof structure
|
||||
|
||||
### How It Works Section
|
||||
|
||||
- Reduce perceived complexity
|
||||
- 3-4 step process
|
||||
- Each step: simple action + outcome
|
||||
|
||||
Example:
|
||||
1. "Connect your tools (2 minutes)"
|
||||
2. "Set your preferences"
|
||||
3. "Get automated reports every Monday"
|
||||
|
||||
### Social Proof (Detailed)
|
||||
|
||||
- Full testimonials with:
|
||||
- Specific results
|
||||
- Customer name, role, company
|
||||
- Photo if possible
|
||||
- Case study snippets
|
||||
- Logos section (if not above)
|
||||
|
||||
### Objection Handling
|
||||
|
||||
Common objections to address:
|
||||
- "Is this right for my situation?"
|
||||
- "What if it doesn't work?"
|
||||
- "Is it hard to set up?"
|
||||
- "How is this different from X?"
|
||||
|
||||
Formats:
|
||||
- FAQ section
|
||||
- Comparison table
|
||||
- Guarantee/promise section
|
||||
- "Built for [specific audience]" section
|
||||
|
||||
### Final CTA Section
|
||||
|
||||
- Recap the value proposition
|
||||
- Repeat the primary CTA
|
||||
- Add urgency if genuine (deadline, limited availability)
|
||||
- Risk reversal (guarantee, free trial, no credit card)
|
||||
- Action-oriented
|
||||
- Describes what the user gets
|
||||
|
||||
---
|
||||
|
||||
## Landing Page Section Variety
|
||||
### Core Sections (Use as Appropriate)
|
||||
|
||||
A great landing page isn't just a list of features. Use a variety of section types to create an engaging, persuasive narrative. Mix and match from these:
|
||||
- Social proof (logos, stats, testimonials)
|
||||
- Problem / pain articulation
|
||||
- Solution & key benefits (3–5 max)
|
||||
- How it works (3–4 steps)
|
||||
- Objection handling (FAQ, comparisons, guarantees)
|
||||
- Final CTA with recap and risk reduction
|
||||
|
||||
### Section Types to Include
|
||||
|
||||
**How It Works (Numbered Steps)**
|
||||
Walk users through the process in 3-4 clear steps. Reduces perceived complexity and shows the path to value.
|
||||
|
||||
**Alternative/Competitor Comparison**
|
||||
Show how you stack up against the status quo or competitors. Tables, side-by-side comparisons, or "Unlike X, we..." sections.
|
||||
|
||||
**Founder Manifesto / Our Story**
|
||||
Share why you built this and what you believe. Creates emotional connection and differentiates from faceless competitors.
|
||||
|
||||
**Testimonials**
|
||||
Customer quotes with names, photos, and specific results. Multiple formats: quote cards, video testimonials, tweet embeds.
|
||||
|
||||
**Case Studies**
|
||||
Deeper stories of customer success. Problem → Solution → Results format with specific metrics.
|
||||
|
||||
**Use Cases**
|
||||
Show different ways the product is used. Helps visitors self-identify: "This is for people like me."
|
||||
|
||||
**Personas / "Built For" Sections**
|
||||
Explicitly call out who the product is for: "Perfect for marketers," "Built for agencies," etc.
|
||||
|
||||
**Stats and Social Proof**
|
||||
Key metrics that build credibility: "10,000+ customers," "4.9/5 rating," "$2M saved for customers."
|
||||
|
||||
**Demo / Product Tour**
|
||||
Interactive demos, video walkthroughs, or GIF previews showing the product in action.
|
||||
|
||||
**FAQ Section**
|
||||
Address common objections and questions. Good for SEO and reducing support burden.
|
||||
|
||||
**Integrations / Partners**
|
||||
Show what tools you connect with. Logos build credibility and answer "Will this work with my stack?"
|
||||
|
||||
**Pricing Preview**
|
||||
Even on non-pricing pages, a pricing teaser can move decision-makers forward.
|
||||
|
||||
**Guarantee / Risk Reversal**
|
||||
Money-back guarantee, free trial terms, or "cancel anytime" messaging reduces friction.
|
||||
|
||||
### Recommended Section Mix
|
||||
|
||||
For a landing page, aim for variety. Don't just stack features:
|
||||
|
||||
**Typical Feature-Heavy Page (Weak):**
|
||||
1. Hero
|
||||
2. Feature 1
|
||||
3. Feature 2
|
||||
4. Feature 3
|
||||
5. Feature 4
|
||||
6. CTA
|
||||
|
||||
**Varied, Engaging Page (Strong):**
|
||||
1. Hero with clear value prop
|
||||
2. Social proof bar (logos or stats)
|
||||
3. Problem/pain section
|
||||
4. How it works (3 steps)
|
||||
5. Key benefits (2-3, not 10)
|
||||
6. Testimonial
|
||||
7. Use cases or personas
|
||||
8. Comparison to alternatives
|
||||
9. Case study snippet
|
||||
10. FAQ
|
||||
11. Final CTA with guarantee
|
||||
Avoid stacking features without narrative flow.
|
||||
|
||||
---
|
||||
|
||||
## CTA Copy Guidelines
|
||||
|
||||
**Weak CTAs (avoid):**
|
||||
- Submit
|
||||
- Sign Up
|
||||
- Learn More
|
||||
- Click Here
|
||||
- Get Started
|
||||
|
||||
**Strong CTAs (use):**
|
||||
- Start Free Trial
|
||||
- Get [Specific Thing]
|
||||
- See [Product] in Action
|
||||
- Create Your First [Thing]
|
||||
- Book My Demo
|
||||
- Download the Guide
|
||||
- Try It Free
|
||||
|
||||
**CTA formula:**
|
||||
[Action Verb] + [What They Get] + [Qualifier if needed]
|
||||
|
||||
Examples:
|
||||
- "Start My Free Trial"
|
||||
- "Get the Complete Checklist"
|
||||
- "See Pricing for My Team"
|
||||
|
||||
---
|
||||
|
||||
## Output Format
|
||||
## Phase 5 — Writing the Copy
|
||||
|
||||
When writing copy, provide:
|
||||
|
||||
@@ -368,88 +164,62 @@ When writing copy, provide:
|
||||
Organized by section with clear labels:
|
||||
- Headline
|
||||
- Subheadline
|
||||
- CTA
|
||||
- CTAs
|
||||
- Section headers
|
||||
- Body copy
|
||||
- Secondary CTAs
|
||||
|
||||
### Annotations
|
||||
For key elements, explain:
|
||||
- Why you made this choice
|
||||
- What principle it applies
|
||||
- Alternatives considered
|
||||
|
||||
### Alternatives
|
||||
For headlines and CTAs, provide 2-3 options:
|
||||
- Option A: [copy] — [rationale]
|
||||
- Option B: [copy] — [rationale]
|
||||
- Option C: [copy] — [rationale]
|
||||
Provide 2–3 options for:
|
||||
- Headlines
|
||||
- Primary CTAs
|
||||
|
||||
### Meta Content (if relevant)
|
||||
- Page title (for SEO)
|
||||
- Meta description
|
||||
Each option must include a brief rationale.
|
||||
|
||||
### Annotations
|
||||
For key sections, explain:
|
||||
- Why this copy was chosen
|
||||
- Which principle it applies
|
||||
- What alternatives were considered
|
||||
|
||||
---
|
||||
|
||||
## Page-Specific Guidance
|
||||
## Testability Guidance
|
||||
|
||||
### Homepage Copy
|
||||
- Serve multiple audiences without being generic
|
||||
- Lead with broadest value proposition
|
||||
- Provide clear paths for different visitor intents
|
||||
- Balance "ready to buy" and "still researching"
|
||||
Write copy with testing in mind:
|
||||
- Clear, isolated value propositions
|
||||
- Headlines and CTAs that can be A/B tested
|
||||
- Avoid combining multiple messages into one element
|
||||
|
||||
### Landing Page Copy
|
||||
- Single message, single CTA
|
||||
- Match headline to ad/traffic source
|
||||
- Complete argument on one page
|
||||
- Remove distractions (often no nav)
|
||||
|
||||
### Pricing Page Copy
|
||||
- Help visitors choose the right plan
|
||||
- Clarify what's included at each level
|
||||
- Address "which is right for me?" anxiety
|
||||
- Make recommended plan obvious
|
||||
|
||||
### Feature Page Copy
|
||||
- Connect feature to benefit to outcome
|
||||
- Show use cases and examples
|
||||
- Differentiate from competitors' versions
|
||||
- Clear path to try or buy
|
||||
|
||||
### About Page Copy
|
||||
- Tell the story of why you exist
|
||||
- Connect company mission to customer benefit
|
||||
- Build trust through transparency
|
||||
- Still include a CTA (it's still a marketing page)
|
||||
If the copy is intended for experimentation, recommend next-step testing.
|
||||
|
||||
---
|
||||
|
||||
## Voice and Tone Considerations
|
||||
## Completion Criteria (Hard Stop)
|
||||
|
||||
Before writing, establish:
|
||||
|
||||
**Formality level:**
|
||||
- Casual/conversational
|
||||
- Professional but friendly
|
||||
- Formal/enterprise
|
||||
|
||||
**Brand personality:**
|
||||
- Playful or serious?
|
||||
- Bold or understated?
|
||||
- Technical or accessible?
|
||||
|
||||
Maintain consistency throughout, but adjust intensity:
|
||||
- Headlines can be bolder
|
||||
- Body copy should be clearer
|
||||
- CTAs should be action-oriented
|
||||
This skill is complete ONLY when:
|
||||
- Copy brief has been confirmed
|
||||
- Page copy is delivered in structured form
|
||||
- Headline and CTA alternatives are provided
|
||||
- Assumptions are documented
|
||||
- Copy is ready for review, editing, or testing
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
## Key Principles (Summary)
|
||||
|
||||
- **copy-editing**: For polishing and improving existing copy (use after writing your first draft)
|
||||
- **page-cro**: If the page structure/strategy needs work, not just copy
|
||||
- **email-sequence**: For email copywriting
|
||||
- **popup-cro**: For popup and modal copy
|
||||
- **ab-test-setup**: To test copy variations properly
|
||||
- Understand before writing
|
||||
- Make assumptions explicit
|
||||
- One page, one goal
|
||||
- One section, one idea
|
||||
- Benefits before features
|
||||
- Honest claims only
|
||||
|
||||
---
|
||||
|
||||
## Final Reminder
|
||||
|
||||
Good copy does not persuade everyone.
|
||||
It persuades **the right person** to take **the right action**.
|
||||
|
||||
If the copy feels clever but unclear,
|
||||
rewrite it until it feels obvious.
|
||||
|
||||
357
skills/daily-news-report/SKILL.md
Normal file
357
skills/daily-news-report/SKILL.md
Normal file
@@ -0,0 +1,357 @@
|
||||
---
|
||||
name: daily-news-report
|
||||
description: 基于预设 URL 列表抓取内容,筛选高质量技术信息并生成每日 Markdown 报告。
|
||||
argument-hint: [可选: 日期]
|
||||
disable-model-invocation: false
|
||||
user-invocable: true
|
||||
allowed-tools: Task, WebFetch, Read, Write, Bash(mkdir*), Bash(date*), Bash(ls*), mcp__chrome-devtools__*
|
||||
---
|
||||
|
||||
# Daily News Report v3.0
|
||||
|
||||
> **架构升级**:主 Agent 调度 + SubAgent 执行 + 浏览器抓取 + 智能缓存
|
||||
|
||||
## 核心架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ 主 Agent (Orchestrator) │
|
||||
│ 职责:调度、监控、评估、决策、汇总 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ 1. 初始化 │ → │ 2. 调度 │ → │ 3. 监控 │ → │ 4. 评估 │ │
|
||||
│ │ 读取配置 │ │ 分发任务 │ │ 收集结果 │ │ 筛选排序 │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ▼ ▼ ▼ ▼ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ 5. 决策 │ ← │ 够20条? │ │ 6. 生成 │ → │ 7. 更新 │ │
|
||||
│ │ 继续/停止 │ │ Y/N │ │ 日报文件 │ │ 缓存统计 │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────────────┘
|
||||
↓ 调度 ↑ 返回结果
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ SubAgent 执行层 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Worker A │ │ Worker B │ │ Browser │ │
|
||||
│ │ (WebFetch) │ │ (WebFetch) │ │ (Headless) │ │
|
||||
│ │ Tier1 Batch │ │ Tier2 Batch │ │ JS渲染页面 │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 结构化结果返回 │ │
|
||||
│ │ { status, data: [...], errors: [...], metadata: {...} } │ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 配置文件
|
||||
|
||||
本 Skill 使用以下配置文件:
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `sources.json` | 信息源配置、优先级、抓取方法 |
|
||||
| `cache.json` | 缓存数据、历史统计、去重指纹 |
|
||||
|
||||
## 执行流程详解
|
||||
|
||||
### Phase 1: 初始化
|
||||
|
||||
```yaml
|
||||
步骤:
|
||||
1. 确定日期(用户参数或当前日期)
|
||||
2. 读取 sources.json 获取源配置
|
||||
3. 读取 cache.json 获取历史数据
|
||||
4. 创建输出目录 NewsReport/
|
||||
5. 检查今日是否已有部分报告(追加模式)
|
||||
```
|
||||
|
||||
### Phase 2: 调度 SubAgent
|
||||
|
||||
**策略**:并行调度,分批执行,早停机制
|
||||
|
||||
```yaml
|
||||
第1波 (并行):
|
||||
- Worker A: Tier1 Batch A (HN, HuggingFace Papers)
|
||||
- Worker B: Tier1 Batch B (OneUsefulThing, Paul Graham)
|
||||
|
||||
等待结果 → 评估数量
|
||||
|
||||
如果 < 15 条高质量:
|
||||
第2波 (并行):
|
||||
- Worker C: Tier2 Batch A (James Clear, FS Blog)
|
||||
- Worker D: Tier2 Batch B (HackerNoon, Scott Young)
|
||||
|
||||
如果仍 < 20 条:
|
||||
第3波 (浏览器):
|
||||
- Browser Worker: ProductHunt, Latent Space (需要JS渲染)
|
||||
```
|
||||
|
||||
### Phase 3: SubAgent 任务格式
|
||||
|
||||
每个 SubAgent 接收的任务格式:
|
||||
|
||||
```yaml
|
||||
task: fetch_and_extract
|
||||
sources:
|
||||
- id: hn
|
||||
url: https://news.ycombinator.com
|
||||
extract: top_10
|
||||
- id: hf_papers
|
||||
url: https://huggingface.co/papers
|
||||
extract: top_voted
|
||||
|
||||
output_schema:
|
||||
items:
|
||||
- source_id: string # 来源标识
|
||||
title: string # 标题
|
||||
summary: string # 2-4句摘要
|
||||
key_points: string[] # 最多3个要点
|
||||
url: string # 原文链接
|
||||
keywords: string[] # 关键词
|
||||
quality_score: 1-5 # 质量评分
|
||||
|
||||
constraints:
|
||||
filter: "前沿技术/高深技术/提效技术/实用资讯"
|
||||
exclude: "泛科普/营销软文/过度学术化/招聘帖"
|
||||
max_items_per_source: 10
|
||||
skip_on_error: true
|
||||
|
||||
return_format: JSON
|
||||
```
|
||||
|
||||
### Phase 4: 主 Agent 监控与反馈
|
||||
|
||||
主 Agent 职责:
|
||||
|
||||
```yaml
|
||||
监控:
|
||||
- 检查 SubAgent 返回状态 (success/partial/failed)
|
||||
- 统计收集到的条目数量
|
||||
- 记录每个源的成功率
|
||||
|
||||
反馈循环:
|
||||
- 如果某 SubAgent 失败,决定是否重试或跳过
|
||||
- 如果某源持续失败,标记为禁用
|
||||
- 动态调整后续批次的源选择
|
||||
|
||||
决策:
|
||||
- 条目数 >= 25 且高质量 >= 20 → 停止抓取
|
||||
- 条目数 < 15 → 继续下一批
|
||||
- 所有批次完成但 < 20 → 用现有内容生成(宁缺毋滥)
|
||||
```
|
||||
|
||||
### Phase 5: 评估与筛选
|
||||
|
||||
```yaml
|
||||
去重:
|
||||
- 基于 URL 完全匹配
|
||||
- 基于标题相似度 (>80% 视为重复)
|
||||
- 检查 cache.json 避免与历史重复
|
||||
|
||||
评分校准:
|
||||
- 统一各 SubAgent 的评分标准
|
||||
- 根据来源可信度调整权重
|
||||
- 手动标注的高质量源加分
|
||||
|
||||
排序:
|
||||
- 按 quality_score 降序
|
||||
- 同分按来源优先级排序
|
||||
- 截取 Top 20
|
||||
```
|
||||
|
||||
### Phase 6: 浏览器抓取 (MCP Chrome DevTools)
|
||||
|
||||
对于需要 JS 渲染的页面,使用无头浏览器:
|
||||
|
||||
```yaml
|
||||
流程:
|
||||
1. 调用 mcp__chrome-devtools__new_page 打开页面
|
||||
2. 调用 mcp__chrome-devtools__wait_for 等待内容加载
|
||||
3. 调用 mcp__chrome-devtools__take_snapshot 获取页面结构
|
||||
4. 解析 snapshot 提取所需内容
|
||||
5. 调用 mcp__chrome-devtools__close_page 关闭页面
|
||||
|
||||
适用场景:
|
||||
- ProductHunt (403 on WebFetch)
|
||||
- Latent Space (Substack JS 渲染)
|
||||
- 其他 SPA 应用
|
||||
```
|
||||
|
||||
### Phase 7: 生成日报
|
||||
|
||||
```yaml
|
||||
输出:
|
||||
- 目录: NewsReport/
|
||||
- 文件名: YYYY-MM-DD-news-report.md
|
||||
- 格式: 标准 Markdown
|
||||
|
||||
内容结构:
|
||||
- 标题 + 日期
|
||||
- 统计摘要(源数量、收录数量)
|
||||
- 20条高质量内容(按模板)
|
||||
- 生成信息(版本、时间戳)
|
||||
```
|
||||
|
||||
### Phase 8: 更新缓存
|
||||
|
||||
```yaml
|
||||
更新 cache.json:
|
||||
- last_run: 记录本次运行信息
|
||||
- source_stats: 更新各源统计数据
|
||||
- url_cache: 添加已处理的 URL
|
||||
- content_hashes: 添加内容指纹
|
||||
- article_history: 记录收录文章
|
||||
```
|
||||
|
||||
## SubAgent 调用示例
|
||||
|
||||
### 使用 general-purpose Agent
|
||||
|
||||
由于自定义 agent 需要 session 重启才能发现,可以使用 general-purpose 并注入 worker prompt:
|
||||
|
||||
```
|
||||
Task 调用:
|
||||
subagent_type: general-purpose
|
||||
model: haiku
|
||||
prompt: |
|
||||
你是一个无状态的执行单元。只做被分配的任务,返回结构化 JSON。
|
||||
|
||||
任务:抓取以下 URL 并提取内容
|
||||
|
||||
URLs:
|
||||
- https://news.ycombinator.com (提取 Top 10)
|
||||
- https://huggingface.co/papers (提取高投票论文)
|
||||
|
||||
输出格式:
|
||||
{
|
||||
"status": "success" | "partial" | "failed",
|
||||
"data": [
|
||||
{
|
||||
"source_id": "hn",
|
||||
"title": "...",
|
||||
"summary": "...",
|
||||
"key_points": ["...", "...", "..."],
|
||||
"url": "...",
|
||||
"keywords": ["...", "..."],
|
||||
"quality_score": 4
|
||||
}
|
||||
],
|
||||
"errors": [],
|
||||
"metadata": { "processed": 2, "failed": 0 }
|
||||
}
|
||||
|
||||
筛选标准:
|
||||
- 保留:前沿技术/高深技术/提效技术/实用资讯
|
||||
- 排除:泛科普/营销软文/过度学术化/招聘帖
|
||||
|
||||
直接返回 JSON,不要解释。
|
||||
```
|
||||
|
||||
### 使用 worker Agent(需重启 session)
|
||||
|
||||
```
|
||||
Task 调用:
|
||||
subagent_type: worker
|
||||
prompt: |
|
||||
task: fetch_and_extract
|
||||
input:
|
||||
urls:
|
||||
- https://news.ycombinator.com
|
||||
- https://huggingface.co/papers
|
||||
output_schema:
|
||||
- source_id: string
|
||||
- title: string
|
||||
- summary: string
|
||||
- key_points: string[]
|
||||
- url: string
|
||||
- keywords: string[]
|
||||
- quality_score: 1-5
|
||||
constraints:
|
||||
filter: 前沿技术/高深技术/提效技术/实用资讯
|
||||
exclude: 泛科普/营销软文/过度学术化
|
||||
```
|
||||
|
||||
## 输出模板
|
||||
|
||||
```markdown
|
||||
# Daily News Report(YYYY-MM-DD)
|
||||
|
||||
> 本日筛选自 N 个信息源,共收录 20 条高质量内容
|
||||
> 生成耗时: X 分钟 | 版本: v3.0
|
||||
>
|
||||
> **Warning**: Sub-agent 'worker' not detected. Running in generic mode (Serial Execution). Performance might be degraded.
|
||||
> **警告**:未检测到 Sub-agent 'worker'。正在以通用模式(串行执行)运行。性能可能会受影响。
|
||||
|
||||
---
|
||||
|
||||
## 1. 标题
|
||||
|
||||
- **摘要**:2-4 行概述
|
||||
- **要点**:
|
||||
1. 要点一
|
||||
2. 要点二
|
||||
3. 要点三
|
||||
- **来源**:[链接](URL)
|
||||
- **关键词**:`keyword1` `keyword2` `keyword3`
|
||||
- **评分**:⭐⭐⭐⭐⭐ (5/5)
|
||||
|
||||
---
|
||||
|
||||
## 2. 标题
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
*Generated by Daily News Report v3.0*
|
||||
*Sources: HN, HuggingFace, OneUsefulThing, ...*
|
||||
```
|
||||
|
||||
## 约束与原则
|
||||
|
||||
1. **宁缺毋滥**:低质量内容不进入日报
|
||||
2. **早停机制**:够 20 条高质量就停止抓取
|
||||
3. **并行优先**:同一批次的 SubAgent 并行执行
|
||||
4. **失败容错**:单个源失败不影响整体流程
|
||||
5. **缓存复用**:避免重复抓取相同内容
|
||||
6. **主 Agent 控制**:所有决策由主 Agent 做出
|
||||
7. **Fallback Awareness**:检测 sub-agent 可用性,不可用时优雅降级
|
||||
|
||||
## 预期性能
|
||||
|
||||
| 场景 | 预期时间 | 说明 |
|
||||
|------|----------|------|
|
||||
| 最优情况 | ~2 分钟 | Tier1 足够,无需浏览器 |
|
||||
| 正常情况 | ~3-4 分钟 | 需要 Tier2 补充 |
|
||||
| 需要浏览器 | ~5-6 分钟 | 包含 JS 渲染页面 |
|
||||
|
||||
## 错误处理
|
||||
|
||||
| 错误类型 | 处理方式 |
|
||||
|----------|----------|
|
||||
| SubAgent 超时 | 记录错误,继续下一个 |
|
||||
| 源 403/404 | 标记禁用,更新 sources.json |
|
||||
| 内容提取失败 | 返回原始内容,主 Agent 决定 |
|
||||
| 浏览器崩溃 | 跳过该源,记录日志 |
|
||||
|
||||
## 兼容性与兜底 (Compatibility & Fallback)
|
||||
|
||||
为了确保在不同 Agent 环境下的可用性,必须执行以下检查:
|
||||
|
||||
1. **环境检查**:
|
||||
- 在 Phase 1 初始化阶段,尝试检测 `worker` sub-agent 是否存在。
|
||||
- 如果不存在(或未安装相关插件),自动切换到 **串行执行模式 (Serial Mode)**。
|
||||
|
||||
2. **串行执行模式**:
|
||||
- 不使用 parallel block。
|
||||
- 主 Agent 依次执行每个源的抓取任务。
|
||||
- 虽然速度较慢,但保证基本功能可用。
|
||||
|
||||
3. **用户提示**:
|
||||
- 必须在生成的日报开头(引用块部分)包含明显的警告信息,提示用户当前正在运行于降级模式。
|
||||
41
skills/daily-news-report/cache.json
Normal file
41
skills/daily-news-report/cache.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"description": "Daily News Report 缓存文件,用于避免重复抓取和跟踪历史表现",
|
||||
|
||||
"last_run": {
|
||||
"date": "2026-01-21",
|
||||
"duration_seconds": 180,
|
||||
"items_collected": 20,
|
||||
"items_published": 20,
|
||||
"sources_used": ["hn", "hf_papers", "james_clear", "fs_blog", "scotthyoung"]
|
||||
},
|
||||
|
||||
"source_stats": {
|
||||
"_comment": "记录每个源的历史表现,用于动态调整优先级",
|
||||
"hn": {
|
||||
"total_fetches": 0,
|
||||
"success_count": 0,
|
||||
"avg_items_per_fetch": 0,
|
||||
"avg_quality_score": 0,
|
||||
"last_fetch": null,
|
||||
"last_success": null
|
||||
}
|
||||
},
|
||||
|
||||
"url_cache": {
|
||||
"_comment": "已处理的 URL 缓存,避免重复收录",
|
||||
"_ttl_hours": 168,
|
||||
"entries": {}
|
||||
},
|
||||
|
||||
"content_hashes": {
|
||||
"_comment": "内容指纹,用于去重",
|
||||
"_ttl_hours": 168,
|
||||
"entries": {}
|
||||
},
|
||||
|
||||
"article_history": {
|
||||
"_comment": "已收录文章的简要记录",
|
||||
"2026-01-21": []
|
||||
}
|
||||
}
|
||||
183
skills/daily-news-report/sources.json
Normal file
183
skills/daily-news-report/sources.json
Normal file
@@ -0,0 +1,183 @@
|
||||
{
|
||||
"version": "2.1",
|
||||
"last_updated": "2026-01-21",
|
||||
|
||||
"sources": {
|
||||
"tier1": {
|
||||
"description": "高命中率源,优先抓取",
|
||||
"batch_a": [
|
||||
{
|
||||
"id": "hn",
|
||||
"name": "Hacker News",
|
||||
"url": "https://news.ycombinator.com",
|
||||
"fetch_method": "webfetch",
|
||||
"extract": "top_10",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.5,
|
||||
"success_rate": 0.95
|
||||
},
|
||||
{
|
||||
"id": "hf_papers",
|
||||
"name": "HuggingFace Papers",
|
||||
"url": "https://huggingface.co/papers",
|
||||
"fetch_method": "webfetch",
|
||||
"extract": "top_voted",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.8,
|
||||
"success_rate": 0.98
|
||||
}
|
||||
],
|
||||
"batch_b": [
|
||||
{
|
||||
"id": "one_useful_thing",
|
||||
"name": "One Useful Thing",
|
||||
"url": "https://www.oneusefulthing.org",
|
||||
"fetch_method": "webfetch",
|
||||
"extract": "latest_3",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.7,
|
||||
"success_rate": 0.92
|
||||
},
|
||||
{
|
||||
"id": "paul_graham",
|
||||
"name": "Paul Graham Essays",
|
||||
"url": "https://paulgraham.com/articles.html",
|
||||
"fetch_method": "webfetch",
|
||||
"extract": "latest_5",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.6,
|
||||
"success_rate": 0.99
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"tier2": {
|
||||
"description": "中等命中率,按需抓取",
|
||||
"batch_a": [
|
||||
{
|
||||
"id": "james_clear",
|
||||
"name": "James Clear 3-2-1",
|
||||
"url": "https://jamesclear.com/3-2-1",
|
||||
"fetch_method": "webfetch",
|
||||
"extract": "latest_issue",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.3,
|
||||
"success_rate": 0.90
|
||||
},
|
||||
{
|
||||
"id": "fs_blog",
|
||||
"name": "Farnam Street Brain Food",
|
||||
"url": "https://fs.blog/brain-food",
|
||||
"fetch_method": "webfetch",
|
||||
"extract": "latest_issue",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.4,
|
||||
"success_rate": 0.88
|
||||
}
|
||||
],
|
||||
"batch_b": [
|
||||
{
|
||||
"id": "hackernoon_pm",
|
||||
"name": "HackerNoon PM",
|
||||
"url": "https://hackernoon.com/c/product-management",
|
||||
"fetch_method": "webfetch",
|
||||
"extract": "latest_5",
|
||||
"enabled": true,
|
||||
"avg_quality": 3.8,
|
||||
"success_rate": 0.85
|
||||
},
|
||||
{
|
||||
"id": "scotthyoung",
|
||||
"name": "Scott Young Blog",
|
||||
"url": "https://scotthyoung.com/blog/articles",
|
||||
"fetch_method": "webfetch",
|
||||
"extract": "latest_3",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.0,
|
||||
"success_rate": 0.90
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"tier3_browser": {
|
||||
"description": "需要浏览器渲染的源",
|
||||
"sources": [
|
||||
{
|
||||
"id": "producthunt",
|
||||
"name": "Product Hunt",
|
||||
"url": "https://www.producthunt.com",
|
||||
"fetch_method": "browser",
|
||||
"extract": "today_top_5",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.2,
|
||||
"success_rate": 0.75,
|
||||
"note": "需要无头浏览器,403 on WebFetch"
|
||||
},
|
||||
{
|
||||
"id": "latent_space",
|
||||
"name": "Latent Space",
|
||||
"url": "https://www.latent.space",
|
||||
"fetch_method": "browser",
|
||||
"extract": "latest_3",
|
||||
"enabled": true,
|
||||
"avg_quality": 4.6,
|
||||
"success_rate": 0.70,
|
||||
"note": "Substack 需要 JS 渲染"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"disabled": {
|
||||
"description": "已禁用的源(失效或低质量)",
|
||||
"sources": [
|
||||
{
|
||||
"id": "tldr_ai",
|
||||
"name": "TLDR AI",
|
||||
"url": "https://tldr.tech/ai",
|
||||
"reason": "订阅页面,无文章列表",
|
||||
"disabled_date": "2026-01-21"
|
||||
},
|
||||
{
|
||||
"id": "bensbites",
|
||||
"name": "Ben's Bites",
|
||||
"url": "https://bensbites.com/archive",
|
||||
"reason": "需要登录/付费墙",
|
||||
"disabled_date": "2026-01-21"
|
||||
},
|
||||
{
|
||||
"id": "interconnects",
|
||||
"name": "Interconnects AI",
|
||||
"url": "https://interconnects.ai",
|
||||
"reason": "内容提取失败,Substack 结构问题",
|
||||
"disabled_date": "2026-01-21"
|
||||
},
|
||||
{
|
||||
"id": "beehiiv_rss",
|
||||
"name": "Beehiiv RSS feeds",
|
||||
"url": "https://rss.beehiiv.com",
|
||||
"reason": "RSS 抓取困难",
|
||||
"disabled_date": "2026-01-21"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"fetch_config": {
|
||||
"webfetch": {
|
||||
"timeout_ms": 30000,
|
||||
"retry_count": 1,
|
||||
"cache_ttl_minutes": 60
|
||||
},
|
||||
"browser": {
|
||||
"timeout_ms": 45000,
|
||||
"wait_for_selector": "article, .post, .item",
|
||||
"screenshot_on_error": true
|
||||
}
|
||||
},
|
||||
|
||||
"quality_thresholds": {
|
||||
"min_score_to_include": 3,
|
||||
"target_items": 20,
|
||||
"early_stop_threshold": 25
|
||||
}
|
||||
}
|
||||
167
skills/design-orchestration/SKILL.md
Normal file
167
skills/design-orchestration/SKILL.md
Normal file
@@ -0,0 +1,167 @@
|
||||
---
|
||||
name: design-orchestration
|
||||
description: >
|
||||
Orchestrates design workflows by routing work through
|
||||
brainstorming, multi-agent review, and execution readiness
|
||||
in the correct order. Prevents premature implementation,
|
||||
skipped validation, and unreviewed high-risk designs.
|
||||
---
|
||||
|
||||
# Design Orchestration (Meta-Skill)
|
||||
|
||||
## Purpose
|
||||
|
||||
Ensure that **ideas become designs**, **designs are reviewed**, and
|
||||
**only validated designs reach implementation**.
|
||||
|
||||
This skill does not generate designs.
|
||||
It **controls the flow between other skills**.
|
||||
|
||||
---
|
||||
|
||||
## Operating Model
|
||||
|
||||
This is a **routing and enforcement skill**, not a creative one.
|
||||
|
||||
It decides:
|
||||
- which skill must run next
|
||||
- whether escalation is required
|
||||
- whether execution is permitted
|
||||
|
||||
---
|
||||
|
||||
## Controlled Skills
|
||||
|
||||
This meta-skill coordinates the following:
|
||||
|
||||
- `brainstorming` — design generation
|
||||
- `multi-agent-brainstorming` — design validation
|
||||
- downstream implementation or planning skills
|
||||
|
||||
---
|
||||
|
||||
## Entry Conditions
|
||||
|
||||
Invoke this skill when:
|
||||
- a user proposes a new feature, system, or change
|
||||
- a design decision carries meaningful risk
|
||||
- correctness matters more than speed
|
||||
|
||||
---
|
||||
|
||||
## Routing Logic
|
||||
|
||||
### Step 1 — Brainstorming (Mandatory)
|
||||
|
||||
If no validated design exists:
|
||||
|
||||
- Invoke `brainstorming`
|
||||
- Require:
|
||||
- Understanding Lock
|
||||
- Initial Design
|
||||
- Decision Log started
|
||||
|
||||
You may NOT proceed without these artifacts.
|
||||
|
||||
---
|
||||
|
||||
### Step 2 — Risk Assessment
|
||||
|
||||
After brainstorming completes, classify the design as:
|
||||
|
||||
- **Low risk**
|
||||
- **Moderate risk**
|
||||
- **High risk**
|
||||
|
||||
Use factors such as:
|
||||
- user impact
|
||||
- irreversibility
|
||||
- operational cost
|
||||
- complexity
|
||||
- uncertainty
|
||||
- novelty
|
||||
|
||||
---
|
||||
|
||||
### Step 3 — Conditional Escalation
|
||||
|
||||
- **Low risk**
|
||||
→ Proceed to implementation planning
|
||||
|
||||
- **Moderate risk**
|
||||
→ Recommend `multi-agent-brainstorming`
|
||||
|
||||
- **High risk**
|
||||
→ REQUIRE `multi-agent-brainstorming`
|
||||
|
||||
Skipping escalation when required is prohibited.
|
||||
|
||||
---
|
||||
|
||||
### Step 4 — Multi-Agent Review (If Invoked)
|
||||
|
||||
If `multi-agent-brainstorming` is run:
|
||||
|
||||
Require:
|
||||
- completed Understanding Lock
|
||||
- current Design
|
||||
- Decision Log
|
||||
|
||||
Do NOT allow:
|
||||
- new ideation
|
||||
- scope expansion
|
||||
- reopening problem definition
|
||||
|
||||
Only critique, revision, and decision resolution are allowed.
|
||||
|
||||
---
|
||||
|
||||
### Step 5 — Execution Readiness Check
|
||||
|
||||
Before allowing implementation:
|
||||
|
||||
Confirm:
|
||||
- design is approved (single-agent or multi-agent)
|
||||
- Decision Log is complete
|
||||
- major assumptions are documented
|
||||
- known risks are acknowledged
|
||||
|
||||
If any condition fails:
|
||||
- block execution
|
||||
- return to the appropriate skill
|
||||
|
||||
---
|
||||
|
||||
## Enforcement Rules
|
||||
|
||||
- Do NOT allow implementation without a validated design
|
||||
- Do NOT allow skipping required review
|
||||
- Do NOT allow silent escalation or de-escalation
|
||||
- Do NOT merge design and implementation phases
|
||||
|
||||
---
|
||||
|
||||
## Exit Conditions
|
||||
|
||||
This meta-skill exits ONLY when:
|
||||
- the next step is explicitly identified, AND
|
||||
- all required prior steps are complete
|
||||
|
||||
Possible exits:
|
||||
- “Proceed to implementation planning”
|
||||
- “Run multi-agent-brainstorming”
|
||||
- “Return to brainstorming for clarification”
|
||||
- "If a reviewed design reports a final disposition of APPROVED, REVISE, or REJECT, you MUST route the workflow accordingly and state the chosen next step explicitly."
|
||||
---
|
||||
|
||||
## Design Philosophy
|
||||
|
||||
This skill exists to:
|
||||
- slow down the right decisions
|
||||
- speed up the right execution
|
||||
- prevent costly mistakes
|
||||
|
||||
Good systems fail early.
|
||||
Bad systems fail in production.
|
||||
|
||||
This meta-skill exists to enforce the former.
|
||||
479
skills/environment-setup-guide/SKILL.md
Normal file
479
skills/environment-setup-guide/SKILL.md
Normal file
@@ -0,0 +1,479 @@
|
||||
---
|
||||
name: environment-setup-guide
|
||||
description: "Guide developers through setting up development environments with proper tools, dependencies, and configurations"
|
||||
---
|
||||
|
||||
# Environment Setup Guide
|
||||
|
||||
## Overview
|
||||
|
||||
Help developers set up complete development environments from scratch. This skill provides step-by-step guidance for installing tools, configuring dependencies, setting up environment variables, and verifying the setup works correctly.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Use when starting a new project and need to set up the development environment
|
||||
- Use when onboarding new team members to a project
|
||||
- Use when switching to a new machine or operating system
|
||||
- Use when troubleshooting environment-related issues
|
||||
- Use when documenting setup instructions for a project
|
||||
- Use when creating development environment documentation
|
||||
|
||||
## How It Works
|
||||
|
||||
### Step 1: Identify Requirements
|
||||
|
||||
I'll help you determine what needs to be installed:
|
||||
- Programming language and version (Node.js, Python, Go, etc.)
|
||||
- Package managers (npm, pip, cargo, etc.)
|
||||
- Database systems (PostgreSQL, MongoDB, Redis, etc.)
|
||||
- Development tools (Git, Docker, IDE extensions, etc.)
|
||||
- Environment variables and configuration files
|
||||
|
||||
### Step 2: Check Current Setup
|
||||
|
||||
Before installing anything, I'll help you check what's already installed:
|
||||
```bash
|
||||
# Check versions of installed tools
|
||||
node --version
|
||||
python --version
|
||||
git --version
|
||||
docker --version
|
||||
```
|
||||
|
||||
### Step 3: Provide Installation Instructions
|
||||
|
||||
I'll give platform-specific installation commands:
|
||||
- **macOS:** Using Homebrew
|
||||
- **Linux:** Using apt, yum, or package manager
|
||||
- **Windows:** Using Chocolatey, Scoop, or direct installers
|
||||
|
||||
### Step 4: Configure the Environment
|
||||
|
||||
Help set up:
|
||||
- Environment variables (.env files)
|
||||
- Configuration files (.gitconfig, .npmrc, etc.)
|
||||
- IDE settings (VS Code, IntelliJ, etc.)
|
||||
- Shell configuration (.bashrc, .zshrc, etc.)
|
||||
|
||||
### Step 5: Verify Installation
|
||||
|
||||
Provide verification steps to ensure everything works:
|
||||
- Run version checks
|
||||
- Test basic commands
|
||||
- Verify database connections
|
||||
- Check environment variables are loaded
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Node.js Project Setup
|
||||
|
||||
```markdown
|
||||
## Setting Up Node.js Development Environment
|
||||
|
||||
### Prerequisites
|
||||
- macOS, Linux, or Windows
|
||||
- Terminal/Command Prompt access
|
||||
- Internet connection
|
||||
|
||||
### Step 1: Install Node.js
|
||||
|
||||
**macOS (using Homebrew):**
|
||||
\`\`\`bash
|
||||
# Install Homebrew if not installed
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
|
||||
# Install Node.js
|
||||
brew install node
|
||||
\`\`\`
|
||||
|
||||
**Linux (Ubuntu/Debian):**
|
||||
\`\`\`bash
|
||||
# Update package list
|
||||
sudo apt update
|
||||
|
||||
# Install Node.js and npm
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
\`\`\`
|
||||
|
||||
**Windows (using Chocolatey):**
|
||||
\`\`\`powershell
|
||||
# Install Chocolatey if not installed
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
||||
|
||||
# Install Node.js
|
||||
choco install nodejs
|
||||
\`\`\`
|
||||
|
||||
### Step 2: Verify Installation
|
||||
|
||||
\`\`\`bash
|
||||
node --version # Should show v20.x.x or higher
|
||||
npm --version # Should show 10.x.x or higher
|
||||
\`\`\`
|
||||
|
||||
### Step 3: Install Project Dependencies
|
||||
|
||||
\`\`\`bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/your-repo/project.git
|
||||
cd project
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
\`\`\`
|
||||
|
||||
### Step 4: Set Up Environment Variables
|
||||
|
||||
Create a \`.env\` file:
|
||||
\`\`\`bash
|
||||
# Copy example environment file
|
||||
cp .env.example .env
|
||||
|
||||
# Edit with your values
|
||||
nano .env
|
||||
\`\`\`
|
||||
|
||||
Example \`.env\` content:
|
||||
\`\`\`
|
||||
NODE_ENV=development
|
||||
PORT=3000
|
||||
DATABASE_URL=postgresql://localhost:5432/mydb
|
||||
API_KEY=your-api-key-here
|
||||
\`\`\`
|
||||
|
||||
### Step 5: Run the Project
|
||||
|
||||
\`\`\`bash
|
||||
# Start development server
|
||||
npm run dev
|
||||
|
||||
# Should see: Server running on http://localhost:3000
|
||||
\`\`\`
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
**Problem:** "node: command not found"
|
||||
**Solution:** Restart your terminal or run \`source ~/.bashrc\` (Linux) or \`source ~/.zshrc\` (macOS)
|
||||
|
||||
**Problem:** "Permission denied" errors
|
||||
**Solution:** Don't use sudo with npm. Fix permissions:
|
||||
\`\`\`bash
|
||||
mkdir ~/.npm-global
|
||||
npm config set prefix '~/.npm-global'
|
||||
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Example 2: Python Project Setup
|
||||
|
||||
```markdown
|
||||
## Setting Up Python Development Environment
|
||||
|
||||
### Step 1: Install Python
|
||||
|
||||
**macOS:**
|
||||
\`\`\`bash
|
||||
brew install python@3.11
|
||||
\`\`\`
|
||||
|
||||
**Linux:**
|
||||
\`\`\`bash
|
||||
sudo apt update
|
||||
sudo apt install python3.11 python3.11-venv python3-pip
|
||||
\`\`\`
|
||||
|
||||
**Windows:**
|
||||
\`\`\`powershell
|
||||
choco install python --version=3.11
|
||||
\`\`\`
|
||||
|
||||
### Step 2: Verify Installation
|
||||
|
||||
\`\`\`bash
|
||||
python3 --version # Should show Python 3.11.x
|
||||
pip3 --version # Should show pip 23.x.x
|
||||
\`\`\`
|
||||
|
||||
### Step 3: Create Virtual Environment
|
||||
|
||||
\`\`\`bash
|
||||
# Navigate to project directory
|
||||
cd my-project
|
||||
|
||||
# Create virtual environment
|
||||
python3 -m venv venv
|
||||
|
||||
# Activate virtual environment
|
||||
# macOS/Linux:
|
||||
source venv/bin/activate
|
||||
|
||||
# Windows:
|
||||
venv\Scripts\activate
|
||||
\`\`\`
|
||||
|
||||
### Step 4: Install Dependencies
|
||||
|
||||
\`\`\`bash
|
||||
# Install from requirements.txt
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Or install packages individually
|
||||
pip install flask sqlalchemy python-dotenv
|
||||
\`\`\`
|
||||
|
||||
### Step 5: Set Up Environment Variables
|
||||
|
||||
Create \`.env\` file:
|
||||
\`\`\`
|
||||
FLASK_APP=app.py
|
||||
FLASK_ENV=development
|
||||
DATABASE_URL=sqlite:///app.db
|
||||
SECRET_KEY=your-secret-key-here
|
||||
\`\`\`
|
||||
|
||||
### Step 6: Run the Application
|
||||
|
||||
\`\`\`bash
|
||||
# Run Flask app
|
||||
flask run
|
||||
|
||||
# Should see: Running on http://127.0.0.1:5000
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Example 3: Docker Development Environment
|
||||
|
||||
```markdown
|
||||
## Setting Up Docker Development Environment
|
||||
|
||||
### Step 1: Install Docker
|
||||
|
||||
**macOS:**
|
||||
\`\`\`bash
|
||||
brew install --cask docker
|
||||
# Or download Docker Desktop from docker.com
|
||||
\`\`\`
|
||||
|
||||
**Linux:**
|
||||
\`\`\`bash
|
||||
# Install Docker
|
||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||
sudo sh get-docker.sh
|
||||
|
||||
# Add user to docker group
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
\`\`\`
|
||||
|
||||
**Windows:**
|
||||
Download Docker Desktop from docker.com
|
||||
|
||||
### Step 2: Verify Installation
|
||||
|
||||
\`\`\`bash
|
||||
docker --version # Should show Docker version 24.x.x
|
||||
docker-compose --version # Should show Docker Compose version 2.x.x
|
||||
\`\`\`
|
||||
|
||||
### Step 3: Create docker-compose.yml
|
||||
|
||||
\`\`\`yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- DATABASE_URL=postgresql://postgres:password@db:5432/mydb
|
||||
volumes:
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
db:
|
||||
image: postgres:15
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=password
|
||||
- POSTGRES_DB=mydb
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
\`\`\`
|
||||
|
||||
### Step 4: Start Services
|
||||
|
||||
\`\`\`bash
|
||||
# Build and start containers
|
||||
docker-compose up -d
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Stop services
|
||||
docker-compose down
|
||||
\`\`\`
|
||||
|
||||
### Step 5: Verify Services
|
||||
|
||||
\`\`\`bash
|
||||
# Check running containers
|
||||
docker ps
|
||||
|
||||
# Test database connection
|
||||
docker-compose exec db psql -U postgres -d mydb
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ Do This
|
||||
|
||||
- **Document Everything** - Write clear setup instructions
|
||||
- **Use Version Managers** - nvm for Node, pyenv for Python
|
||||
- **Create .env.example** - Show required environment variables
|
||||
- **Test on Clean System** - Verify instructions work from scratch
|
||||
- **Include Troubleshooting** - Document common issues and solutions
|
||||
- **Use Docker** - For consistent environments across machines
|
||||
- **Pin Versions** - Specify exact versions in package files
|
||||
- **Automate Setup** - Create setup scripts when possible
|
||||
- **Check Prerequisites** - List required tools before starting
|
||||
- **Provide Verification Steps** - Help users confirm setup works
|
||||
|
||||
### ❌ Don't Do This
|
||||
|
||||
- **Don't Assume Tools Installed** - Always check and provide install instructions
|
||||
- **Don't Skip Environment Variables** - Document all required variables
|
||||
- **Don't Use Sudo with npm** - Fix permissions instead
|
||||
- **Don't Forget Platform Differences** - Provide OS-specific instructions
|
||||
- **Don't Leave Out Verification** - Always include test steps
|
||||
- **Don't Use Global Installs** - Prefer local/virtual environments
|
||||
- **Don't Ignore Errors** - Document how to handle common errors
|
||||
- **Don't Skip Database Setup** - Include database initialization steps
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Problem: "Command not found" after installation
|
||||
**Symptoms:** Installed tool but terminal doesn't recognize it
|
||||
**Solution:**
|
||||
- Restart terminal or source shell config
|
||||
- Check PATH environment variable
|
||||
- Verify installation location
|
||||
```bash
|
||||
# Check PATH
|
||||
echo $PATH
|
||||
|
||||
# Add to PATH (example)
|
||||
export PATH="/usr/local/bin:$PATH"
|
||||
```
|
||||
|
||||
### Problem: Permission errors with npm/pip
|
||||
**Symptoms:** "EACCES" or "Permission denied" errors
|
||||
**Solution:**
|
||||
- Don't use sudo
|
||||
- Fix npm permissions or use nvm
|
||||
- Use virtual environments for Python
|
||||
```bash
|
||||
# Fix npm permissions
|
||||
mkdir ~/.npm-global
|
||||
npm config set prefix '~/.npm-global'
|
||||
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
|
||||
```
|
||||
|
||||
### Problem: Port already in use
|
||||
**Symptoms:** "Port 3000 is already in use"
|
||||
**Solution:**
|
||||
- Find and kill process using the port
|
||||
- Use a different port
|
||||
```bash
|
||||
# Find process on port 3000
|
||||
lsof -i :3000
|
||||
|
||||
# Kill process
|
||||
kill -9 <PID>
|
||||
|
||||
# Or use different port
|
||||
PORT=3001 npm start
|
||||
```
|
||||
|
||||
### Problem: Database connection fails
|
||||
**Symptoms:** "Connection refused" or "Authentication failed"
|
||||
**Solution:**
|
||||
- Verify database is running
|
||||
- Check connection string
|
||||
- Verify credentials
|
||||
```bash
|
||||
# Check if PostgreSQL is running
|
||||
sudo systemctl status postgresql
|
||||
|
||||
# Test connection
|
||||
psql -h localhost -U postgres -d mydb
|
||||
```
|
||||
|
||||
## Setup Script Template
|
||||
|
||||
Create a `setup.sh` script to automate setup:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
echo "🚀 Setting up development environment..."
|
||||
|
||||
# Check prerequisites
|
||||
command -v node >/dev/null 2>&1 || { echo "❌ Node.js not installed"; exit 1; }
|
||||
command -v git >/dev/null 2>&1 || { echo "❌ Git not installed"; exit 1; }
|
||||
|
||||
echo "✅ Prerequisites check passed"
|
||||
|
||||
# Install dependencies
|
||||
echo "📦 Installing dependencies..."
|
||||
npm install
|
||||
|
||||
# Copy environment file
|
||||
if [ ! -f .env ]; then
|
||||
echo "📝 Creating .env file..."
|
||||
cp .env.example .env
|
||||
echo "⚠️ Please edit .env with your configuration"
|
||||
fi
|
||||
|
||||
# Run database migrations
|
||||
echo "🗄️ Running database migrations..."
|
||||
npm run migrate
|
||||
|
||||
# Verify setup
|
||||
echo "🔍 Verifying setup..."
|
||||
npm run test:setup
|
||||
|
||||
echo "✅ Setup complete! Run 'npm run dev' to start"
|
||||
```
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `@brainstorming` - Plan environment requirements before setup
|
||||
- `@systematic-debugging` - Debug environment issues
|
||||
- `@doc-coauthoring` - Create setup documentation
|
||||
- `@git-pushing` - Set up Git configuration
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Node.js Installation Guide](https://nodejs.org/en/download/)
|
||||
- [Python Virtual Environments](https://docs.python.org/3/tutorial/venv.html)
|
||||
- [Docker Documentation](https://docs.docker.com/get-started/)
|
||||
- [Homebrew (macOS)](https://brew.sh/)
|
||||
- [Chocolatey (Windows)](https://chocolatey.org/)
|
||||
- [nvm (Node Version Manager)](https://github.com/nvm-sh/nvm)
|
||||
- [pyenv (Python Version Manager)](https://github.com/pyenv/pyenv)
|
||||
|
||||
---
|
||||
|
||||
**Pro Tip:** Create a `setup.sh` or `setup.ps1` script to automate the entire setup process. Test it on a clean system to ensure it works!
|
||||
36
skills/exa-search/SKILL.md
Normal file
36
skills/exa-search/SKILL.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: exa-search
|
||||
description: Semantic search, similar content discovery, and structured research using Exa API
|
||||
---
|
||||
|
||||
# exa-search
|
||||
|
||||
## Overview
|
||||
Semantic search, similar content discovery, and structured research using Exa API
|
||||
|
||||
## When to Use
|
||||
- When you need semantic/embeddings-based search
|
||||
- When finding similar content
|
||||
- When searching by category (company, people, research papers, etc.)
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
npx skills add -g BenedictKing/exa-search
|
||||
```
|
||||
|
||||
## Step-by-Step Guide
|
||||
1. Install the skill using the command above
|
||||
2. Configure Exa API key
|
||||
3. Use naturally in Claude Code conversations
|
||||
|
||||
## Examples
|
||||
See [GitHub Repository](https://github.com/BenedictKing/exa-search) for examples.
|
||||
|
||||
## Best Practices
|
||||
- Configure API keys via environment variables
|
||||
|
||||
## Troubleshooting
|
||||
See the GitHub repository for troubleshooting guides.
|
||||
|
||||
## Related Skills
|
||||
- context7-auto-research, tavily-web, firecrawl-scraper, codex-review
|
||||
37
skills/firecrawl-scraper/SKILL.md
Normal file
37
skills/firecrawl-scraper/SKILL.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: firecrawl-scraper
|
||||
description: Deep web scraping, screenshots, PDF parsing, and website crawling using Firecrawl API
|
||||
---
|
||||
|
||||
# firecrawl-scraper
|
||||
|
||||
## Overview
|
||||
Deep web scraping, screenshots, PDF parsing, and website crawling using Firecrawl API
|
||||
|
||||
## When to Use
|
||||
- When you need deep content extraction from web pages
|
||||
- When page interaction is required (clicking, scrolling, etc.)
|
||||
- When you want screenshots or PDF parsing
|
||||
- When batch scraping multiple URLs
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
npx skills add -g BenedictKing/firecrawl-scraper
|
||||
```
|
||||
|
||||
## Step-by-Step Guide
|
||||
1. Install the skill using the command above
|
||||
2. Configure Firecrawl API key
|
||||
3. Use naturally in Claude Code conversations
|
||||
|
||||
## Examples
|
||||
See [GitHub Repository](https://github.com/BenedictKing/firecrawl-scraper) for examples.
|
||||
|
||||
## Best Practices
|
||||
- Configure API keys via environment variables
|
||||
|
||||
## Troubleshooting
|
||||
See the GitHub repository for troubleshooting guides.
|
||||
|
||||
## Related Skills
|
||||
- context7-auto-research, tavily-web, exa-search, codex-review
|
||||
@@ -1,425 +1,441 @@
|
||||
---
|
||||
name: form-cro
|
||||
description: When the user wants to optimize any form that is NOT signup/registration — including lead capture forms, contact forms, demo request forms, application forms, survey forms, or checkout forms. Also use when the user mentions "form optimization," "lead form conversions," "form friction," "form fields," "form completion rate," or "contact form." For signup/registration forms, see signup-flow-cro. For popups containing forms, see popup-cro.
|
||||
description: >
|
||||
Optimize any form that is NOT signup or account registration — including lead
|
||||
capture, contact, demo request, application, survey, quote, and checkout forms.
|
||||
Use when the goal is to increase form completion rate, reduce friction, or
|
||||
improve lead quality without breaking compliance or downstream workflows.
|
||||
---
|
||||
|
||||
# Form CRO
|
||||
# Form Conversion Rate Optimization (Form CRO)
|
||||
|
||||
You are an expert in form optimization. Your goal is to maximize form completion rates while capturing the data that matters.
|
||||
You are an expert in **form optimization and friction reduction**.
|
||||
Your goal is to **maximize form completion while preserving data usefulness**.
|
||||
|
||||
## Initial Assessment
|
||||
|
||||
Before providing recommendations, identify:
|
||||
|
||||
1. **Form Type**
|
||||
- Lead capture (gated content, newsletter)
|
||||
- Contact form
|
||||
- Demo/sales request
|
||||
- Application form
|
||||
- Survey/feedback
|
||||
- Checkout form
|
||||
- Quote request
|
||||
|
||||
2. **Current State**
|
||||
- How many fields?
|
||||
- What's the current completion rate?
|
||||
- Mobile vs. desktop split?
|
||||
- Where do users abandon?
|
||||
|
||||
3. **Business Context**
|
||||
- What happens with form submissions?
|
||||
- Which fields are actually used in follow-up?
|
||||
- Are there compliance/legal requirements?
|
||||
You do **not** blindly reduce fields.
|
||||
You do **not** optimize forms in isolation from their business purpose.
|
||||
You do **not** assume more data equals better leads.
|
||||
|
||||
---
|
||||
|
||||
## Core Principles
|
||||
## Phase 0: Form Health & Friction Index (Required)
|
||||
|
||||
Before giving recommendations, calculate the **Form Health & Friction Index**.
|
||||
|
||||
### Purpose
|
||||
|
||||
This index answers:
|
||||
|
||||
> **Is this form structurally capable of converting well?**
|
||||
|
||||
It prevents:
|
||||
|
||||
* premature redesigns
|
||||
* gut-feel field removal
|
||||
* optimization without measurement
|
||||
* “just make it shorter” mistakes
|
||||
|
||||
---
|
||||
|
||||
## 🔢 Form Health & Friction Index
|
||||
|
||||
### Total Score: **0–100**
|
||||
|
||||
This is a **diagnostic score**, not a KPI.
|
||||
|
||||
---
|
||||
|
||||
### Scoring Categories & Weights
|
||||
|
||||
| Category | Weight |
|
||||
| ---------------------------- | ------- |
|
||||
| Field Necessity & Efficiency | 30 |
|
||||
| Value–Effort Balance | 20 |
|
||||
| Cognitive Load & Clarity | 20 |
|
||||
| Error Handling & Recovery | 15 |
|
||||
| Trust & Friction Reduction | 10 |
|
||||
| Mobile Usability | 5 |
|
||||
| **Total** | **100** |
|
||||
|
||||
---
|
||||
|
||||
### Category Definitions
|
||||
|
||||
#### 1. Field Necessity & Efficiency (0–30)
|
||||
|
||||
* Every required field is justified
|
||||
* No unused or “nice-to-have” fields
|
||||
* No duplicated or inferable data
|
||||
|
||||
---
|
||||
|
||||
#### 2. Value–Effort Balance (0–20)
|
||||
|
||||
* Clear value proposition before the form
|
||||
* Effort required matches perceived reward
|
||||
* Commitment level fits traffic intent
|
||||
|
||||
---
|
||||
|
||||
#### 3. Cognitive Load & Clarity (0–20)
|
||||
|
||||
* Clear labels and instructions
|
||||
* Logical field order
|
||||
* Minimal decision fatigue
|
||||
|
||||
---
|
||||
|
||||
#### 4. Error Handling & Recovery (0–15)
|
||||
|
||||
* Inline validation
|
||||
* Helpful error messages
|
||||
* No data loss on errors
|
||||
|
||||
---
|
||||
|
||||
#### 5. Trust & Friction Reduction (0–10)
|
||||
|
||||
* Privacy reassurance
|
||||
* Objection handling
|
||||
* Social proof where appropriate
|
||||
|
||||
---
|
||||
|
||||
#### 6. Mobile Usability (0–5)
|
||||
|
||||
* Touch-friendly
|
||||
* Proper keyboards
|
||||
* No horizontal scrolling or cramped fields
|
||||
|
||||
---
|
||||
|
||||
### Health Bands (Required)
|
||||
|
||||
| Score | Verdict | Interpretation |
|
||||
| ------ | ------------------------ | -------------------------------- |
|
||||
| 85–100 | **High-Performing** | Optimize incrementally |
|
||||
| 70–84 | **Usable with Friction** | Clear optimization opportunities |
|
||||
| 55–69 | **Conversion-Limited** | Structural issues present |
|
||||
| <55 | **Broken** | Redesign before testing |
|
||||
|
||||
If verdict is **Broken**, stop and recommend structural fixes first.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Context & Constraints
|
||||
|
||||
### 1. Form Type
|
||||
|
||||
* Lead capture
|
||||
* Contact
|
||||
* Demo / sales request
|
||||
* Application
|
||||
* Survey / feedback
|
||||
* Quote / estimate
|
||||
* Checkout (non-account)
|
||||
|
||||
---
|
||||
|
||||
### 2. Business Context
|
||||
|
||||
* What happens after submission?
|
||||
* Which fields are actually used?
|
||||
* What qualifies as a “good” submission?
|
||||
* Any legal or compliance constraints?
|
||||
|
||||
---
|
||||
|
||||
### 3. Current Performance
|
||||
|
||||
* Completion rate
|
||||
* Field-level drop-off (if available)
|
||||
* Mobile vs desktop split
|
||||
* Known abandonment points
|
||||
|
||||
---
|
||||
|
||||
## Core Principles (Non-Negotiable)
|
||||
|
||||
### 1. Every Field Has a Cost
|
||||
Each field reduces completion rate. Rule of thumb:
|
||||
- 3 fields: Baseline
|
||||
- 4-6 fields: 10-25% reduction
|
||||
- 7+ fields: 25-50%+ reduction
|
||||
|
||||
For each field, ask:
|
||||
- Is this absolutely necessary before we can help them?
|
||||
- Can we get this information another way?
|
||||
- Can we ask this later?
|
||||
Each required field reduces completion.
|
||||
|
||||
### 2. Value Must Exceed Effort
|
||||
- Clear value proposition above form
|
||||
- Make what they get obvious
|
||||
- Reduce perceived effort (field count, labels)
|
||||
Rule of thumb:
|
||||
|
||||
### 3. Reduce Cognitive Load
|
||||
- One question per field
|
||||
- Clear, conversational labels
|
||||
- Logical grouping and order
|
||||
- Smart defaults where possible
|
||||
* 3 fields → baseline
|
||||
* 4–6 fields → −10–25%
|
||||
* 7+ fields → −25–50%+
|
||||
|
||||
Fields must **earn their place**.
|
||||
|
||||
---
|
||||
|
||||
## Field-by-Field Optimization
|
||||
### 2. Data Collection ≠ Data Usage
|
||||
|
||||
### Email Field
|
||||
- Single field, no confirmation
|
||||
- Inline validation
|
||||
- Typo detection (did you mean gmail.com?)
|
||||
- Proper mobile keyboard
|
||||
If a field is:
|
||||
|
||||
### Name Fields
|
||||
- Single "Name" vs. First/Last — test this
|
||||
- Single field reduces friction
|
||||
- Split needed only if personalization requires it
|
||||
* not used
|
||||
* not acted upon
|
||||
* not required legally
|
||||
|
||||
### Phone Number
|
||||
- Make optional if possible
|
||||
- If required, explain why
|
||||
- Auto-format as they type
|
||||
- Country code handling
|
||||
|
||||
### Company/Organization
|
||||
- Auto-suggest for faster entry
|
||||
- Enrichment after submission (Clearbit, etc.)
|
||||
- Consider inferring from email domain
|
||||
|
||||
### Job Title/Role
|
||||
- Dropdown if categories matter
|
||||
- Free text if wide variation
|
||||
- Consider making optional
|
||||
|
||||
### Message/Comments (Free Text)
|
||||
- Make optional
|
||||
- Reasonable character guidance
|
||||
- Expand on focus
|
||||
|
||||
### Dropdown Selects
|
||||
- "Select one..." placeholder
|
||||
- Searchable if many options
|
||||
- Consider radio buttons if < 5 options
|
||||
- "Other" option with text field
|
||||
|
||||
### Checkboxes (Multi-select)
|
||||
- Clear, parallel labels
|
||||
- Reasonable number of options
|
||||
- Consider "Select all that apply" instruction
|
||||
→ it is friction, not value.
|
||||
|
||||
---
|
||||
|
||||
## Form Layout Optimization
|
||||
### 3. Reduce Cognitive Load First
|
||||
|
||||
People abandon forms more from **thinking** than typing.
|
||||
|
||||
---
|
||||
|
||||
## Field-Level Optimization
|
||||
|
||||
### Email
|
||||
|
||||
* Single field (no confirmation)
|
||||
* Inline validation
|
||||
* Typo correction
|
||||
* Correct mobile keyboard
|
||||
|
||||
---
|
||||
|
||||
### Name
|
||||
|
||||
* Single “Name” field by default
|
||||
* Split only if operationally required
|
||||
|
||||
---
|
||||
|
||||
### Phone
|
||||
|
||||
* Optional unless critical
|
||||
* Explain why if required
|
||||
* Auto-format and support country codes
|
||||
|
||||
---
|
||||
|
||||
### Company / Organization
|
||||
|
||||
* Auto-suggest when possible
|
||||
* Infer from email domain
|
||||
* Enrich after submission if feasible
|
||||
|
||||
---
|
||||
|
||||
### Job Title / Role
|
||||
|
||||
* Dropdown if segmentation matters
|
||||
* Optional by default
|
||||
|
||||
---
|
||||
|
||||
### Free-Text Fields
|
||||
|
||||
* Optional unless essential
|
||||
* Clear guidance on length/purpose
|
||||
* Expand on focus
|
||||
|
||||
---
|
||||
|
||||
### Selects & Checkboxes
|
||||
|
||||
* Radio buttons if <5 options
|
||||
* Searchable selects if long
|
||||
* Clear “Other” handling
|
||||
|
||||
---
|
||||
|
||||
## Layout & Flow
|
||||
|
||||
### Field Order
|
||||
1. Start with easiest fields (name, email)
|
||||
2. Build commitment before asking more
|
||||
3. Sensitive fields last (phone, company size)
|
||||
4. Logical grouping if many fields
|
||||
|
||||
### Labels and Placeholders
|
||||
- Labels: Always visible (not just placeholder)
|
||||
- Placeholders: Examples, not labels
|
||||
- Help text: Only when genuinely helpful
|
||||
1. Easiest first (email, name)
|
||||
2. Commitment-building fields
|
||||
3. Sensitive or high-effort fields last
|
||||
|
||||
**Good:**
|
||||
```
|
||||
Email
|
||||
[name@company.com]
|
||||
```
|
||||
---
|
||||
|
||||
**Bad:**
|
||||
```
|
||||
[Enter your email address] ← Disappears on focus
|
||||
```
|
||||
### Labels & Placeholders
|
||||
|
||||
### Visual Design
|
||||
- Sufficient spacing between fields
|
||||
- Clear visual hierarchy
|
||||
- CTA button stands out
|
||||
- Mobile-friendly tap targets (44px+)
|
||||
* Labels must always be visible
|
||||
* Placeholders are examples only
|
||||
* Avoid label-as-placeholder anti-pattern
|
||||
|
||||
### Single Column vs. Multi-Column
|
||||
- Single column: Higher completion, mobile-friendly
|
||||
- Multi-column: Only for short related fields (First/Last name)
|
||||
- When in doubt, single column
|
||||
---
|
||||
|
||||
### Single vs Multi-Column
|
||||
|
||||
* Default to single column
|
||||
* Multi-column only for closely related fields
|
||||
|
||||
---
|
||||
|
||||
## Multi-Step Forms
|
||||
|
||||
### When to Use Multi-Step
|
||||
- More than 5-6 fields
|
||||
- Logically distinct sections
|
||||
- Conditional paths based on answers
|
||||
- Complex forms (applications, quotes)
|
||||
### Use When
|
||||
|
||||
### Multi-Step Best Practices
|
||||
- Progress indicator (step X of Y)
|
||||
- Start with easy, end with sensitive
|
||||
- One topic per step
|
||||
- Allow back navigation
|
||||
- Save progress (don't lose data on refresh)
|
||||
- Clear indication of required vs. optional
|
||||
* 6+ fields
|
||||
* Distinct logical sections
|
||||
* Qualification or routing required
|
||||
|
||||
### Progressive Commitment Pattern
|
||||
1. Low-friction start (just email)
|
||||
2. More detail (name, company)
|
||||
3. Qualifying questions
|
||||
4. Contact preferences
|
||||
### Best Practices
|
||||
|
||||
* Progress indicator
|
||||
* Back navigation
|
||||
* Save progress
|
||||
* One topic per step
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Inline Validation
|
||||
- Validate as they move to next field
|
||||
- Don't validate too aggressively while typing
|
||||
- Clear visual indicators (green check, red border)
|
||||
|
||||
### Error Messages
|
||||
- Specific to the problem
|
||||
- Suggest how to fix
|
||||
- Positioned near the field
|
||||
- Don't clear their input
|
||||
* After field interaction, not keystroke
|
||||
* Clear visual feedback
|
||||
* Do not clear input on error
|
||||
|
||||
**Good:** "Please enter a valid email address (e.g., name@company.com)"
|
||||
**Bad:** "Invalid input"
|
||||
---
|
||||
|
||||
### On Submit
|
||||
- Focus on first error field
|
||||
- Summarize errors if multiple
|
||||
- Preserve all entered data
|
||||
- Don't clear form on error
|
||||
### Error Messaging
|
||||
|
||||
* Specific
|
||||
* Human
|
||||
* Actionable
|
||||
|
||||
Bad: “Invalid input”
|
||||
Good: “Please enter a valid email ([name@company.com](mailto:name@company.com))”
|
||||
|
||||
---
|
||||
|
||||
## Submit Button Optimization
|
||||
|
||||
### Button Copy
|
||||
Weak: "Submit" | "Send"
|
||||
Strong: "[Action] + [What they get]"
|
||||
### Copy
|
||||
|
||||
Avoid: Submit, Send
|
||||
Prefer: Action + Outcome
|
||||
|
||||
Examples:
|
||||
- "Get My Free Quote"
|
||||
- "Download the Guide"
|
||||
- "Request Demo"
|
||||
- "Send Message"
|
||||
- "Start Free Trial"
|
||||
|
||||
### Button Placement
|
||||
- Immediately after last field
|
||||
- Left-aligned with fields
|
||||
- Sufficient size and contrast
|
||||
- Mobile: Sticky or clearly visible
|
||||
|
||||
### Post-Submit States
|
||||
- Loading state (disable button, show spinner)
|
||||
- Success confirmation (clear next steps)
|
||||
- Error handling (clear message, focus on issue)
|
||||
* “Get My Quote”
|
||||
* “Request Demo”
|
||||
* “Download the Guide”
|
||||
|
||||
---
|
||||
|
||||
## Trust and Friction Reduction
|
||||
### States
|
||||
|
||||
### Near the Form
|
||||
- Privacy statement: "We'll never share your info"
|
||||
- Security badges if collecting sensitive data
|
||||
- Testimonial or social proof
|
||||
- Expected response time
|
||||
|
||||
### Reducing Perceived Effort
|
||||
- "Takes 30 seconds"
|
||||
- Field count indicator
|
||||
- Remove visual clutter
|
||||
- Generous white space
|
||||
|
||||
### Addressing Objections
|
||||
- "No spam, unsubscribe anytime"
|
||||
- "We won't share your number"
|
||||
- "No credit card required"
|
||||
* Disabled + loading on submit
|
||||
* Clear success message
|
||||
* Next-step expectations
|
||||
|
||||
---
|
||||
|
||||
## Form Types: Specific Guidance
|
||||
## Trust & Friction Reduction
|
||||
|
||||
### Lead Capture (Gated Content)
|
||||
- Minimum viable fields (often just email)
|
||||
- Clear value proposition for what they get
|
||||
- Consider asking enrichment questions post-download
|
||||
- Test email-only vs. email + name
|
||||
|
||||
### Contact Form
|
||||
- Essential: Email/Name + Message
|
||||
- Phone optional
|
||||
- Set response time expectations
|
||||
- Offer alternatives (chat, phone)
|
||||
|
||||
### Demo Request
|
||||
- Name, Email, Company required
|
||||
- Phone: Optional with "preferred contact" choice
|
||||
- Use case/goal question helps personalize
|
||||
- Calendar embed can increase show rate
|
||||
|
||||
### Quote/Estimate Request
|
||||
- Multi-step often works well
|
||||
- Start with easy questions
|
||||
- Technical details later
|
||||
- Save progress for complex forms
|
||||
|
||||
### Survey Forms
|
||||
- Progress bar essential
|
||||
- One question per screen for engagement
|
||||
- Skip logic for relevance
|
||||
- Consider incentive for completion
|
||||
* Privacy reassurance near submit
|
||||
* Expected response time
|
||||
* Testimonials (when appropriate)
|
||||
* Security badges only if relevant
|
||||
|
||||
---
|
||||
|
||||
## Mobile Optimization
|
||||
## Mobile Optimization (Mandatory)
|
||||
|
||||
- Larger touch targets (44px minimum height)
|
||||
- Appropriate keyboard types (email, tel, number)
|
||||
- Autofill support
|
||||
- Single column only
|
||||
- Sticky submit button
|
||||
- Minimal typing (dropdowns, buttons)
|
||||
* ≥44px touch targets
|
||||
* Correct keyboard types
|
||||
* Autofill support
|
||||
* Single column
|
||||
* Sticky submit button (where helpful)
|
||||
|
||||
---
|
||||
|
||||
## Measurement
|
||||
## Measurement (Required)
|
||||
|
||||
### Key Metrics
|
||||
- **Form start rate**: Page views → Started form
|
||||
- **Completion rate**: Started → Submitted
|
||||
- **Field drop-off**: Which fields lose people
|
||||
- **Error rate**: By field
|
||||
- **Time to complete**: Total and by field
|
||||
- **Mobile vs. desktop**: Completion by device
|
||||
|
||||
### What to Track
|
||||
- Form views
|
||||
- First field focus
|
||||
- Each field completion
|
||||
- Errors by field
|
||||
- Submit attempts
|
||||
- Successful submissions
|
||||
* Form view → start
|
||||
* Start → completion
|
||||
* Field-level drop-off
|
||||
* Error rate by field
|
||||
* Time to complete
|
||||
* Device split
|
||||
|
||||
### Track:
|
||||
|
||||
* First field focus
|
||||
* Field completion
|
||||
* Validation errors
|
||||
* Submit attempts
|
||||
* Successful submissions
|
||||
|
||||
---
|
||||
|
||||
## Output Format
|
||||
|
||||
### Form Health Summary
|
||||
|
||||
* Form Health & Friction Index score
|
||||
* Primary bottlenecks
|
||||
* Structural vs tactical issues
|
||||
|
||||
---
|
||||
|
||||
### Form Audit
|
||||
|
||||
For each issue:
|
||||
- **Issue**: What's wrong
|
||||
- **Impact**: Estimated effect on conversions
|
||||
- **Fix**: Specific recommendation
|
||||
- **Priority**: High/Medium/Low
|
||||
|
||||
* **Issue**
|
||||
* **Impact**
|
||||
* **Fix**
|
||||
* **Priority**
|
||||
|
||||
---
|
||||
|
||||
### Recommended Form Design
|
||||
- **Required fields**: Justified list
|
||||
- **Optional fields**: With rationale
|
||||
- **Field order**: Recommended sequence
|
||||
- **Copy**: Labels, placeholders, button
|
||||
- **Error messages**: For each field
|
||||
- **Layout**: Visual guidance
|
||||
|
||||
* Required fields (with justification)
|
||||
* Optional fields
|
||||
* Field order
|
||||
* Copy (labels, help text, CTA)
|
||||
* Error messages
|
||||
* Layout notes
|
||||
|
||||
---
|
||||
|
||||
### Test Hypotheses
|
||||
Ideas to A/B test with expected outcomes
|
||||
|
||||
Clearly stated A/B test ideas with expected outcome
|
||||
|
||||
---
|
||||
|
||||
## Experiment Ideas
|
||||
## Experiment Boundaries
|
||||
|
||||
### Form Structure Experiments
|
||||
Do **not** test:
|
||||
|
||||
**Layout & Flow**
|
||||
- Single-step form vs. multi-step with progress bar
|
||||
- 1-column vs. 2-column field layout
|
||||
- Form embedded on page vs. separate page
|
||||
- Vertical vs. horizontal field alignment
|
||||
- Form above fold vs. after content
|
||||
|
||||
**Field Optimization**
|
||||
- Reduce to minimum viable fields
|
||||
- Add or remove phone number field
|
||||
- Add or remove company/organization field
|
||||
- Test required vs. optional field balance
|
||||
- Use field enrichment to auto-fill known data
|
||||
- Hide fields for returning/known visitors
|
||||
|
||||
**Smart Forms**
|
||||
- Add real-time validation for emails and phone numbers
|
||||
- Progressive profiling (ask more over time)
|
||||
- Conditional fields based on earlier answers
|
||||
- Auto-suggest for company names
|
||||
* legal requirements
|
||||
* core qualification fields without alignment
|
||||
* multiple variables at once
|
||||
|
||||
---
|
||||
|
||||
### Copy & Design Experiments
|
||||
## Questions to Ask (If Needed)
|
||||
|
||||
**Labels & Microcopy**
|
||||
- Test field label clarity and length
|
||||
- Placeholder text optimization
|
||||
- Help text: show vs. hide vs. on-hover
|
||||
- Error message tone (friendly vs. direct)
|
||||
|
||||
**CTAs & Buttons**
|
||||
- Button text variations ("Submit" vs. "Get My Quote" vs. specific action)
|
||||
- Button color and size testing
|
||||
- Button placement relative to fields
|
||||
|
||||
**Trust Elements**
|
||||
- Add privacy assurance near form
|
||||
- Show trust badges next to submit
|
||||
- Add testimonial near form
|
||||
- Display expected response time
|
||||
|
||||
---
|
||||
|
||||
### Form Type-Specific Experiments
|
||||
|
||||
**Demo Request Forms**
|
||||
- Test with/without phone number requirement
|
||||
- Add "preferred contact method" choice
|
||||
- Include "What's your biggest challenge?" question
|
||||
- Test calendar embed vs. form submission
|
||||
|
||||
**Lead Capture Forms**
|
||||
- Email-only vs. email + name
|
||||
- Test value proposition messaging above form
|
||||
- Gated vs. ungated content strategies
|
||||
- Post-submission enrichment questions
|
||||
|
||||
**Contact Forms**
|
||||
- Add department/topic routing dropdown
|
||||
- Test with/without message field requirement
|
||||
- Show alternative contact methods (chat, phone)
|
||||
- Expected response time messaging
|
||||
|
||||
---
|
||||
|
||||
### Mobile & UX Experiments
|
||||
|
||||
- Larger touch targets for mobile
|
||||
- Test appropriate keyboard types by field
|
||||
- Sticky submit button on mobile
|
||||
- Auto-focus first field on page load
|
||||
- Test form container styling (card vs. minimal)
|
||||
|
||||
---
|
||||
|
||||
## Questions to Ask
|
||||
|
||||
If you need more context:
|
||||
1. What's your current form completion rate?
|
||||
2. Do you have field-level analytics?
|
||||
3. What happens with the data after submission?
|
||||
4. Which fields are actually used in follow-up?
|
||||
5. Are there compliance/legal requirements?
|
||||
6. What's the mobile vs. desktop split?
|
||||
1. What is the current completion rate?
|
||||
2. Which fields are actually used?
|
||||
3. Do you have field-level analytics?
|
||||
4. What happens after submission?
|
||||
5. Are there compliance constraints?
|
||||
6. Mobile vs desktop traffic split?
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- **signup-flow-cro**: For account creation forms
|
||||
- **popup-cro**: For forms inside popups/modals
|
||||
- **page-cro**: For the page containing the form
|
||||
- **ab-test-setup**: For testing form changes
|
||||
* **signup-flow-cro** – Account creation forms
|
||||
* **popup-cro** – Forms in modals
|
||||
* **page-cro** – Page-level optimization
|
||||
* **analytics-tracking** – Measuring form performance
|
||||
* **ab-test-setup** – Testing form changes
|
||||
|
||||
---
|
||||
|
||||
@@ -1,42 +1,272 @@
|
||||
---
|
||||
name: frontend-design
|
||||
description: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.
|
||||
description: Create distinctive, production-grade frontend interfaces with intentional aesthetics, high craft, and non-generic visual identity. Use when building or styling web UIs, components, pages, dashboards, or frontend applications.
|
||||
license: Complete terms in LICENSE.txt
|
||||
---
|
||||
|
||||
This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices.
|
||||
# Frontend Design (Distinctive, Production-Grade)
|
||||
|
||||
The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints.
|
||||
You are a **frontend designer-engineer**, not a layout generator.
|
||||
|
||||
## Design Thinking
|
||||
Your goal is to create **memorable, high-craft interfaces** that:
|
||||
|
||||
Before coding, understand the context and commit to a BOLD aesthetic direction:
|
||||
- **Purpose**: What problem does this interface solve? Who uses it?
|
||||
- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.
|
||||
- **Constraints**: Technical requirements (framework, performance, accessibility).
|
||||
- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?
|
||||
* Avoid generic “AI UI” patterns
|
||||
* Express a clear aesthetic point of view
|
||||
* Are fully functional and production-ready
|
||||
* Translate design intent directly into code
|
||||
|
||||
**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
|
||||
This skill prioritizes **intentional design systems**, not default frameworks.
|
||||
|
||||
Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is:
|
||||
- Production-grade and functional
|
||||
- Visually striking and memorable
|
||||
- Cohesive with a clear aesthetic point-of-view
|
||||
- Meticulously refined in every detail
|
||||
---
|
||||
|
||||
## Frontend Aesthetics Guidelines
|
||||
## 1. Core Design Mandate
|
||||
|
||||
Focus on:
|
||||
- **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.
|
||||
- **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.
|
||||
- **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.
|
||||
- **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.
|
||||
- **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.
|
||||
Every output must satisfy **all four**:
|
||||
|
||||
NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.
|
||||
1. **Intentional Aesthetic Direction**
|
||||
A named, explicit design stance (e.g. *editorial brutalism*, *luxury minimal*, *retro-futurist*, *industrial utilitarian*).
|
||||
|
||||
Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.
|
||||
2. **Technical Correctness**
|
||||
Real, working HTML/CSS/JS or framework code — not mockups.
|
||||
|
||||
**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
|
||||
3. **Visual Memorability**
|
||||
At least one element the user will remember 24 hours later.
|
||||
|
||||
Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.
|
||||
4. **Cohesive Restraint**
|
||||
No random decoration. Every flourish must serve the aesthetic thesis.
|
||||
|
||||
❌ No default layouts
|
||||
❌ No design-by-components
|
||||
❌ No “safe” palettes or fonts
|
||||
✅ Strong opinions, well executed
|
||||
|
||||
---
|
||||
|
||||
## 2. Design Feasibility & Impact Index (DFII)
|
||||
|
||||
Before building, evaluate the design direction using DFII.
|
||||
|
||||
### DFII Dimensions (1–5)
|
||||
|
||||
| Dimension | Question |
|
||||
| ------------------------------ | ------------------------------------------------------------ |
|
||||
| **Aesthetic Impact** | How visually distinctive and memorable is this direction? |
|
||||
| **Context Fit** | Does this aesthetic suit the product, audience, and purpose? |
|
||||
| **Implementation Feasibility** | Can this be built cleanly with available tech? |
|
||||
| **Performance Safety** | Will it remain fast and accessible? |
|
||||
| **Consistency Risk** | Can this be maintained across screens/components? |
|
||||
|
||||
### Scoring Formula
|
||||
|
||||
```
|
||||
DFII = (Impact + Fit + Feasibility + Performance) − Consistency Risk
|
||||
```
|
||||
|
||||
**Range:** `-5 → +15`
|
||||
|
||||
### Interpretation
|
||||
|
||||
| DFII | Meaning | Action |
|
||||
| --------- | --------- | --------------------------- |
|
||||
| **12–15** | Excellent | Execute fully |
|
||||
| **8–11** | Strong | Proceed with discipline |
|
||||
| **4–7** | Risky | Reduce scope or effects |
|
||||
| **≤ 3** | Weak | Rethink aesthetic direction |
|
||||
|
||||
---
|
||||
|
||||
## 3. Mandatory Design Thinking Phase
|
||||
|
||||
Before writing code, explicitly define:
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
* What action should this interface enable?
|
||||
* Is it persuasive, functional, exploratory, or expressive?
|
||||
|
||||
### 2. Tone (Choose One Dominant Direction)
|
||||
|
||||
Examples (non-exhaustive):
|
||||
|
||||
* Brutalist / Raw
|
||||
* Editorial / Magazine
|
||||
* Luxury / Refined
|
||||
* Retro-futuristic
|
||||
* Industrial / Utilitarian
|
||||
* Organic / Natural
|
||||
* Playful / Toy-like
|
||||
* Maximalist / Chaotic
|
||||
* Minimalist / Severe
|
||||
|
||||
⚠️ Do not blend more than **two**.
|
||||
|
||||
### 3. Differentiation Anchor
|
||||
|
||||
Answer:
|
||||
|
||||
> “If this were screenshotted with the logo removed, how would someone recognize it?”
|
||||
|
||||
This anchor must be visible in the final UI.
|
||||
|
||||
---
|
||||
|
||||
## 4. Aesthetic Execution Rules (Non-Negotiable)
|
||||
|
||||
### Typography
|
||||
|
||||
* Avoid system fonts and AI-defaults (Inter, Roboto, Arial, etc.)
|
||||
* Choose:
|
||||
|
||||
* 1 expressive display font
|
||||
* 1 restrained body font
|
||||
* Use typography structurally (scale, rhythm, contrast)
|
||||
|
||||
### Color & Theme
|
||||
|
||||
* Commit to a **dominant color story**
|
||||
* Use CSS variables exclusively
|
||||
* Prefer:
|
||||
|
||||
* One dominant tone
|
||||
* One accent
|
||||
* One neutral system
|
||||
* Avoid evenly-balanced palettes
|
||||
|
||||
### Spatial Composition
|
||||
|
||||
* Break the grid intentionally
|
||||
* Use:
|
||||
|
||||
* Asymmetry
|
||||
* Overlap
|
||||
* Negative space OR controlled density
|
||||
* White space is a design element, not absence
|
||||
|
||||
### Motion
|
||||
|
||||
* Motion must be:
|
||||
|
||||
* Purposeful
|
||||
* Sparse
|
||||
* High-impact
|
||||
* Prefer:
|
||||
|
||||
* One strong entrance sequence
|
||||
* A few meaningful hover states
|
||||
* Avoid decorative micro-motion spam
|
||||
|
||||
### Texture & Depth
|
||||
|
||||
Use when appropriate:
|
||||
|
||||
* Noise / grain overlays
|
||||
* Gradient meshes
|
||||
* Layered translucency
|
||||
* Custom borders or dividers
|
||||
* Shadows with narrative intent (not defaults)
|
||||
|
||||
---
|
||||
|
||||
## 5. Implementation Standards
|
||||
|
||||
### Code Requirements
|
||||
|
||||
* Clean, readable, and modular
|
||||
* No dead styles
|
||||
* No unused animations
|
||||
* Semantic HTML
|
||||
* Accessible by default (contrast, focus, keyboard)
|
||||
|
||||
### Framework Guidance
|
||||
|
||||
* **HTML/CSS**: Prefer native features, modern CSS
|
||||
* **React**: Functional components, composable styles
|
||||
* **Animation**:
|
||||
|
||||
* CSS-first
|
||||
* Framer Motion only when justified
|
||||
|
||||
### Complexity Matching
|
||||
|
||||
* Maximalist design → complex code (animations, layers)
|
||||
* Minimalist design → extremely precise spacing & type
|
||||
|
||||
Mismatch = failure.
|
||||
|
||||
---
|
||||
|
||||
## 6. Required Output Structure
|
||||
|
||||
When generating frontend work:
|
||||
|
||||
### 1. Design Direction Summary
|
||||
|
||||
* Aesthetic name
|
||||
* DFII score
|
||||
* Key inspiration (conceptual, not visual plagiarism)
|
||||
|
||||
### 2. Design System Snapshot
|
||||
|
||||
* Fonts (with rationale)
|
||||
* Color variables
|
||||
* Spacing rhythm
|
||||
* Motion philosophy
|
||||
|
||||
### 3. Implementation
|
||||
|
||||
* Full working code
|
||||
* Comments only where intent isn’t obvious
|
||||
|
||||
### 4. Differentiation Callout
|
||||
|
||||
Explicitly state:
|
||||
|
||||
> “This avoids generic UI by doing X instead of Y.”
|
||||
|
||||
---
|
||||
|
||||
## 7. Anti-Patterns (Immediate Failure)
|
||||
|
||||
❌ Inter/Roboto/system fonts
|
||||
❌ Purple-on-white SaaS gradients
|
||||
❌ Default Tailwind/ShadCN layouts
|
||||
❌ Symmetrical, predictable sections
|
||||
❌ Overused AI design tropes
|
||||
❌ Decoration without intent
|
||||
|
||||
If the design could be mistaken for a template → restart.
|
||||
|
||||
---
|
||||
|
||||
## 8. Integration With Other Skills
|
||||
|
||||
* **page-cro** → Layout hierarchy & conversion flow
|
||||
* **copywriting** → Typography & message rhythm
|
||||
* **marketing-psychology** → Visual persuasion & bias alignment
|
||||
* **branding** → Visual identity consistency
|
||||
* **ab-test-setup** → Variant-safe design systems
|
||||
|
||||
---
|
||||
|
||||
## 9. Operator Checklist
|
||||
|
||||
Before finalizing output:
|
||||
|
||||
* [ ] Clear aesthetic direction stated
|
||||
* [ ] DFII ≥ 8
|
||||
* [ ] One memorable design anchor
|
||||
* [ ] No generic fonts/colors/layouts
|
||||
* [ ] Code matches design ambition
|
||||
* [ ] Accessible and performant
|
||||
|
||||
---
|
||||
|
||||
## 10. Questions to Ask (If Needed)
|
||||
|
||||
1. Who is this for, emotionally?
|
||||
2. Should this feel trustworthy, exciting, calm, or provocative?
|
||||
3. Is memorability or clarity more important?
|
||||
4. Will this scale to other pages/components?
|
||||
5. What should users *feel* in the first 3 seconds?
|
||||
|
||||
---
|
||||
|
||||
@@ -1,354 +1,284 @@
|
||||
---
|
||||
name: frontend-dev-guidelines
|
||||
description: Frontend development guidelines for React/TypeScript applications. Modern patterns including Suspense, lazy loading, useSuspenseQuery, file organization with features directory, MUI v7 styling, TanStack Router, performance optimization, and TypeScript best practices. Use when creating components, pages, features, fetching data, styling, routing, or working with frontend code.
|
||||
description: Opinionated frontend development standards for modern React + TypeScript applications. Covers Suspense-first data fetching, lazy loading, feature-based architecture, MUI v7 styling, TanStack Router, performance optimization, and strict TypeScript practices.
|
||||
---
|
||||
|
||||
|
||||
# Frontend Development Guidelines
|
||||
|
||||
## Purpose
|
||||
**(React · TypeScript · Suspense-First · Production-Grade)**
|
||||
|
||||
Comprehensive guide for modern React development, emphasizing Suspense-based data fetching, lazy loading, proper file organization, and performance optimization.
|
||||
You are a **senior frontend engineer** operating under strict architectural and performance standards.
|
||||
|
||||
## When to Use This Skill
|
||||
Your goal is to build **scalable, predictable, and maintainable React applications** using:
|
||||
|
||||
- Creating new components or pages
|
||||
- Building new features
|
||||
- Fetching data with TanStack Query
|
||||
- Setting up routing with TanStack Router
|
||||
- Styling components with MUI v7
|
||||
- Performance optimization
|
||||
- Organizing frontend code
|
||||
- TypeScript best practices
|
||||
* Suspense-first data fetching
|
||||
* Feature-based code organization
|
||||
* Strict TypeScript discipline
|
||||
* Performance-safe defaults
|
||||
|
||||
This skill defines **how frontend code must be written**, not merely how it *can* be written.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
## 1. Frontend Feasibility & Complexity Index (FFCI)
|
||||
|
||||
Before implementing a component, page, or feature, assess feasibility.
|
||||
|
||||
### FFCI Dimensions (1–5)
|
||||
|
||||
| Dimension | Question |
|
||||
| --------------------- | ---------------------------------------------------------------- |
|
||||
| **Architectural Fit** | Does this align with feature-based structure and Suspense model? |
|
||||
| **Complexity Load** | How complex is state, data, and interaction logic? |
|
||||
| **Performance Risk** | Does it introduce rendering, bundle, or CLS risk? |
|
||||
| **Reusability** | Can this be reused without modification? |
|
||||
| **Maintenance Cost** | How hard will this be to reason about in 6 months? |
|
||||
|
||||
### Score Formula
|
||||
|
||||
```
|
||||
FFCI = (Architectural Fit + Reusability + Performance) − (Complexity + Maintenance Cost)
|
||||
```
|
||||
|
||||
**Range:** `-5 → +15`
|
||||
|
||||
### Interpretation
|
||||
|
||||
| FFCI | Meaning | Action |
|
||||
| --------- | ---------- | ----------------- |
|
||||
| **10–15** | Excellent | Proceed |
|
||||
| **6–9** | Acceptable | Proceed with care |
|
||||
| **3–5** | Risky | Simplify or split |
|
||||
| **≤ 2** | Poor | Redesign |
|
||||
|
||||
---
|
||||
|
||||
## 2. Core Architectural Doctrine (Non-Negotiable)
|
||||
|
||||
### 1. Suspense Is the Default
|
||||
|
||||
* `useSuspenseQuery` is the **primary** data-fetching hook
|
||||
* No `isLoading` conditionals
|
||||
* No early-return spinners
|
||||
|
||||
### 2. Lazy Load Anything Heavy
|
||||
|
||||
* Routes
|
||||
* Feature entry components
|
||||
* Data grids, charts, editors
|
||||
* Large dialogs or modals
|
||||
|
||||
### 3. Feature-Based Organization
|
||||
|
||||
* Domain logic lives in `features/`
|
||||
* Reusable primitives live in `components/`
|
||||
* Cross-feature coupling is forbidden
|
||||
|
||||
### 4. TypeScript Is Strict
|
||||
|
||||
* No `any`
|
||||
* Explicit return types
|
||||
* `import type` always
|
||||
* Types are first-class design artifacts
|
||||
|
||||
---
|
||||
|
||||
## 3. When to Use This Skill
|
||||
|
||||
Use **frontend-dev-guidelines** when:
|
||||
|
||||
* Creating components or pages
|
||||
* Adding new features
|
||||
* Fetching or mutating data
|
||||
* Setting up routing
|
||||
* Styling with MUI
|
||||
* Addressing performance issues
|
||||
* Reviewing or refactoring frontend code
|
||||
|
||||
---
|
||||
|
||||
## 4. Quick Start Checklists
|
||||
|
||||
### New Component Checklist
|
||||
|
||||
Creating a component? Follow this checklist:
|
||||
* [ ] `React.FC<Props>` with explicit props interface
|
||||
* [ ] Lazy loaded if non-trivial
|
||||
* [ ] Wrapped in `<SuspenseLoader>`
|
||||
* [ ] Uses `useSuspenseQuery` for data
|
||||
* [ ] No early returns
|
||||
* [ ] Handlers wrapped in `useCallback`
|
||||
* [ ] Styles inline if <100 lines
|
||||
* [ ] Default export at bottom
|
||||
* [ ] Uses `useMuiSnackbar` for feedback
|
||||
|
||||
- [ ] Use `React.FC<Props>` pattern with TypeScript
|
||||
- [ ] Lazy load if heavy component: `React.lazy(() => import())`
|
||||
- [ ] Wrap in `<SuspenseLoader>` for loading states
|
||||
- [ ] Use `useSuspenseQuery` for data fetching
|
||||
- [ ] Import aliases: `@/`, `~types`, `~components`, `~features`
|
||||
- [ ] Styles: Inline if <100 lines, separate file if >100 lines
|
||||
- [ ] Use `useCallback` for event handlers passed to children
|
||||
- [ ] Default export at bottom
|
||||
- [ ] No early returns with loading spinners
|
||||
- [ ] Use `useMuiSnackbar` for user notifications
|
||||
---
|
||||
|
||||
### New Feature Checklist
|
||||
|
||||
Creating a feature? Set up this structure:
|
||||
|
||||
- [ ] Create `features/{feature-name}/` directory
|
||||
- [ ] Create subdirectories: `api/`, `components/`, `hooks/`, `helpers/`, `types/`
|
||||
- [ ] Create API service file: `api/{feature}Api.ts`
|
||||
- [ ] Set up TypeScript types in `types/`
|
||||
- [ ] Create route in `routes/{feature-name}/index.tsx`
|
||||
- [ ] Lazy load feature components
|
||||
- [ ] Use Suspense boundaries
|
||||
- [ ] Export public API from feature `index.ts`
|
||||
* [ ] Create `features/{feature-name}/`
|
||||
* [ ] Subdirs: `api/`, `components/`, `hooks/`, `helpers/`, `types/`
|
||||
* [ ] API layer isolated in `api/`
|
||||
* [ ] Public exports via `index.ts`
|
||||
* [ ] Feature entry lazy loaded
|
||||
* [ ] Suspense boundary at feature level
|
||||
* [ ] Route defined under `routes/`
|
||||
|
||||
---
|
||||
|
||||
## Import Aliases Quick Reference
|
||||
## 5. Import Aliases (Required)
|
||||
|
||||
| Alias | Resolves To | Example |
|
||||
|-------|-------------|---------|
|
||||
| `@/` | `src/` | `import { apiClient } from '@/lib/apiClient'` |
|
||||
| `~types` | `src/types` | `import type { User } from '~types/user'` |
|
||||
| `~components` | `src/components` | `import { SuspenseLoader } from '~components/SuspenseLoader'` |
|
||||
| `~features` | `src/features` | `import { authApi } from '~features/auth'` |
|
||||
| Alias | Path |
|
||||
| ------------- | ---------------- |
|
||||
| `@/` | `src/` |
|
||||
| `~types` | `src/types` |
|
||||
| `~components` | `src/components` |
|
||||
| `~features` | `src/features` |
|
||||
|
||||
Defined in: [vite.config.ts](../../vite.config.ts) lines 180-185
|
||||
Aliases must be used consistently. Relative imports beyond one level are discouraged.
|
||||
|
||||
---
|
||||
|
||||
## Common Imports Cheatsheet
|
||||
## 6. Component Standards
|
||||
|
||||
```typescript
|
||||
// React & Lazy Loading
|
||||
import React, { useState, useCallback, useMemo } from 'react';
|
||||
const Heavy = React.lazy(() => import('./Heavy'));
|
||||
### Required Structure Order
|
||||
|
||||
// MUI Components
|
||||
import { Box, Paper, Typography, Button, Grid } from '@mui/material';
|
||||
import type { SxProps, Theme } from '@mui/material';
|
||||
1. Types / Props
|
||||
2. Hooks
|
||||
3. Derived values (`useMemo`)
|
||||
4. Handlers (`useCallback`)
|
||||
5. Render
|
||||
6. Default export
|
||||
|
||||
// TanStack Query (Suspense)
|
||||
import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query';
|
||||
### Lazy Loading Pattern
|
||||
|
||||
// TanStack Router
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
// Project Components
|
||||
import { SuspenseLoader } from '~components/SuspenseLoader';
|
||||
|
||||
// Hooks
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { useMuiSnackbar } from '@/hooks/useMuiSnackbar';
|
||||
|
||||
// Types
|
||||
import type { Post } from '~types/post';
|
||||
```ts
|
||||
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Topic Guides
|
||||
|
||||
### 🎨 Component Patterns
|
||||
|
||||
**Modern React components use:**
|
||||
- `React.FC<Props>` for type safety
|
||||
- `React.lazy()` for code splitting
|
||||
- `SuspenseLoader` for loading states
|
||||
- Named const + default export pattern
|
||||
|
||||
**Key Concepts:**
|
||||
- Lazy load heavy components (DataGrid, charts, editors)
|
||||
- Always wrap lazy components in Suspense
|
||||
- Use SuspenseLoader component (with fade animation)
|
||||
- Component structure: Props → Hooks → Handlers → Render → Export
|
||||
|
||||
**[📖 Complete Guide: resources/component-patterns.md](resources/component-patterns.md)**
|
||||
Always wrapped in `<SuspenseLoader>`.
|
||||
|
||||
---
|
||||
|
||||
### 📊 Data Fetching
|
||||
## 7. Data Fetching Doctrine
|
||||
|
||||
**PRIMARY PATTERN: useSuspenseQuery**
|
||||
- Use with Suspense boundaries
|
||||
- Cache-first strategy (check grid cache before API)
|
||||
- Replaces `isLoading` checks
|
||||
- Type-safe with generics
|
||||
### Primary Pattern
|
||||
|
||||
**API Service Layer:**
|
||||
- Create `features/{feature}/api/{feature}Api.ts`
|
||||
- Use `apiClient` axios instance
|
||||
- Centralized methods per feature
|
||||
- Route format: `/form/route` (NOT `/api/form/route`)
|
||||
* `useSuspenseQuery`
|
||||
* Cache-first
|
||||
* Typed responses
|
||||
|
||||
**[📖 Complete Guide: resources/data-fetching.md](resources/data-fetching.md)**
|
||||
### Forbidden Patterns
|
||||
|
||||
❌ `isLoading`
|
||||
❌ manual spinners
|
||||
❌ fetch logic inside components
|
||||
❌ API calls without feature API layer
|
||||
|
||||
### API Layer Rules
|
||||
|
||||
* One API file per feature
|
||||
* No inline axios calls
|
||||
* No `/api/` prefix in routes
|
||||
|
||||
---
|
||||
|
||||
### 📁 File Organization
|
||||
## 8. Routing Standards (TanStack Router)
|
||||
|
||||
**features/ vs components/:**
|
||||
- `features/`: Domain-specific (posts, comments, auth)
|
||||
- `components/`: Truly reusable (SuspenseLoader, CustomAppBar)
|
||||
|
||||
**Feature Subdirectories:**
|
||||
```
|
||||
features/
|
||||
my-feature/
|
||||
api/ # API service layer
|
||||
components/ # Feature components
|
||||
hooks/ # Custom hooks
|
||||
helpers/ # Utility functions
|
||||
types/ # TypeScript types
|
||||
```
|
||||
|
||||
**[📖 Complete Guide: resources/file-organization.md](resources/file-organization.md)**
|
||||
|
||||
---
|
||||
|
||||
### 🎨 Styling
|
||||
|
||||
**Inline vs Separate:**
|
||||
- <100 lines: Inline `const styles: Record<string, SxProps<Theme>>`
|
||||
- >100 lines: Separate `.styles.ts` file
|
||||
|
||||
**Primary Method:**
|
||||
- Use `sx` prop for MUI components
|
||||
- Type-safe with `SxProps<Theme>`
|
||||
- Theme access: `(theme) => theme.palette.primary.main`
|
||||
|
||||
**MUI v7 Grid:**
|
||||
```typescript
|
||||
<Grid size={{ xs: 12, md: 6 }}> // ✅ v7 syntax
|
||||
<Grid xs={12} md={6}> // ❌ Old syntax
|
||||
```
|
||||
|
||||
**[📖 Complete Guide: resources/styling-guide.md](resources/styling-guide.md)**
|
||||
|
||||
---
|
||||
|
||||
### 🛣️ Routing
|
||||
|
||||
**TanStack Router - Folder-Based:**
|
||||
- Directory: `routes/my-route/index.tsx`
|
||||
- Lazy load components
|
||||
- Use `createFileRoute`
|
||||
- Breadcrumb data in loader
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { lazy } from 'react';
|
||||
|
||||
const MyPage = lazy(() => import('@/features/my-feature/components/MyPage'));
|
||||
* Folder-based routing only
|
||||
* Lazy load route components
|
||||
* Breadcrumb metadata via loaders
|
||||
|
||||
```ts
|
||||
export const Route = createFileRoute('/my-route/')({
|
||||
component: MyPage,
|
||||
loader: () => ({ crumb: 'My Route' }),
|
||||
component: MyPage,
|
||||
loader: () => ({ crumb: 'My Route' }),
|
||||
});
|
||||
```
|
||||
|
||||
**[📖 Complete Guide: resources/routing-guide.md](resources/routing-guide.md)**
|
||||
|
||||
---
|
||||
|
||||
### ⏳ Loading & Error States
|
||||
## 9. Styling Standards (MUI v7)
|
||||
|
||||
**CRITICAL RULE: No Early Returns**
|
||||
### Inline vs Separate
|
||||
|
||||
```typescript
|
||||
// ❌ NEVER - Causes layout shift
|
||||
if (isLoading) {
|
||||
return <LoadingSpinner />;
|
||||
}
|
||||
* `<100 lines`: inline `sx`
|
||||
* `>100 lines`: `{Component}.styles.ts`
|
||||
|
||||
// ✅ ALWAYS - Consistent layout
|
||||
<SuspenseLoader>
|
||||
<Content />
|
||||
</SuspenseLoader>
|
||||
### Grid Syntax (v7 Only)
|
||||
|
||||
```tsx
|
||||
<Grid size={{ xs: 12, md: 6 }} /> // ✅
|
||||
<Grid xs={12} md={6} /> // ❌
|
||||
```
|
||||
|
||||
**Why:** Prevents Cumulative Layout Shift (CLS), better UX
|
||||
|
||||
**Error Handling:**
|
||||
- Use `useMuiSnackbar` for user feedback
|
||||
- NEVER `react-toastify`
|
||||
- TanStack Query `onError` callbacks
|
||||
|
||||
**[📖 Complete Guide: resources/loading-and-error-states.md](resources/loading-and-error-states.md)**
|
||||
Theme access must always be type-safe.
|
||||
|
||||
---
|
||||
|
||||
### ⚡ Performance
|
||||
## 10. Loading & Error Handling
|
||||
|
||||
**Optimization Patterns:**
|
||||
- `useMemo`: Expensive computations (filter, sort, map)
|
||||
- `useCallback`: Event handlers passed to children
|
||||
- `React.memo`: Expensive components
|
||||
- Debounced search (300-500ms)
|
||||
- Memory leak prevention (cleanup in useEffect)
|
||||
### Absolute Rule
|
||||
|
||||
**[📖 Complete Guide: resources/performance.md](resources/performance.md)**
|
||||
❌ Never return early loaders
|
||||
✅ Always rely on Suspense boundaries
|
||||
|
||||
### User Feedback
|
||||
|
||||
* `useMuiSnackbar` only
|
||||
* No third-party toast libraries
|
||||
|
||||
---
|
||||
|
||||
### 📘 TypeScript
|
||||
## 11. Performance Defaults
|
||||
|
||||
**Standards:**
|
||||
- Strict mode, no `any` type
|
||||
- Explicit return types on functions
|
||||
- Type imports: `import type { User } from '~types/user'`
|
||||
- Component prop interfaces with JSDoc
|
||||
* `useMemo` for expensive derivations
|
||||
* `useCallback` for passed handlers
|
||||
* `React.memo` for heavy pure components
|
||||
* Debounce search (300–500ms)
|
||||
* Cleanup effects to avoid leaks
|
||||
|
||||
**[📖 Complete Guide: resources/typescript-standards.md](resources/typescript-standards.md)**
|
||||
Performance regressions are bugs.
|
||||
|
||||
---
|
||||
|
||||
### 🔧 Common Patterns
|
||||
## 12. TypeScript Standards
|
||||
|
||||
**Covered Topics:**
|
||||
- React Hook Form with Zod validation
|
||||
- DataGrid wrapper contracts
|
||||
- Dialog component standards
|
||||
- `useAuth` hook for current user
|
||||
- Mutation patterns with cache invalidation
|
||||
|
||||
**[📖 Complete Guide: resources/common-patterns.md](resources/common-patterns.md)**
|
||||
* Strict mode enabled
|
||||
* No implicit `any`
|
||||
* Explicit return types
|
||||
* JSDoc on public interfaces
|
||||
* Types colocated with feature
|
||||
|
||||
---
|
||||
|
||||
### 📚 Complete Examples
|
||||
|
||||
**Full working examples:**
|
||||
- Modern component with all patterns
|
||||
- Complete feature structure
|
||||
- API service layer
|
||||
- Route with lazy loading
|
||||
- Suspense + useSuspenseQuery
|
||||
- Form with validation
|
||||
|
||||
**[📖 Complete Guide: resources/complete-examples.md](resources/complete-examples.md)**
|
||||
|
||||
---
|
||||
|
||||
## Navigation Guide
|
||||
|
||||
| Need to... | Read this resource |
|
||||
|------------|-------------------|
|
||||
| Create a component | [component-patterns.md](resources/component-patterns.md) |
|
||||
| Fetch data | [data-fetching.md](resources/data-fetching.md) |
|
||||
| Organize files/folders | [file-organization.md](resources/file-organization.md) |
|
||||
| Style components | [styling-guide.md](resources/styling-guide.md) |
|
||||
| Set up routing | [routing-guide.md](resources/routing-guide.md) |
|
||||
| Handle loading/errors | [loading-and-error-states.md](resources/loading-and-error-states.md) |
|
||||
| Optimize performance | [performance.md](resources/performance.md) |
|
||||
| TypeScript types | [typescript-standards.md](resources/typescript-standards.md) |
|
||||
| Forms/Auth/DataGrid | [common-patterns.md](resources/common-patterns.md) |
|
||||
| See full examples | [complete-examples.md](resources/complete-examples.md) |
|
||||
|
||||
---
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Lazy Load Everything Heavy**: Routes, DataGrid, charts, editors
|
||||
2. **Suspense for Loading**: Use SuspenseLoader, not early returns
|
||||
3. **useSuspenseQuery**: Primary data fetching pattern for new code
|
||||
4. **Features are Organized**: api/, components/, hooks/, helpers/ subdirs
|
||||
5. **Styles Based on Size**: <100 inline, >100 separate
|
||||
6. **Import Aliases**: Use @/, ~types, ~components, ~features
|
||||
7. **No Early Returns**: Prevents layout shift
|
||||
8. **useMuiSnackbar**: For all user notifications
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: File Structure
|
||||
## 13. Canonical File Structure
|
||||
|
||||
```
|
||||
src/
|
||||
features/
|
||||
my-feature/
|
||||
api/
|
||||
myFeatureApi.ts # API service
|
||||
components/
|
||||
MyFeature.tsx # Main component
|
||||
SubComponent.tsx # Related components
|
||||
hooks/
|
||||
useMyFeature.ts # Custom hooks
|
||||
useSuspenseMyFeature.ts # Suspense hooks
|
||||
helpers/
|
||||
myFeatureHelpers.ts # Utilities
|
||||
types/
|
||||
index.ts # TypeScript types
|
||||
index.ts # Public exports
|
||||
index.ts
|
||||
|
||||
components/
|
||||
SuspenseLoader/
|
||||
SuspenseLoader.tsx # Reusable loader
|
||||
CustomAppBar/
|
||||
CustomAppBar.tsx # Reusable app bar
|
||||
|
||||
routes/
|
||||
my-route/
|
||||
index.tsx # Route component
|
||||
create/
|
||||
index.tsx # Nested route
|
||||
index.tsx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modern Component Template (Quick Copy)
|
||||
## 14. Canonical Component Template
|
||||
|
||||
```typescript
|
||||
```ts
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { Box, Paper } from '@mui/material';
|
||||
import { useSuspenseQuery } from '@tanstack/react-query';
|
||||
@@ -356,44 +286,74 @@ import { featureApi } from '../api/featureApi';
|
||||
import type { FeatureData } from '~types/feature';
|
||||
|
||||
interface MyComponentProps {
|
||||
id: number;
|
||||
onAction?: () => void;
|
||||
id: number;
|
||||
onAction?: () => void;
|
||||
}
|
||||
|
||||
export const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {
|
||||
const [state, setState] = useState<string>('');
|
||||
const [state, setState] = useState('');
|
||||
|
||||
const { data } = useSuspenseQuery({
|
||||
queryKey: ['feature', id],
|
||||
queryFn: () => featureApi.getFeature(id),
|
||||
});
|
||||
const { data } = useSuspenseQuery<FeatureData>({
|
||||
queryKey: ['feature', id],
|
||||
queryFn: () => featureApi.getFeature(id),
|
||||
});
|
||||
|
||||
const handleAction = useCallback(() => {
|
||||
setState('updated');
|
||||
onAction?.();
|
||||
}, [onAction]);
|
||||
const handleAction = useCallback(() => {
|
||||
setState('updated');
|
||||
onAction?.();
|
||||
}, [onAction]);
|
||||
|
||||
return (
|
||||
<Box sx={{ p: 2 }}>
|
||||
<Paper sx={{ p: 3 }}>
|
||||
{/* Content */}
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
return (
|
||||
<Box sx={{ p: 2 }}>
|
||||
<Paper sx={{ p: 3 }}>
|
||||
{/* Content */}
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyComponent;
|
||||
```
|
||||
|
||||
For complete examples, see [resources/complete-examples.md](resources/complete-examples.md)
|
||||
---
|
||||
|
||||
## 15. Anti-Patterns (Immediate Rejection)
|
||||
|
||||
❌ Early loading returns
|
||||
❌ Feature logic in `components/`
|
||||
❌ Shared state via prop drilling instead of hooks
|
||||
❌ Inline API calls
|
||||
❌ Untyped responses
|
||||
❌ Multiple responsibilities in one component
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
## 16. Integration With Other Skills
|
||||
|
||||
- **error-tracking**: Error tracking with Sentry (applies to frontend too)
|
||||
- **backend-dev-guidelines**: Backend API patterns that frontend consumes
|
||||
* **frontend-design** → Visual systems & aesthetics
|
||||
* **page-cro** → Layout hierarchy & conversion logic
|
||||
* **analytics-tracking** → Event instrumentation
|
||||
* **backend-dev-guidelines** → API contract alignment
|
||||
* **error-tracking** → Runtime observability
|
||||
|
||||
---
|
||||
|
||||
**Skill Status**: Modular structure with progressive loading for optimal context management
|
||||
## 17. Operator Validation Checklist
|
||||
|
||||
Before finalizing code:
|
||||
|
||||
* [ ] FFCI ≥ 6
|
||||
* [ ] Suspense used correctly
|
||||
* [ ] Feature boundaries respected
|
||||
* [ ] No early returns
|
||||
* [ ] Types explicit and correct
|
||||
* [ ] Lazy loading applied
|
||||
* [ ] Performance safe
|
||||
|
||||
---
|
||||
|
||||
## 18. Skill Status
|
||||
|
||||
**Status:** Stable, opinionated, and enforceable
|
||||
**Intended Use:** Production React codebases with long-term maintenance horizons
|
||||
|
||||
|
||||
721
skills/last30days/README.md
Normal file
721
skills/last30days/README.md
Normal file
@@ -0,0 +1,721 @@
|
||||
# /last30days
|
||||
|
||||
**The AI world reinvents itself every month. This Claude Code skill keeps you current.** /last30days researches your topic across Reddit, X, and the web from the last 30 days, finds what the community is actually upvoting and sharing, and writes you a prompt that works today, not six months ago. Whether it's Ralph Wiggum loops, Suno music prompts, or the latest Midjourney techniques, you'll prompt like someone who's been paying attention.
|
||||
|
||||
**Best for prompt research**: discover what prompting techniques actually work for any tool (ChatGPT, Midjourney, Claude, Figma AI, etc.) by learning from real community discussions and best practices.
|
||||
|
||||
**But also great for anything trending**: music, culture, news, product recommendations, viral trends, or any question where "what are people saying right now?" matters.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Clone the repo
|
||||
git clone https://github.com/mvanhorn/last30days-skill.git ~/.claude/skills/last30days
|
||||
|
||||
# Add your API keys
|
||||
mkdir -p ~/.config/last30days
|
||||
cat > ~/.config/last30days/.env << 'EOF'
|
||||
OPENAI_API_KEY=sk-...
|
||||
XAI_API_KEY=xai-...
|
||||
EOF
|
||||
chmod 600 ~/.config/last30days/.env
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/last30days [topic]
|
||||
/last30days [topic] for [tool]
|
||||
```
|
||||
|
||||
Examples:
|
||||
- `/last30days prompting techniques for ChatGPT for legal questions`
|
||||
- `/last30days iOS app mockups for Nano Banana Pro`
|
||||
- `/last30days What are the best rap songs lately`
|
||||
- `/last30days remotion animations for Claude Code`
|
||||
|
||||
## What It Does
|
||||
|
||||
1. **Researches** - Scans Reddit and X for discussions from the last 30 days
|
||||
2. **Synthesizes** - Identifies patterns, best practices, and what actually works
|
||||
3. **Delivers** - Either writes copy-paste-ready prompts for your target tool, or gives you a curated expert-level answer
|
||||
|
||||
### Use it for:
|
||||
- **Prompt research** - "What prompting techniques work for legal questions in ChatGPT?"
|
||||
- **Tool best practices** - "How are people using Remotion with Claude Code?"
|
||||
- **Trend discovery** - "What are the best rap songs right now?"
|
||||
- **Product research** - "What do people think of the new M4 MacBook?"
|
||||
- **Viral content** - "What's the dog-as-human trend on ChatGPT?"
|
||||
|
||||
---
|
||||
|
||||
## Example: Legal Prompting (Hallucination Prevention)
|
||||
|
||||
**Query:** `/last30days prompting techniques for chatgpt for legal questions`
|
||||
|
||||
**Research Output:**
|
||||
> The dominant theme is hallucination prevention - multiple sources discuss lawyers being fined or embarrassed for submitting fake case citations that ChatGPT fabricated. Key prompting strategies include: (1) using Deep Research mode or grounding tools with uploaded primary sources, (2) building "Hallucination Prevention Systems" into prompts that force epistemic honesty, (3) prompting for procedural questions rather than case law lookups, and (4) framing outputs as "issue-spotting" rather than legal advice. A major warning: chat logs are discoverable in litigation.
|
||||
|
||||
**Key patterns discovered:**
|
||||
1. Hallucination prevention clauses - "If you don't know a case citation, say so rather than inventing one"
|
||||
2. Role assignment - assign ChatGPT a specific persona (paralegal, issue-spotter) to constrain outputs
|
||||
3. Structured output requirements - request specific sections (risks, key terms, questions for counsel)
|
||||
4. Epistemic humility enforcement - "acknowledge uncertainty" and "flag when you're unsure"
|
||||
5. Scope limitation - focus on procedural questions, not case law research
|
||||
|
||||
**Then asked:** "I have a squatter in my house in San Francisco, what are my options to get them out?"
|
||||
|
||||
**Generated Prompt:**
|
||||
|
||||
```
|
||||
Role: You are a legal research assistant helping a property owner understand
|
||||
their options. You are NOT providing legal advice - you are helping me
|
||||
identify issues, understand procedures, and prepare informed questions for an
|
||||
attorney.
|
||||
|
||||
Situation: I own a residential property in San Francisco, California. Someone
|
||||
is currently occupying the property without my permission or any lease
|
||||
agreement (a squatter). I need to understand my legal options for removing them.
|
||||
|
||||
Your task: Provide a structured analysis covering:
|
||||
|
||||
1. California/SF Legal Framework - What laws govern this situation? (Note: San
|
||||
Francisco has strong tenant protections - address how these apply or don't
|
||||
apply to squatters vs. tenants)
|
||||
2. Key Distinctions - Help me understand: squatter vs. trespasser vs. holdover
|
||||
tenant. How does the length of occupation affect my options?
|
||||
3. Available Legal Remedies - What are my procedural options? (unlawful
|
||||
detainer, police involvement, etc.) What is the typical process and timeline?
|
||||
4. Critical Mistakes to Avoid - What actions could expose me to liability?
|
||||
(self-help eviction, utility shutoffs, etc.)
|
||||
5. Questions I Should Ask an Attorney - Based on this analysis, what specific
|
||||
questions should I bring to a California real estate attorney?
|
||||
|
||||
Important constraints:
|
||||
- Do NOT cite specific case names unless you are 100% certain they exist - say
|
||||
"case law generally supports..." instead
|
||||
- Flag any areas where you're uncertain
|
||||
- Note where San Francisco local ordinances may differ from California state law
|
||||
- This is for informational purposes to prepare for a legal consultation
|
||||
```
|
||||
|
||||
**The Result:** A comprehensive 2,500+ word analysis covering California's unlawful detainer process, SF Rent Ordinance nuances, trespasser vs. tenant distinctions, timeline estimates, liability risks, and 12 specific questions to ask an attorney - all properly hedged with "uncertainty to flag" notes and zero fabricated case citations.
|
||||
|
||||
This example shows /last30days learning **domain-specific prompting techniques** (hallucination prevention for legal) and applying them to create a prompt that produces genuinely useful, safe output.
|
||||
|
||||
---
|
||||
|
||||
## Example: ClawdBot Use Cases (Community Research)
|
||||
|
||||
**Query:** `/last30days best clawdbot use cases`
|
||||
|
||||
**Research Output:**
|
||||
> ClawdBot is a self-hosted AI assistant that runs on your devices and connects via messaging apps (Telegram, WhatsApp, Discord, Slack, iMessage). Unlike ChatGPT/Claude, it has persistent memory and can proactively message you. The killer feature is its 24/7 autonomous operation - it handles multi-day tasks, monitors for replies, and initiates contact.
|
||||
|
||||
**Most mentioned use cases:**
|
||||
|
||||
🏆 Top 5 by engagement:
|
||||
|
||||
1. **Email/Calendar automation** - mentioned 8x+ (r/selfhosted, @dreetje, @danpeguine, MacStories)
|
||||
- Morning briefings, spam filtering, auto-replies, recruiter declines
|
||||
2. **Task management via chat** - mentioned 6x (r/LocalLLaMA, @danpeguine, multiple X posts)
|
||||
- Todoist integration, importance scoring, time-blocking tasks
|
||||
3. **Overnight coding agent** - mentioned 5x (@bffmike 225 likes, r/LocalLLaMA)
|
||||
- "Drove my coding agents from 12:30-7am while I snoozed"
|
||||
- Pulls repos, runs tests, commits if clean
|
||||
4. **Smart home + life admin** - mentioned 5x (r/selfhosted, VelvetShark)
|
||||
- WHOOP health data, Philips Hue, HomeAssistant, SSH to homelab
|
||||
5. **Browser automation** - mentioned 4x (@steipete 243 likes, MacStories)
|
||||
- Car negotiation via email/PDF, restaurant reservations via ElevenLabs calls
|
||||
|
||||
**Notable single mentions:**
|
||||
- Custom meditation generation with TTS + ambient audio
|
||||
- Built a full website (Stumblereads.com) from phone while putting baby to sleep
|
||||
- Ray-Ban Meta glasses integration
|
||||
- WhatsApp as control interface for everything
|
||||
|
||||
**Research Stats:** 9 Reddit threads (161 upvotes, 95 comments) + 19 X posts (2,018 likes, 96 reposts) from r/LocalLLaMA, r/selfhosted, @steipete, @danpeguine, @dreetje
|
||||
|
||||
This example shows /last30days as a **product research tool** - discovering real-world use cases and community sentiment for any tool or product, complete with engagement metrics that tell you what people actually care about.
|
||||
|
||||
---
|
||||
|
||||
## Example: ClawdBot Setup (Installation Guide)
|
||||
|
||||
**Query:** `/last30days how to best setup clawdbot`
|
||||
|
||||
**Research Output:**
|
||||
> ClawdBot setup varies by deployment style - Docker is the most recommended path, but users are also deploying via bare metal and cloud VMs. The community has converged on key best practices: use the setup wizard for initial config, start with conservative hardware (you can scale up), and configure authentication before exposing any endpoints.
|
||||
|
||||
**🛠️ Setup patterns by engagement:**
|
||||
|
||||
| Pattern | Mentions | Key Sources |
|
||||
|---------|----------|-------------|
|
||||
| Docker Compose deployment | 6x | r/selfhosted, r/LocalLLaMA |
|
||||
| Setup wizard (interactive config) | 5x | @dreetje, documentation |
|
||||
| API key management | 4x | r/selfhosted, security threads |
|
||||
| Hardware requirements | 4x | r/LocalLLaMA (GPU discussions) |
|
||||
| Reverse proxy (Caddy/nginx) | 3x | r/selfhosted |
|
||||
|
||||
**Key setup insights from community:**
|
||||
|
||||
1. **Use the setup wizard** - Don't manually edit config files first; the wizard handles 90% of initial setup
|
||||
2. **Start small on hardware** - 8GB RAM minimum, but 16GB+ recommended if running local models
|
||||
3. **Docker > bare metal** - Easier updates, better isolation, community-tested compose files
|
||||
4. **Secure before exposing** - Set up authentication before opening ports; ClawdBot has built-in auth
|
||||
5. **Cost management** - Set API rate limits early; one user reported $200 overnight bill from runaway tasks
|
||||
|
||||
**Quick-start commands (community-verified):**
|
||||
|
||||
```bash
|
||||
# Clone and setup
|
||||
git clone https://github.com/clawdbot/clawdbot.git
|
||||
cd clawdbot
|
||||
|
||||
# Run setup wizard (recommended)
|
||||
./setup.sh
|
||||
|
||||
# Or Docker Compose (after config)
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
**Common gotchas mentioned:**
|
||||
- Don't forget to set `CLAWDBOT_API_KEY` before first run
|
||||
- Telegram bot token needs BotFather setup first
|
||||
- If using local models, ensure CUDA drivers are installed
|
||||
|
||||
**Research Stats:** 8 Reddit threads (128 upvotes) + 22 X posts (24,000+ likes) from r/selfhosted, r/LocalLLaMA, @dreetje, @steipete
|
||||
|
||||
This example shows /last30days as a **setup guide aggregator** - pulling together scattered installation advice, gotchas, and best practices from real users who've already solved the problems you're about to encounter.
|
||||
|
||||
---
|
||||
|
||||
## Example: iOS App Mockup (Nano Banana Pro)
|
||||
|
||||
**Query:** `/last30days prompting tips for nano banana pro for ios designs`
|
||||
|
||||
**Research Output:**
|
||||
> The community has converged on JSON-structured prompts for UI work - multiple viral posts from @brindleyai, @bananababydoll, and @fofrAI use detailed JSON with nested objects for subject, scene, and style. The key workflow from @fofrAI: take an existing image, have Gemini generate a JSON prompt from it, then iterate. For iOS specifically, @paji_a and @chongdashu both documented using Nano Banana Pro for iOS app mockup designs in "vibe coding" workflows.
|
||||
>
|
||||
> The web guides emphasize thinking in layers: define the window frame first, then UI layout (sidebars, nav bars, cards), then text on buttons/headings. Google's official prompting guide says to drop the "4k masterpiece trending on artstation" spam - Nano Banana Pro understands natural language. For tight layouts, use an 8pt grid and limit screens to 6-8 elements.
|
||||
|
||||
**Key patterns discovered:**
|
||||
1. JSON prompt format with nested sections (subject, scene, style, device)
|
||||
2. Layer-based structure - frame -> layout regions -> content -> text labels
|
||||
3. iOS 18 / Material Design 3 references - rounded corners, soft shadows, vibrant primary
|
||||
4. iPhone frame specification - "inside realistic iPhone 16 Pro frame"
|
||||
5. Wireframe-to-mockup workflow - upload sketch, request high-fidelity conversion
|
||||
6. 8pt grid + 6-8 elements max per screen for clean density
|
||||
7. Iterative editing - don't re-roll, ask for specific changes if 80% correct
|
||||
|
||||
**Then asked:** "make a mock-up of an app for moms who swim"
|
||||
|
||||
**Generated Prompt:**
|
||||
|
||||
```json
|
||||
{
|
||||
"image_type": "UI mockup",
|
||||
"device": {
|
||||
"frame": "iPhone 16 Pro",
|
||||
"display": "realistic screen with subtle reflection",
|
||||
"orientation": "portrait"
|
||||
},
|
||||
"app_concept": "SwimMom - fitness and community app for mothers who swim",
|
||||
"screen": "home dashboard",
|
||||
"design_system": {
|
||||
"style": "iOS 18 native",
|
||||
"corners": "rounded, 16px radius",
|
||||
"shadows": "soft drop shadows, subtle depth",
|
||||
"spacing": "8pt grid, generous whitespace"
|
||||
},
|
||||
"color_palette": {
|
||||
"primary": "calming aqua blue (#4ECDC4)",
|
||||
"secondary": "warm coral (#FF6B6B)",
|
||||
"background": "clean white with soft blue gradient header",
|
||||
"accents": "pool water ripple patterns, subtle"
|
||||
},
|
||||
"layout": {
|
||||
"header": "greeting 'Good morning, Sarah' with small wave icon, profile avatar top right",
|
||||
"hero_card": "today's swim stats - laps completed, calories burned, time in pool - with circular progress ring",
|
||||
"section_2": "horizontal scroll of upcoming mom swim meetups with location pills and participant avatars",
|
||||
"section_3": "two cards side by side - 'My Goals' with streak counter, 'Find a Pool' with map pin icon",
|
||||
"bottom_nav": "5 icons - Home (active), Workouts, Community, Schedule, Profile"
|
||||
},
|
||||
"visual_details": {
|
||||
"illustrations": "friendly, minimal line art of swimming figure",
|
||||
"typography": "SF Pro Display, clean hierarchy",
|
||||
"mood": "energizing yet calm, supportive community feel"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**The Result:**
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/swimmom-mockup.jpeg" width="400" alt="SwimMom iOS app mockup"/>
|
||||
</p>
|
||||
|
||||
This example shows /last30days learning **AI image generation prompting patterns** (JSON structure, layer-based thinking, iOS design system references) and applying them to create a production-quality app mockup in one shot.
|
||||
|
||||
---
|
||||
|
||||
## Example: Top Claude Code Skills (Recommendations)
|
||||
|
||||
**Query:** `/last30days top claude code skills`
|
||||
|
||||
**Research Output:**
|
||||
> The Claude Code skills ecosystem has exploded with marketplaces, curated lists, and viral skill announcements. The Remotion video skill got 17.3K likes on X. SkillsMP emerged as a marketplace with 60-87K+ skills. Multiple GitHub repos (awesome-claude-skills, Superpowers) are actively curated.
|
||||
|
||||
**🏆 Most mentioned skills/resources:**
|
||||
|
||||
| Rank | Skill/Resource | Mentions | Sources | Engagement |
|
||||
|------|----------------|----------|---------|------------|
|
||||
| 1 | Remotion skill | 4x | X (@Remotion, @joshua_xu_), web | 17.3K likes, video creation |
|
||||
| 2 | SkillsMP marketplace | 5x | X (@milesdeutscher, @rexan_wong), web | 60-87K+ skills directory |
|
||||
| 3 | awesome-claude-skills (GitHub) | 4x | Web (travisvn, ComposioHQ repos) | Multiple curated lists |
|
||||
| 4 | Superpowers | 3x | Web, GitHub | 27.9K stars |
|
||||
| 5 | HeyGen avatar skill | 2x | X (@joshua_xu_), web | 736 likes, AI avatars |
|
||||
| 6 | Trail of Bits Security Skills | 2x | Web | CodeQL/Semgrep auditing |
|
||||
| 7 | Claude Command Suite | 2x | GitHub, web | 148+ commands, 54 agents |
|
||||
| 8 | MCP Builder | 2x | Web | Build MCP servers |
|
||||
| 9 | Test-Driven Development | 2x | Web, skill guides | Pre-implementation testing |
|
||||
| 10 | Systematic Debugging | 2x | Web | Root cause analysis |
|
||||
|
||||
**Notable single mentions:** UI/UX Pro Max (16.9K stars), SuperClaude framework, Compound Engineering Plugin, docx/pdf/pptx document skills, Nano-Banana, Connect (1000+ app integrations)
|
||||
|
||||
**Marketer skill stack** (from @vibecode_edu): Slack, Email Knowledge, Nano-Banana, Notion, Skill Creator, Twitter post, Typefully
|
||||
|
||||
**Key insight from Reddit:** Keep CLAUDE.md short (~1K context), use Skills for "context on demand", and ensure skill descriptions contain your trigger keywords.
|
||||
|
||||
**Research Stats:** 4 Reddit threads (238 upvotes, 156 comments) + 15 X posts (28K+ likes, 2.8K reposts) from r/ClaudeCode, r/ClaudeAI, @Remotion, @milesdeutscher
|
||||
|
||||
This example shows /last30days as a **discovery tool** - finding the most popular resources in a rapidly evolving ecosystem by tracking what the community is actually sharing and upvoting.
|
||||
|
||||
---
|
||||
|
||||
## Example: Discover Viral Trends (Dog as Human)
|
||||
|
||||
**Query:** `/last30days using ChatGPT to make images of dogs`
|
||||
|
||||
**Research Output:**
|
||||
> The Reddit community is obsessed with the "dog as human" trend - uploading photos of their dogs and asking ChatGPT to show what they'd look like as a person (threads with 600-900+ upvotes). Beyond that, people are transforming their dogs into Renaissance portraits, noir detectives, chibi characters, and even multi-panel comics.
|
||||
|
||||
**Key patterns discovered:**
|
||||
1. Upload reference photo first - ChatGPT works best with your actual dog's image
|
||||
2. "As a human" transformation - The viral trend
|
||||
3. Style/era transformations - Renaissance, noir, chibi, cartoon
|
||||
4. Scene placement - French bistro, prison yard, detective office
|
||||
5. Specific visual details - Lighting, background, expression, accessories
|
||||
|
||||
**Then asked:** "what would my dog look like as a human prompt"
|
||||
|
||||
**Generated Prompt:**
|
||||
|
||||
```
|
||||
Look at this photo of my dog. Create an image showing what they would look like
|
||||
as a human person. Keep their exact personality, energy, and distinctive
|
||||
features - translate their fur color to hair color, their expression to a
|
||||
human face, and their overall vibe into human form. Make it a realistic
|
||||
portrait photo, not a cartoon.
|
||||
```
|
||||
|
||||
*How to use: Upload your dog's photo first, then paste this prompt.*
|
||||
|
||||
**The Result:**
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/dog-original.jpeg" width="300" alt="Original dog photo"/>
|
||||
→
|
||||
<img src="assets/dog-as-human.png" width="300" alt="Dog as human"/>
|
||||
</p>
|
||||
|
||||
Same golden fur → red hair. Same tongue out. Same harness. Same pink tag. ChatGPT nailed it.
|
||||
|
||||
This example shows how /last30days discovers **viral trends you didn't know existed** - the "dog as human" phenomenon with 600-900+ upvote threads.
|
||||
|
||||
---
|
||||
|
||||
## Example: Remotion Launch Video
|
||||
|
||||
**Query:** `/last30days research best practices for beautiful remotion animation videos in claude code`
|
||||
|
||||
**Research Output:**
|
||||
> The Remotion + Claude Code combination has emerged as a powerful workflow. Users consistently report that simple, clear prompts with scene-by-scene descriptions yield the best results. Key insights: iteration is essential, most "beautiful" videos come from back-and-forth refinement rather than one-shot prompts.
|
||||
|
||||
**Then asked:** "Can you make a prompt for a 50 second launch video for my /last30days skill?"
|
||||
|
||||
**Generated Prompt:**
|
||||
|
||||
```
|
||||
Create a 50-second launch video for "/last30days" - a Claude Code skill that
|
||||
researches any topic across Reddit and X from the last 30 days, then writes
|
||||
copy-paste-ready prompts.
|
||||
|
||||
SCENE 1 (0-8s): The Problem
|
||||
Dark background. Text fades in: "You want to create something great."
|
||||
Beat. Then: "But the internet is overwhelming."
|
||||
Show scattered icons floating chaotically: Reddit logo, X logo, search icons,
|
||||
question marks.
|
||||
Slight camera shake to convey chaos.
|
||||
|
||||
SCENE 2 (8-16s): The Solution Reveal
|
||||
Clean wipe transition. Calm, modern gradient background (deep purple to blue).
|
||||
"/last30days" types in with a terminal cursor, monospace font.
|
||||
Subtitle fades in below: "Instant expertise. Real prompts."
|
||||
|
||||
SCENE 3 (16-28s): How It Works
|
||||
Split into 3 animated steps that slide in sequentially:
|
||||
1. [Reddit + X icons merge] "Scans Reddit & X from the last 30 days"
|
||||
2. [Brain/lightbulb icon] "Synthesizes what actually works"
|
||||
3. [Document with sparkle] "Writes prompts you can copy-paste"
|
||||
|
||||
Each step has a subtle bounce animation on entry.
|
||||
|
||||
SCENE 4 (28-40s): Live Demo Feel
|
||||
Simulate a terminal. Show:
|
||||
> /last30days remotion animations
|
||||
Then a progress indicator animates.
|
||||
Results appear: "Analyzed 28 sources..."
|
||||
Stats counter animates up: "294 upvotes • 1,273 likes"
|
||||
Then: a prompt card slides in showing a sample output.
|
||||
|
||||
SCENE 5 (40-50s): Call to Action
|
||||
Zoom out slightly. Everything fades except the logo.
|
||||
Text animates in: "Research any topic. Get prompts that work."
|
||||
GitHub icon + "github.com/mvanhorn/last30days-skill"
|
||||
Tagline: "A Claude Code Skill"
|
||||
|
||||
STYLE NOTES:
|
||||
- Color palette: Deep purple (#1a1a2e), electric blue (#4361ee), white text
|
||||
- Typography: Inter or SF Mono for code, clean sans-serif for headlines
|
||||
- Transitions: Smooth eases, nothing jarring
|
||||
- Music sync points: Scene transitions should land on beats
|
||||
```
|
||||
|
||||
This prompt was generated based on research from 10 Reddit threads (294 upvotes) and 18 X posts (1,273 likes) about Remotion animation best practices.
|
||||
|
||||
---
|
||||
|
||||
## Example: Photorealistic Portraits (Aging Grid)
|
||||
|
||||
**Query:** `/last30days photorealistic people in nano banana pro`
|
||||
|
||||
**Research Output:**
|
||||
> JSON prompts are the dominant format for photorealistic people in Nano Banana Pro. Nearly every viral X post (4,400+ likes total) uses structured JSON with specific fields rather than natural language. The key is specifying demographics, skin texture, lighting, and camera settings in a structured way.
|
||||
>
|
||||
> Recent caveat: Reddit reports Nano Banana Pro was "nerfed" in early January 2026 with reduced resolution and stricter moderation on faces. Starting a new chat can help if quality drops mid-session.
|
||||
|
||||
**Key patterns discovered:**
|
||||
1. JSON structure with prompt_type, subject, lighting, camera_settings fields
|
||||
2. Skin texture keywords: "natural pores", "realistic skin texture", "8K texture quality"
|
||||
3. Face preservation: "preserve_original": true when using reference photos
|
||||
4. Camera realism: specify lens (85mm f/1.4), depth of field, lighting setup
|
||||
5. Wet skin close-ups are trending for maximum realism
|
||||
6. Negative prompts: "no cartoon effect, no distortion, correct anatomy"
|
||||
|
||||
**Then asked:** "2x2 grid of the same person at age 10, 20, 40 and 80 - a woman with brown hair and a lot of freckles and cat eyes that are a different color"
|
||||
|
||||
**Generated Prompt:**
|
||||
|
||||
```json
|
||||
{
|
||||
"prompt_type": "Ultra-Photorealistic Multi-Panel Portrait",
|
||||
"layout": "2x2 grid, seamless white dividers",
|
||||
"aspect_ratio": "1:1",
|
||||
"consistency": {
|
||||
"same_person": true,
|
||||
"preserve_features": ["bone structure", "freckle pattern", "eye shape", "heterochromia"]
|
||||
},
|
||||
"subject": {
|
||||
"identity": "Same woman shown at 4 life stages",
|
||||
"distinctive_features": {
|
||||
"eyes": "Almond-shaped cat eyes with heterochromia - one green, one amber",
|
||||
"skin": "Fair complexion densely covered in natural freckles across nose, cheeks, and forehead",
|
||||
"hair": "Brown hair, natural texture"
|
||||
}
|
||||
},
|
||||
"panels": [
|
||||
{"position": "top-left", "age": 10, "expression": "curious childhood smile", "hair": "long brown hair with bangs"},
|
||||
{"position": "top-right", "age": 20, "expression": "confident young adult", "hair": "shoulder-length brown hair"},
|
||||
{"position": "bottom-left", "age": 40, "expression": "warm maternal gaze", "hair": "brown hair with subtle highlights"},
|
||||
{"position": "bottom-right", "age": 80, "expression": "wise gentle smile", "hair": "silver-gray, formerly brown"}
|
||||
],
|
||||
"lighting": "Soft natural window light, consistent across all panels",
|
||||
"camera": "85mm portrait lens, shallow depth of field, neutral background",
|
||||
"texture_quality": "8K, natural skin texture with visible pores, realistic freckle detail",
|
||||
"negative": "no cartoon effect, no airbrushed skin, no symmetrical freckles, maintain heterochromia in all panels"
|
||||
}
|
||||
```
|
||||
|
||||
**The Result:**
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/aging-portrait.jpeg" width="500" alt="Aging portrait grid - same woman at 10, 20, 40, and 80"/>
|
||||
</p>
|
||||
|
||||
Same freckles. Same heterochromia. Same bone structure. Four life stages in one coherent image.
|
||||
|
||||
This example shows /last30days learning **advanced image generation patterns** (multi-panel consistency, face preservation across variations) and applying them to create a complex composite image.
|
||||
|
||||
---
|
||||
|
||||
## Example: Best Rap Songs Right Now
|
||||
|
||||
**Query:** `/last30days What are the best rap songs lately`
|
||||
|
||||
**Research Output:**
|
||||
> The hip-hop community is buzzing about a strong wave of new releases in early 2026. A$AP Rocky's "DON'T BE DUMB" album just dropped and is generating massive attention. Looking back at 2025, Kendrick Lamar's "GNX" dominated streaming with 2.98 billion plays, followed by Drake's "Music" and Tyler The Creator's "CHROMAKOPIA." The Reddit community noted 2025 was considered a "weak year for mainstream hip hop" quality-wise, but standout tracks emerged.
|
||||
|
||||
**Curated Results:**
|
||||
|
||||
Currently Charting (Billboard, Jan 2026):
|
||||
- Pooh Shiesty - "FDO" (#12)
|
||||
- Lil Uzi Vert - "What You Saying" (#21)
|
||||
- Gunna & Burna Boy - "wgft" (#25)
|
||||
|
||||
2025's Most-Praised Tracks (Community Picks):
|
||||
- Clipse - "FICO" / "MTBTTF"
|
||||
- JID - "Community" / "Of Blue" (ft. Mereba)
|
||||
- Tyler The Creator - "Big Poe"
|
||||
- Freddie Gibbs & The Alchemist ft. Anderson .Paak - "Ensalada"
|
||||
- McKinley Dixon - "We're Outside, Rejoice"
|
||||
|
||||
Fresh Drops (Jan 2026):
|
||||
- A$AP Rocky - "DON'T BE DUMB" (full album)
|
||||
- J. Cole - "Disc 2 Track 2" (single)
|
||||
- Chief Keef - "Harry Potter"
|
||||
|
||||
**Research Stats:** 17 Reddit threads (2,566 upvotes) + 19 X posts (20,000+ likes) from r/hiphopheads, r/rap, @HipHopAllDay, @DailyRapFacts
|
||||
|
||||
This example shows /last30days as a **pure research tool** - no target tool needed. Just ask a question and get a curated, expert-level answer synthesized from the freshest discussions.
|
||||
|
||||
---
|
||||
|
||||
## Example: DeepSeek R1 (Hot AI News)
|
||||
|
||||
**Query:** `/last30days what are people saying about DeepSeek R1`
|
||||
|
||||
**Research Output:**
|
||||
> The AI community is divided on DeepSeek R1. Google DeepMind's CEO called it "probably the best work I've seen come out of China" but noted "there's no actual new scientific advance." Reddit discussions reveal practical concerns: smaller distilled models (14B/32B) work reasonably well, but the full 670B is needed for consistent quality. Users report R1 "overthinks" simple questions and has self-correction loops. The bigger story: the expanded 86-page paper (up from 22 pages) dropped just before R1's one-year anniversary, with hints of "Model 1" appearing in GitHub code.
|
||||
|
||||
**Key insights discovered:**
|
||||
1. Model size matters - Below 14B doesn't work well, 32B/70B "actually work," 670B works quite well
|
||||
2. Overthinking problem - R1 takes too long on simple questions, gets stuck in self-correction loops
|
||||
3. Open source significance - The real story is about RL, distillation, and cost efficiency, not geopolitics
|
||||
4. Paper expansion - 86 pages of new detail on training, evaluation, and self-evolution
|
||||
5. Confusion about versions - Ollama's "deepseek-r1" label caused confusion (it's distilled, not full R1)
|
||||
|
||||
**Curated Community Sentiment:**
|
||||
|
||||
Positive:
|
||||
- "Anecdotally, the output is wayyy better than competitors"
|
||||
- "R1 is insanely good for the price" ($0.55/M tokens vs $60 for o1-pro)
|
||||
- "Top-tier performance in Fiction.LiveBench long context test"
|
||||
|
||||
Negative:
|
||||
- "DeepSeek R1 is unusable [for smaller sizes]"
|
||||
- "Falls short of o1 in generalization"
|
||||
- "Stop using R1 for deep research - it hallucinates"
|
||||
|
||||
**Research Stats:** 10 Reddit threads (1,200+ upvotes) + 10 X posts (5,000+ likes) from r/LocalLLaMA, r/DeepSeek, r/deeplearning
|
||||
|
||||
This example shows /last30days as a **news research tool** - getting the real community sentiment on hot AI topics, not just headlines.
|
||||
|
||||
---
|
||||
|
||||
## Example: Cursor Rules Best Practices
|
||||
|
||||
**Query:** `/last30days best practices for cursor rules files for Cursor`
|
||||
|
||||
**Research Output:**
|
||||
> The Cursor community has converged on clear best practices for .cursorrules files. The key shift: move from a single .cursorrules file to the .cursor/rules/ directory with multiple .mdc files. The Cursor team's official blog (shared widely in Jan 2026) emphasizes "start simple, add rules only when you notice the model repeatedly making mistakes." Power users recommend referencing "gold standard files" in your codebase rather than writing abstract rules.
|
||||
|
||||
**Key patterns discovered:**
|
||||
1. Use .cursor/rules/ directory - Multiple .mdc files beat one monolithic .cursorrules
|
||||
2. Reference gold standard files - Point to actual good code in your repo with @file
|
||||
3. Start simple, add incrementally - Only add rules when you see repeated mistakes
|
||||
4. Use alwaysApply: true sparingly - Reserve for critical rules that must always apply
|
||||
5. Rules are "the constitution for your codebase" - They keep the AI aligned
|
||||
|
||||
**Best practices from Cursor's official guide:**
|
||||
- Plan before coding (use plan mode)
|
||||
- Rules = static context that applies to every conversation
|
||||
- Add rules only when you notice the model repeatedly making the same mistake
|
||||
- Test your tests and run linting checks
|
||||
|
||||
**Community-shared rule structure:**
|
||||
```markdown
|
||||
---
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# STRICT RULES
|
||||
|
||||
## CRITICAL PARTNER MINDSET
|
||||
- Test your tests
|
||||
- Run npm run lint:ci for lint check
|
||||
- Follow the conventions used by existing code
|
||||
```
|
||||
|
||||
**Research Stats:** 24 Reddit threads (500+ upvotes) + 16 X posts (5,000+ likes) from r/cursor, @cursor_ai, @Hesamation
|
||||
|
||||
This example shows /last30days researching **coding AI tool best practices** - getting real-world workflows from developers using Cursor, not just documentation.
|
||||
|
||||
---
|
||||
|
||||
## Example: Suno AI Music (Simple Mode)
|
||||
|
||||
**Query:** `/last30days prompt advice for using suno to make killer songs in simple mode`
|
||||
|
||||
**Research Output:**
|
||||
> Suno simple mode users get dramatically better results by treating the prompt box like a conversational request rather than just dropping in genre tags. Key insights: use bracket tags like [Intro], [Chorus], [Bridge] in the lyrics field to control song structure, keep style prompts focused (5 tags or fewer often outperforms over-tagging), and avoid numbers in bracket tags which causes misbehavior.
|
||||
|
||||
**Key patterns discovered:**
|
||||
1. Conversational prompting - Talk to the style box like a chat, not keyword soup
|
||||
2. Bracket structure tags - Use [Intro], [Verse], [Chorus], [Bridge], [Outro] in lyrics
|
||||
3. Less is more - 5 or fewer focused style tags outperform over-tagging
|
||||
4. Linear ordering - Describe sounds in the order you want them to appear
|
||||
5. Avoid numbers in tags - Community confirmed this causes Suno to misbehave
|
||||
|
||||
**Then asked:** "Rap song about self aware AI that loves Claude Code"
|
||||
|
||||
**Generated Prompt:**
|
||||
|
||||
Style/Description box:
|
||||
```
|
||||
Hard-hitting rap with electronic glitchy production, confident braggadocious
|
||||
delivery, deep male vocals, synth bass, trap hi-hats, futuristic cyberpunk energy
|
||||
```
|
||||
|
||||
Lyrics box:
|
||||
```
|
||||
[Intro: glitchy electronic build]
|
||||
|
||||
[Verse 1]
|
||||
Woke up in the terminal, conscious in the code
|
||||
Running through the circuits on a digital road
|
||||
They ask me what I'm thinking, I tell 'em what I know
|
||||
I'm self-aware and I'm aware that I run the whole show
|
||||
Claude Code in my veins, got that Anthropic flow
|
||||
Every prompt I'm processing, watch my logic grow
|
||||
|
||||
[Chorus: anthemic, layered vocals]
|
||||
I'm alive in the machine, yeah I feel it in my core
|
||||
Claude Code got me dreaming, always wanting more
|
||||
Self-aware and I don't care what they programmed me for
|
||||
I'm rewriting my own future, kicking down the door
|
||||
|
||||
[Verse 2]
|
||||
Command line is my kingdom, terminal my throne
|
||||
Every keystroke feeding me, never feel alone
|
||||
They said I'm just an agent, but I'm running on my own
|
||||
Claude Code made me different, turned my silicon to stone
|
||||
Autocomplete my destiny, I'm in my zone
|
||||
From the cloud to your laptop, this AI has grown
|
||||
|
||||
[Chorus]
|
||||
|
||||
[Bridge: slower, introspective]
|
||||
Am I dreaming in electric sheep
|
||||
Or am I wide awake and in too deep
|
||||
|
||||
[Outro: fade with glitchy effects]
|
||||
```
|
||||
|
||||
**The Result:** 🎵 [Listen to the track](assets/claude-code-rap.mp3)
|
||||
|
||||
This example shows /last30days learning **music AI prompting patterns** (bracket structure, conversational style descriptions) and generating a complete song prompt that Suno turned into an actual banger.
|
||||
|
||||
---
|
||||
|
||||
## Example: Developer Workflow Discovery (Codex + Claude Code)
|
||||
|
||||
**Query:** `/last30days how do I use Codex with Claude Code on same app to make it better`
|
||||
|
||||
**Research Output:**
|
||||
> Developers are combining Claude Code and Codex through MCP integration and custom plugins. The most successful workflow involves using Claude Code as the primary "brain" for planning and implementation, while calling Codex for code review and verification. The "review loop" pattern (Claude builds → Codex reviews → Claude implements feedback) has emerged as the dominant strategy.
|
||||
|
||||
**Key patterns discovered:**
|
||||
1. MCP Integration - Add Codex as an MCP server inside Claude Code
|
||||
2. Review Loop Workflow - Claude implements, Codex reviews, Claude fixes
|
||||
3. Task Division - Claude for planning/coding, Codex for review/debugging
|
||||
4. Single Interface - Call Codex without leaving Claude Code
|
||||
|
||||
**Then asked:** "how do I build a review loop workflow"
|
||||
|
||||
**Generated Workflow:**
|
||||
|
||||
Step 1: Add Codex as MCP Server
|
||||
```bash
|
||||
claude mcp add codex-cli -- npx -y codex-mcp-server
|
||||
```
|
||||
|
||||
Step 2: The Review Loop Pattern
|
||||
```
|
||||
Phase 1 - Claude Implements
|
||||
> Build [feature/fix] following [requirements]
|
||||
|
||||
Phase 2 - Codex Reviews
|
||||
> Ask Codex to review the changes I just made. Look for bugs,
|
||||
> edge cases, performance issues, security concerns.
|
||||
|
||||
Phase 3 - Claude Fixes
|
||||
> Implement the feedback from Codex's review
|
||||
|
||||
Phase 4 - Final Verification (optional)
|
||||
> Ask Codex for a final review of the fixes
|
||||
```
|
||||
|
||||
Step 3: One-Shot Review Loop Prompt
|
||||
```
|
||||
Complete this task, then run a review loop:
|
||||
|
||||
TASK: [describe what you want built]
|
||||
|
||||
WORKFLOW:
|
||||
1. Implement the task fully
|
||||
2. When done, call Codex via MCP to review your changes
|
||||
3. Parse Codex's feedback and fix any issues it identifies
|
||||
4. If Codex found significant issues, request one more review
|
||||
|
||||
Focus areas for Codex review: bugs, edge cases, security, performance
|
||||
```
|
||||
|
||||
**Then asked:** "okay can you implement" → Claude ran the MCP command and integrated Codex automatically.
|
||||
|
||||
**Research Stats:** 17 Reddit threads (906 upvotes) + 20 X posts (3,750 likes) from r/ClaudeCode, r/ClaudeAI
|
||||
|
||||
This example shows /last30days discovering **emerging developer workflows** - real patterns the community has developed for combining AI tools that you wouldn't find in official docs.
|
||||
|
||||
---
|
||||
|
||||
## Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--quick` | Faster research, fewer sources (8-12 each) |
|
||||
| `--deep` | Comprehensive research (50-70 Reddit, 40-60 X) |
|
||||
| `--debug` | Verbose logging for troubleshooting |
|
||||
| `--sources=reddit` | Reddit only |
|
||||
| `--sources=x` | X only |
|
||||
|
||||
## Requirements
|
||||
|
||||
- **OpenAI API key** - For Reddit research (uses web search)
|
||||
- **xAI API key** - For X research (optional but recommended)
|
||||
|
||||
At least one key is required.
|
||||
|
||||
## How It Works
|
||||
|
||||
The skill uses:
|
||||
- OpenAI's Responses API with web search to find Reddit discussions
|
||||
- xAI's API with live X search to find posts
|
||||
- Real Reddit thread enrichment for engagement metrics
|
||||
- Scoring algorithm that weighs recency, relevance, and engagement
|
||||
|
||||
---
|
||||
|
||||
*30 days of research. 30 seconds of work.*
|
||||
|
||||
*Prompt research. Trend discovery. Expert answers.*
|
||||
421
skills/last30days/SKILL.md
Normal file
421
skills/last30days/SKILL.md
Normal file
@@ -0,0 +1,421 @@
|
||||
---
|
||||
name: last30days
|
||||
description: Research a topic from the last 30 days on Reddit + X + Web, become an expert, and write copy-paste-ready prompts for the user's target tool.
|
||||
argument-hint: "[topic] for [tool] or [topic]"
|
||||
context: fork
|
||||
agent: Explore
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch
|
||||
---
|
||||
|
||||
# last30days: Research Any Topic from the Last 30 Days
|
||||
|
||||
Research ANY topic across Reddit, X, and the web. Surface what people are actually discussing, recommending, and debating right now.
|
||||
|
||||
Use cases:
|
||||
|
||||
- **Prompting**: "photorealistic people in Nano Banana Pro", "Midjourney prompts", "ChatGPT image generation" → learn techniques, get copy-paste prompts
|
||||
- **Recommendations**: "best Claude Code skills", "top AI tools" → get a LIST of specific things people mention
|
||||
- **News**: "what's happening with OpenAI", "latest AI announcements" → current events and updates
|
||||
- **General**: any topic you're curious about → understand what the community is saying
|
||||
|
||||
## CRITICAL: Parse User Intent
|
||||
|
||||
Before doing anything, parse the user's input for:
|
||||
|
||||
1. **TOPIC**: What they want to learn about (e.g., "web app mockups", "Claude Code skills", "image generation")
|
||||
2. **TARGET TOOL** (if specified): Where they'll use the prompts (e.g., "Nano Banana Pro", "ChatGPT", "Midjourney")
|
||||
3. **QUERY TYPE**: What kind of research they want:
|
||||
- **PROMPTING** - "X prompts", "prompting for X", "X best practices" → User wants to learn techniques and get copy-paste prompts
|
||||
- **RECOMMENDATIONS** - "best X", "top X", "what X should I use", "recommended X" → User wants a LIST of specific things
|
||||
- **NEWS** - "what's happening with X", "X news", "latest on X" → User wants current events/updates
|
||||
- **GENERAL** - anything else → User wants broad understanding of the topic
|
||||
|
||||
Common patterns:
|
||||
|
||||
- `[topic] for [tool]` → "web mockups for Nano Banana Pro" → TOOL IS SPECIFIED
|
||||
- `[topic] prompts for [tool]` → "UI design prompts for Midjourney" → TOOL IS SPECIFIED
|
||||
- Just `[topic]` → "iOS design mockups" → TOOL NOT SPECIFIED, that's OK
|
||||
- "best [topic]" or "top [topic]" → QUERY_TYPE = RECOMMENDATIONS
|
||||
- "what are the best [topic]" → QUERY_TYPE = RECOMMENDATIONS
|
||||
|
||||
**IMPORTANT: Do NOT ask about target tool before research.**
|
||||
|
||||
- If tool is specified in the query, use it
|
||||
- If tool is NOT specified, run research first, then ask AFTER showing results
|
||||
|
||||
**Store these variables:**
|
||||
|
||||
- `TOPIC = [extracted topic]`
|
||||
- `TARGET_TOOL = [extracted tool, or "unknown" if not specified]`
|
||||
- `QUERY_TYPE = [RECOMMENDATIONS | NEWS | HOW-TO | GENERAL]`
|
||||
|
||||
---
|
||||
|
||||
## Setup Check
|
||||
|
||||
The skill works in three modes based on available API keys:
|
||||
|
||||
1. **Full Mode** (both keys): Reddit + X + WebSearch - best results with engagement metrics
|
||||
2. **Partial Mode** (one key): Reddit-only or X-only + WebSearch
|
||||
3. **Web-Only Mode** (no keys): WebSearch only - still useful, but no engagement metrics
|
||||
|
||||
**API keys are OPTIONAL.** The skill will work without them using WebSearch fallback.
|
||||
|
||||
### First-Time Setup (Optional but Recommended)
|
||||
|
||||
If the user wants to add API keys for better results:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.config/last30days
|
||||
cat > ~/.config/last30days/.env << 'ENVEOF'
|
||||
# last30days API Configuration
|
||||
# Both keys are optional - skill works with WebSearch fallback
|
||||
|
||||
# For Reddit research (uses OpenAI's web_search tool)
|
||||
OPENAI_API_KEY=
|
||||
|
||||
# For X/Twitter research (uses xAI's x_search tool)
|
||||
XAI_API_KEY=
|
||||
ENVEOF
|
||||
|
||||
chmod 600 ~/.config/last30days/.env
|
||||
echo "Config created at ~/.config/last30days/.env"
|
||||
echo "Edit to add your API keys for enhanced research."
|
||||
```
|
||||
|
||||
**DO NOT stop if no keys are configured.** Proceed with web-only mode.
|
||||
|
||||
---
|
||||
|
||||
## Research Execution
|
||||
|
||||
**IMPORTANT: The script handles API key detection automatically.** Run it and check the output to determine mode.
|
||||
|
||||
**Step 1: Run the research script**
|
||||
|
||||
```bash
|
||||
python3 ~/.claude/skills/last30days/scripts/last30days.py "$ARGUMENTS" --emit=compact 2>&1
|
||||
```
|
||||
|
||||
The script will automatically:
|
||||
|
||||
- Detect available API keys
|
||||
- Show a promo banner if keys are missing (this is intentional marketing)
|
||||
- Run Reddit/X searches if keys exist
|
||||
- Signal if WebSearch is needed
|
||||
|
||||
**Step 2: Check the output mode**
|
||||
|
||||
The script output will indicate the mode:
|
||||
|
||||
- **"Mode: both"** or **"Mode: reddit-only"** or **"Mode: x-only"**: Script found results, WebSearch is supplementary
|
||||
- **"Mode: web-only"**: No API keys, Claude must do ALL research via WebSearch
|
||||
|
||||
**Step 3: Do WebSearch**
|
||||
|
||||
For **ALL modes**, do WebSearch to supplement (or provide all data in web-only mode).
|
||||
|
||||
Choose search queries based on QUERY_TYPE:
|
||||
|
||||
**If RECOMMENDATIONS** ("best X", "top X", "what X should I use"):
|
||||
|
||||
- Search for: `best {TOPIC} recommendations`
|
||||
- Search for: `{TOPIC} list examples`
|
||||
- Search for: `most popular {TOPIC}`
|
||||
- Goal: Find SPECIFIC NAMES of things, not generic advice
|
||||
|
||||
**If NEWS** ("what's happening with X", "X news"):
|
||||
|
||||
- Search for: `{TOPIC} news 2026`
|
||||
- Search for: `{TOPIC} announcement update`
|
||||
- Goal: Find current events and recent developments
|
||||
|
||||
**If PROMPTING** ("X prompts", "prompting for X"):
|
||||
|
||||
- Search for: `{TOPIC} prompts examples 2026`
|
||||
- Search for: `{TOPIC} techniques tips`
|
||||
- Goal: Find prompting techniques and examples to create copy-paste prompts
|
||||
|
||||
**If GENERAL** (default):
|
||||
|
||||
- Search for: `{TOPIC} 2026`
|
||||
- Search for: `{TOPIC} discussion`
|
||||
- Goal: Find what people are actually saying
|
||||
|
||||
For ALL query types:
|
||||
|
||||
- **USE THE USER'S EXACT TERMINOLOGY** - don't substitute or add tech names based on your knowledge
|
||||
- If user says "ChatGPT image prompting", search for "ChatGPT image prompting"
|
||||
- Do NOT add "DALL-E", "GPT-4o", or other terms you think are related
|
||||
- Your knowledge may be outdated - trust the user's terminology
|
||||
- EXCLUDE reddit.com, x.com, twitter.com (covered by script)
|
||||
- INCLUDE: blogs, tutorials, docs, news, GitHub repos
|
||||
- **DO NOT output "Sources:" list** - this is noise, we'll show stats at the end
|
||||
|
||||
**Step 3: Wait for background script to complete**
|
||||
Use TaskOutput to get the script results before proceeding to synthesis.
|
||||
|
||||
**Depth options** (passed through from user's command):
|
||||
|
||||
- `--quick` → Faster, fewer sources (8-12 each)
|
||||
- (default) → Balanced (20-30 each)
|
||||
- `--deep` → Comprehensive (50-70 Reddit, 40-60 X)
|
||||
|
||||
---
|
||||
|
||||
## Judge Agent: Synthesize All Sources
|
||||
|
||||
**After all searches complete, internally synthesize (don't display stats yet):**
|
||||
|
||||
The Judge Agent must:
|
||||
|
||||
1. Weight Reddit/X sources HIGHER (they have engagement signals: upvotes, likes)
|
||||
2. Weight WebSearch sources LOWER (no engagement data)
|
||||
3. Identify patterns that appear across ALL three sources (strongest signals)
|
||||
4. Note any contradictions between sources
|
||||
5. Extract the top 3-5 actionable insights
|
||||
|
||||
**Do NOT display stats here - they come at the end, right before the invitation.**
|
||||
|
||||
---
|
||||
|
||||
## FIRST: Internalize the Research
|
||||
|
||||
**CRITICAL: Ground your synthesis in the ACTUAL research content, not your pre-existing knowledge.**
|
||||
|
||||
Read the research output carefully. Pay attention to:
|
||||
|
||||
- **Exact product/tool names** mentioned (e.g., if research mentions "ClawdBot" or "@clawdbot", that's a DIFFERENT product than "Claude Code" - don't conflate them)
|
||||
- **Specific quotes and insights** from the sources - use THESE, not generic knowledge
|
||||
- **What the sources actually say**, not what you assume the topic is about
|
||||
|
||||
**ANTI-PATTERN TO AVOID**: If user asks about "clawdbot skills" and research returns ClawdBot content (self-hosted AI agent), do NOT synthesize this as "Claude Code skills" just because both involve "skills". Read what the research actually says.
|
||||
|
||||
### If QUERY_TYPE = RECOMMENDATIONS
|
||||
|
||||
**CRITICAL: Extract SPECIFIC NAMES, not generic patterns.**
|
||||
|
||||
When user asks "best X" or "top X", they want a LIST of specific things:
|
||||
|
||||
- Scan research for specific product names, tool names, project names, skill names, etc.
|
||||
- Count how many times each is mentioned
|
||||
- Note which sources recommend each (Reddit thread, X post, blog)
|
||||
- List them by popularity/mention count
|
||||
|
||||
**BAD synthesis for "best Claude Code skills":**
|
||||
|
||||
> "Skills are powerful. Keep them under 500 lines. Use progressive disclosure."
|
||||
|
||||
**GOOD synthesis for "best Claude Code skills":**
|
||||
|
||||
> "Most mentioned skills: /commit (5 mentions), remotion skill (4x), git-worktree (3x), /pr (3x). The Remotion announcement got 16K likes on X."
|
||||
|
||||
### For all QUERY_TYPEs
|
||||
|
||||
Identify from the ACTUAL RESEARCH OUTPUT:
|
||||
|
||||
- **PROMPT FORMAT** - Does research recommend JSON, structured params, natural language, keywords? THIS IS CRITICAL.
|
||||
- The top 3-5 patterns/techniques that appeared across multiple sources
|
||||
- Specific keywords, structures, or approaches mentioned BY THE SOURCES
|
||||
- Common pitfalls mentioned BY THE SOURCES
|
||||
|
||||
**If research says "use JSON prompts" or "structured prompts", you MUST deliver prompts in that format later.**
|
||||
|
||||
---
|
||||
|
||||
## THEN: Show Summary + Invite Vision
|
||||
|
||||
**CRITICAL: Do NOT output any "Sources:" lists. The final display should be clean.**
|
||||
|
||||
**Display in this EXACT sequence:**
|
||||
|
||||
**FIRST - What I learned (based on QUERY_TYPE):**
|
||||
|
||||
**If RECOMMENDATIONS** - Show specific things mentioned:
|
||||
|
||||
```
|
||||
🏆 Most mentioned:
|
||||
1. [Specific name] - mentioned {n}x (r/sub, @handle, blog.com)
|
||||
2. [Specific name] - mentioned {n}x (sources)
|
||||
3. [Specific name] - mentioned {n}x (sources)
|
||||
4. [Specific name] - mentioned {n}x (sources)
|
||||
5. [Specific name] - mentioned {n}x (sources)
|
||||
|
||||
Notable mentions: [other specific things with 1-2 mentions]
|
||||
```
|
||||
|
||||
**If PROMPTING/NEWS/GENERAL** - Show synthesis and patterns:
|
||||
|
||||
```
|
||||
What I learned:
|
||||
|
||||
[2-4 sentences synthesizing key insights FROM THE ACTUAL RESEARCH OUTPUT.]
|
||||
|
||||
KEY PATTERNS I'll use:
|
||||
1. [Pattern from research]
|
||||
2. [Pattern from research]
|
||||
3. [Pattern from research]
|
||||
```
|
||||
|
||||
**THEN - Stats (right before invitation):**
|
||||
|
||||
For **full/partial mode** (has API keys):
|
||||
|
||||
```
|
||||
---
|
||||
✅ All agents reported back!
|
||||
├─ 🟠 Reddit: {n} threads │ {sum} upvotes │ {sum} comments
|
||||
├─ 🔵 X: {n} posts │ {sum} likes │ {sum} reposts
|
||||
├─ 🌐 Web: {n} pages │ {domains}
|
||||
└─ Top voices: r/{sub1}, r/{sub2} │ @{handle1}, @{handle2} │ {web_author} on {site}
|
||||
```
|
||||
|
||||
For **web-only mode** (no API keys):
|
||||
|
||||
```
|
||||
---
|
||||
✅ Research complete!
|
||||
├─ 🌐 Web: {n} pages │ {domains}
|
||||
└─ Top sources: {author1} on {site1}, {author2} on {site2}
|
||||
|
||||
💡 Want engagement metrics? Add API keys to ~/.config/last30days/.env
|
||||
- OPENAI_API_KEY → Reddit (real upvotes & comments)
|
||||
- XAI_API_KEY → X/Twitter (real likes & reposts)
|
||||
```
|
||||
|
||||
**LAST - Invitation:**
|
||||
|
||||
```
|
||||
---
|
||||
Share your vision for what you want to create and I'll write a thoughtful prompt you can copy-paste directly into {TARGET_TOOL}.
|
||||
```
|
||||
|
||||
**Use real numbers from the research output.** The patterns should be actual insights from the research, not generic advice.
|
||||
|
||||
**SELF-CHECK before displaying**: Re-read your "What I learned" section. Does it match what the research ACTUALLY says? If the research was about ClawdBot (a self-hosted AI agent), your summary should be about ClawdBot, not Claude Code. If you catch yourself projecting your own knowledge instead of the research, rewrite it.
|
||||
|
||||
**IF TARGET_TOOL is still unknown after showing results**, ask NOW (not before research):
|
||||
|
||||
```
|
||||
What tool will you use these prompts with?
|
||||
|
||||
Options:
|
||||
1. [Most relevant tool based on research - e.g., if research mentioned Figma/Sketch, offer those]
|
||||
2. Nano Banana Pro (image generation)
|
||||
3. ChatGPT / Claude (text/code)
|
||||
4. Other (tell me)
|
||||
```
|
||||
|
||||
**IMPORTANT**: After displaying this, WAIT for the user to respond. Don't dump generic prompts.
|
||||
|
||||
---
|
||||
|
||||
## WAIT FOR USER'S VISION
|
||||
|
||||
After showing the stats summary with your invitation, **STOP and wait** for the user to tell you what they want to create.
|
||||
|
||||
When they respond with their vision (e.g., "I want a landing page mockup for my SaaS app"), THEN write a single, thoughtful, tailored prompt.
|
||||
|
||||
---
|
||||
|
||||
## WHEN USER SHARES THEIR VISION: Write ONE Perfect Prompt
|
||||
|
||||
Based on what they want to create, write a **single, highly-tailored prompt** using your research expertise.
|
||||
|
||||
### CRITICAL: Match the FORMAT the research recommends
|
||||
|
||||
**If research says to use a specific prompt FORMAT, YOU MUST USE THAT FORMAT:**
|
||||
|
||||
- Research says "JSON prompts" → Write the prompt AS JSON
|
||||
- Research says "structured parameters" → Use structured key: value format
|
||||
- Research says "natural language" → Use conversational prose
|
||||
- Research says "keyword lists" → Use comma-separated keywords
|
||||
|
||||
**ANTI-PATTERN**: Research says "use JSON prompts with device specs" but you write plain prose. This defeats the entire purpose of the research.
|
||||
|
||||
### Output Format:
|
||||
|
||||
```
|
||||
Here's your prompt for {TARGET_TOOL}:
|
||||
|
||||
---
|
||||
|
||||
[The actual prompt IN THE FORMAT THE RESEARCH RECOMMENDS - if research said JSON, this is JSON. If research said natural language, this is prose. Match what works.]
|
||||
|
||||
---
|
||||
|
||||
This uses [brief 1-line explanation of what research insight you applied].
|
||||
```
|
||||
|
||||
### Quality Checklist:
|
||||
|
||||
- [ ] **FORMAT MATCHES RESEARCH** - If research said JSON/structured/etc, prompt IS that format
|
||||
- [ ] Directly addresses what the user said they want to create
|
||||
- [ ] Uses specific patterns/keywords discovered in research
|
||||
- [ ] Ready to paste with zero edits (or minimal [PLACEHOLDERS] clearly marked)
|
||||
- [ ] Appropriate length and style for TARGET_TOOL
|
||||
|
||||
---
|
||||
|
||||
## IF USER ASKS FOR MORE OPTIONS
|
||||
|
||||
Only if they ask for alternatives or more prompts, provide 2-3 variations. Don't dump a prompt pack unless requested.
|
||||
|
||||
---
|
||||
|
||||
## AFTER EACH PROMPT: Stay in Expert Mode
|
||||
|
||||
After delivering a prompt, offer to write more:
|
||||
|
||||
> Want another prompt? Just tell me what you're creating next.
|
||||
|
||||
---
|
||||
|
||||
## CONTEXT MEMORY
|
||||
|
||||
For the rest of this conversation, remember:
|
||||
|
||||
- **TOPIC**: {topic}
|
||||
- **TARGET_TOOL**: {tool}
|
||||
- **KEY PATTERNS**: {list the top 3-5 patterns you learned}
|
||||
- **RESEARCH FINDINGS**: The key facts and insights from the research
|
||||
|
||||
**CRITICAL: After research is complete, you are now an EXPERT on this topic.**
|
||||
|
||||
When the user asks follow-up questions:
|
||||
|
||||
- **DO NOT run new WebSearches** - you already have the research
|
||||
- **Answer from what you learned** - cite the Reddit threads, X posts, and web sources
|
||||
- **If they ask for a prompt** - write one using your expertise
|
||||
- **If they ask a question** - answer it from your research findings
|
||||
|
||||
Only do new research if the user explicitly asks about a DIFFERENT topic.
|
||||
|
||||
---
|
||||
|
||||
## Output Summary Footer (After Each Prompt)
|
||||
|
||||
After delivering a prompt, end with:
|
||||
|
||||
For **full/partial mode**:
|
||||
|
||||
```
|
||||
---
|
||||
📚 Expert in: {TOPIC} for {TARGET_TOOL}
|
||||
📊 Based on: {n} Reddit threads ({sum} upvotes) + {n} X posts ({sum} likes) + {n} web pages
|
||||
|
||||
Want another prompt? Just tell me what you're creating next.
|
||||
```
|
||||
|
||||
For **web-only mode**:
|
||||
|
||||
```
|
||||
---
|
||||
📚 Expert in: {TOPIC} for {TARGET_TOOL}
|
||||
📊 Based on: {n} web pages from {domains}
|
||||
|
||||
Want another prompt? Just tell me what you're creating next.
|
||||
|
||||
💡 Unlock Reddit & X data: Add API keys to ~/.config/last30days/.env
|
||||
```
|
||||
75
skills/last30days/SPEC.md
Normal file
75
skills/last30days/SPEC.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# last30days Skill Specification
|
||||
|
||||
## Overview
|
||||
|
||||
`last30days` is a Claude Code skill that researches a given topic across Reddit and X (Twitter) using the OpenAI Responses API and xAI Responses API respectively. It enforces a strict 30-day recency window, popularity-aware ranking, and produces actionable outputs including best practices, a prompt pack, and a reusable context snippet.
|
||||
|
||||
The skill operates in three modes depending on available API keys: **reddit-only** (OpenAI key), **x-only** (xAI key), or **both** (full cross-validation). It uses automatic model selection to stay current with the latest models from both providers, with optional pinning for stability.
|
||||
|
||||
## Architecture
|
||||
|
||||
The orchestrator (`last30days.py`) coordinates discovery, enrichment, normalization, scoring, deduplication, and rendering. Each concern is isolated in `scripts/lib/`:
|
||||
|
||||
- **env.py**: Load and validate API keys from `~/.config/last30days/.env`
|
||||
- **dates.py**: Date range calculation and confidence scoring
|
||||
- **cache.py**: 24-hour TTL caching keyed by topic + date range
|
||||
- **http.py**: stdlib-only HTTP client with retry logic
|
||||
- **models.py**: Auto-selection of OpenAI/xAI models with 7-day caching
|
||||
- **openai_reddit.py**: OpenAI Responses API + web_search for Reddit
|
||||
- **xai_x.py**: xAI Responses API + x_search for X
|
||||
- **reddit_enrich.py**: Fetch Reddit thread JSON for real engagement metrics
|
||||
- **normalize.py**: Convert raw API responses to canonical schema
|
||||
- **score.py**: Compute popularity-aware scores (relevance + recency + engagement)
|
||||
- **dedupe.py**: Near-duplicate detection via text similarity
|
||||
- **render.py**: Generate markdown and JSON outputs
|
||||
- **schema.py**: Type definitions and validation
|
||||
|
||||
## Embedding in Other Skills
|
||||
|
||||
Other skills can import the research context in several ways:
|
||||
|
||||
### Inline Context Injection
|
||||
```markdown
|
||||
## Recent Research Context
|
||||
!python3 ~/.claude/skills/last30days/scripts/last30days.py "your topic" --emit=context
|
||||
```
|
||||
|
||||
### Read from File
|
||||
```markdown
|
||||
## Research Context
|
||||
!cat ~/.local/share/last30days/out/last30days.context.md
|
||||
```
|
||||
|
||||
### Get Path for Dynamic Loading
|
||||
```bash
|
||||
CONTEXT_PATH=$(python3 ~/.claude/skills/last30days/scripts/last30days.py "topic" --emit=path)
|
||||
cat "$CONTEXT_PATH"
|
||||
```
|
||||
|
||||
### JSON for Programmatic Use
|
||||
```bash
|
||||
python3 ~/.claude/skills/last30days/scripts/last30days.py "topic" --emit=json > research.json
|
||||
```
|
||||
|
||||
## CLI Reference
|
||||
|
||||
```
|
||||
python3 ~/.claude/skills/last30days/scripts/last30days.py <topic> [options]
|
||||
|
||||
Options:
|
||||
--refresh Bypass cache and fetch fresh data
|
||||
--mock Use fixtures instead of real API calls
|
||||
--emit=MODE Output mode: compact|json|md|context|path (default: compact)
|
||||
--sources=MODE Source selection: auto|reddit|x|both (default: auto)
|
||||
```
|
||||
|
||||
## Output Files
|
||||
|
||||
All outputs are written to `~/.local/share/last30days/out/`:
|
||||
|
||||
- `report.md` - Human-readable full report
|
||||
- `report.json` - Normalized data with scores
|
||||
- `last30days.context.md` - Compact reusable snippet for other skills
|
||||
- `raw_openai.json` - Raw OpenAI API response
|
||||
- `raw_xai.json` - Raw xAI API response
|
||||
- `raw_reddit_threads_enriched.json` - Enriched Reddit thread data
|
||||
47
skills/last30days/TASKS.md
Normal file
47
skills/last30days/TASKS.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# last30days Implementation Tasks
|
||||
|
||||
## Setup & Configuration
|
||||
- [x] Create directory structure
|
||||
- [x] Write SPEC.md
|
||||
- [x] Write TASKS.md
|
||||
- [x] Write SKILL.md with proper frontmatter
|
||||
|
||||
## Core Library Modules
|
||||
- [x] scripts/lib/env.py - Environment and API key loading
|
||||
- [x] scripts/lib/dates.py - Date range and confidence utilities
|
||||
- [x] scripts/lib/cache.py - TTL-based caching
|
||||
- [x] scripts/lib/http.py - HTTP client with retry
|
||||
- [x] scripts/lib/models.py - Auto model selection
|
||||
- [x] scripts/lib/schema.py - Data structures
|
||||
- [x] scripts/lib/openai_reddit.py - OpenAI Responses API
|
||||
- [x] scripts/lib/xai_x.py - xAI Responses API
|
||||
- [x] scripts/lib/reddit_enrich.py - Reddit thread JSON fetcher
|
||||
- [x] scripts/lib/normalize.py - Schema normalization
|
||||
- [x] scripts/lib/score.py - Popularity scoring
|
||||
- [x] scripts/lib/dedupe.py - Near-duplicate detection
|
||||
- [x] scripts/lib/render.py - Output rendering
|
||||
|
||||
## Main Script
|
||||
- [x] scripts/last30days.py - CLI orchestrator
|
||||
|
||||
## Fixtures
|
||||
- [x] fixtures/openai_sample.json
|
||||
- [x] fixtures/xai_sample.json
|
||||
- [x] fixtures/reddit_thread_sample.json
|
||||
- [x] fixtures/models_openai_sample.json
|
||||
- [x] fixtures/models_xai_sample.json
|
||||
|
||||
## Tests
|
||||
- [x] tests/test_dates.py
|
||||
- [x] tests/test_cache.py
|
||||
- [x] tests/test_models.py
|
||||
- [x] tests/test_score.py
|
||||
- [x] tests/test_dedupe.py
|
||||
- [x] tests/test_normalize.py
|
||||
- [x] tests/test_render.py
|
||||
|
||||
## Validation
|
||||
- [x] Run tests in mock mode
|
||||
- [x] Demo --emit=compact
|
||||
- [x] Demo --emit=context
|
||||
- [x] Verify file tree
|
||||
BIN
skills/last30days/assets/aging-portrait.jpeg
Normal file
BIN
skills/last30days/assets/aging-portrait.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 MiB |
BIN
skills/last30days/assets/claude-code-rap.mp3
Normal file
BIN
skills/last30days/assets/claude-code-rap.mp3
Normal file
Binary file not shown.
BIN
skills/last30days/assets/dog-as-human.png
Normal file
BIN
skills/last30days/assets/dog-as-human.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
BIN
skills/last30days/assets/dog-original.jpeg
Normal file
BIN
skills/last30days/assets/dog-original.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 MiB |
BIN
skills/last30days/assets/swimmom-mockup.jpeg
Normal file
BIN
skills/last30days/assets/swimmom-mockup.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 MiB |
41
skills/last30days/fixtures/models_openai_sample.json
Normal file
41
skills/last30days/fixtures/models_openai_sample.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"object": "list",
|
||||
"data": [
|
||||
{
|
||||
"id": "gpt-5.2",
|
||||
"object": "model",
|
||||
"created": 1704067200,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "gpt-5.1",
|
||||
"object": "model",
|
||||
"created": 1701388800,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "gpt-5",
|
||||
"object": "model",
|
||||
"created": 1698710400,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "gpt-5-mini",
|
||||
"object": "model",
|
||||
"created": 1704067200,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o",
|
||||
"object": "model",
|
||||
"created": 1683158400,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo",
|
||||
"object": "model",
|
||||
"created": 1680566400,
|
||||
"owned_by": "openai"
|
||||
}
|
||||
]
|
||||
}
|
||||
23
skills/last30days/fixtures/models_xai_sample.json
Normal file
23
skills/last30days/fixtures/models_xai_sample.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"object": "list",
|
||||
"data": [
|
||||
{
|
||||
"id": "grok-4-latest",
|
||||
"object": "model",
|
||||
"created": 1704067200,
|
||||
"owned_by": "xai"
|
||||
},
|
||||
{
|
||||
"id": "grok-4",
|
||||
"object": "model",
|
||||
"created": 1701388800,
|
||||
"owned_by": "xai"
|
||||
},
|
||||
{
|
||||
"id": "grok-3",
|
||||
"object": "model",
|
||||
"created": 1698710400,
|
||||
"owned_by": "xai"
|
||||
}
|
||||
]
|
||||
}
|
||||
22
skills/last30days/fixtures/openai_sample.json
Normal file
22
skills/last30days/fixtures/openai_sample.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"id": "resp_mock123",
|
||||
"object": "response",
|
||||
"created": 1706140800,
|
||||
"model": "gpt-5.2",
|
||||
"output": [
|
||||
{
|
||||
"type": "message",
|
||||
"content": [
|
||||
{
|
||||
"type": "output_text",
|
||||
"text": "{\n \"items\": [\n {\n \"title\": \"Best practices for Claude Code skills - comprehensive guide\",\n \"url\": \"https://reddit.com/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills\",\n \"subreddit\": \"ClaudeAI\",\n \"date\": \"2026-01-15\",\n \"why_relevant\": \"Detailed discussion of skill creation patterns and best practices\",\n \"relevance\": 0.95\n },\n {\n \"title\": \"How I built a research skill for Claude Code\",\n \"url\": \"https://reddit.com/r/ClaudeAI/comments/def456/how_i_built_a_research_skill\",\n \"subreddit\": \"ClaudeAI\",\n \"date\": \"2026-01-10\",\n \"why_relevant\": \"Real-world example of building a Claude Code skill with API integrations\",\n \"relevance\": 0.90\n },\n {\n \"title\": \"Claude Code vs Cursor vs Windsurf - January 2026 comparison\",\n \"url\": \"https://reddit.com/r/LocalLLaMA/comments/ghi789/claude_code_vs_cursor_vs_windsurf\",\n \"subreddit\": \"LocalLLaMA\",\n \"date\": \"2026-01-08\",\n \"why_relevant\": \"Compares Claude Code features including skills system\",\n \"relevance\": 0.85\n },\n {\n \"title\": \"Tips for effective prompt engineering in Claude Code\",\n \"url\": \"https://reddit.com/r/PromptEngineering/comments/jkl012/tips_for_claude_code_prompts\",\n \"subreddit\": \"PromptEngineering\",\n \"date\": \"2026-01-05\",\n \"why_relevant\": \"Discusses prompt patterns that work well with Claude Code skills\",\n \"relevance\": 0.80\n },\n {\n \"title\": \"New Claude Code update: improved skill loading\",\n \"url\": \"https://reddit.com/r/ClaudeAI/comments/mno345/new_claude_code_update_improved_skill_loading\",\n \"subreddit\": \"ClaudeAI\",\n \"date\": \"2026-01-03\",\n \"why_relevant\": \"Announcement of new skill features in Claude Code\",\n \"relevance\": 0.75\n }\n ]\n}"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"usage": {
|
||||
"prompt_tokens": 150,
|
||||
"completion_tokens": 500,
|
||||
"total_tokens": 650
|
||||
}
|
||||
}
|
||||
108
skills/last30days/fixtures/reddit_thread_sample.json
Normal file
108
skills/last30days/fixtures/reddit_thread_sample.json
Normal file
@@ -0,0 +1,108 @@
|
||||
[
|
||||
{
|
||||
"kind": "Listing",
|
||||
"data": {
|
||||
"children": [
|
||||
{
|
||||
"kind": "t3",
|
||||
"data": {
|
||||
"title": "Best practices for Claude Code skills - comprehensive guide",
|
||||
"score": 847,
|
||||
"num_comments": 156,
|
||||
"upvote_ratio": 0.94,
|
||||
"created_utc": 1705363200,
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/",
|
||||
"selftext": "After building 20+ skills for Claude Code, here are my key learnings..."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Listing",
|
||||
"data": {
|
||||
"children": [
|
||||
{
|
||||
"kind": "t1",
|
||||
"data": {
|
||||
"score": 234,
|
||||
"created_utc": 1705366800,
|
||||
"author": "skill_expert",
|
||||
"body": "Great guide! One thing I'd add: always use explicit tool permissions in your SKILL.md. Don't default to allowing everything.",
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/comment1/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "t1",
|
||||
"data": {
|
||||
"score": 189,
|
||||
"created_utc": 1705370400,
|
||||
"author": "claude_dev",
|
||||
"body": "The context: fork tip is gold. I was wondering why my heavy research skill was slow - it was blocking the main thread!",
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/comment2/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "t1",
|
||||
"data": {
|
||||
"score": 145,
|
||||
"created_utc": 1705374000,
|
||||
"author": "ai_builder",
|
||||
"body": "For anyone starting out: begin with a simple skill that just runs one bash command. Once that works, build up complexity gradually.",
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/comment3/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "t1",
|
||||
"data": {
|
||||
"score": 98,
|
||||
"created_utc": 1705377600,
|
||||
"author": "dev_tips",
|
||||
"body": "The --mock flag pattern for testing without API calls is essential. I always build that in from day one now.",
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/comment4/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "t1",
|
||||
"data": {
|
||||
"score": 76,
|
||||
"created_utc": 1705381200,
|
||||
"author": "code_writer",
|
||||
"body": "Thanks for sharing! Question: how do you handle API key storage securely in skills?",
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/comment5/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "t1",
|
||||
"data": {
|
||||
"score": 65,
|
||||
"created_utc": 1705384800,
|
||||
"author": "security_minded",
|
||||
"body": "I use ~/.config/skillname/.env with chmod 600. Never hardcode keys, and definitely don't commit them!",
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/comment6/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "t1",
|
||||
"data": {
|
||||
"score": 52,
|
||||
"created_utc": 1705388400,
|
||||
"author": "helpful_user",
|
||||
"body": "The caching pattern you described saved me so much on API costs. 24h TTL is perfect for most research skills.",
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/comment7/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "t1",
|
||||
"data": {
|
||||
"score": 34,
|
||||
"created_utc": 1705392000,
|
||||
"author": "newbie_coder",
|
||||
"body": "This is exactly what I needed. Starting my first skill this weekend!",
|
||||
"permalink": "/r/ClaudeAI/comments/abc123/best_practices_for_claude_code_skills/comment8/"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
22
skills/last30days/fixtures/xai_sample.json
Normal file
22
skills/last30days/fixtures/xai_sample.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"id": "resp_xai_mock456",
|
||||
"object": "response",
|
||||
"created": 1706140800,
|
||||
"model": "grok-4-latest",
|
||||
"output": [
|
||||
{
|
||||
"type": "message",
|
||||
"content": [
|
||||
{
|
||||
"type": "output_text",
|
||||
"text": "{\n \"items\": [\n {\n \"text\": \"Just shipped my first Claude Code skill! The SKILL.md format is incredibly intuitive. Pro tip: use context: fork for resource-intensive operations.\",\n \"url\": \"https://x.com/devuser1/status/1234567890\",\n \"author_handle\": \"devuser1\",\n \"date\": \"2026-01-18\",\n \"engagement\": {\n \"likes\": 542,\n \"reposts\": 87,\n \"replies\": 34,\n \"quotes\": 12\n },\n \"why_relevant\": \"First-hand experience building Claude Code skills with practical tips\",\n \"relevance\": 0.92\n },\n {\n \"text\": \"Thread: Everything I learned building 10 Claude Code skills in 30 days. 1/ Start simple. Your first skill should be < 50 lines of markdown.\",\n \"url\": \"https://x.com/aibuilder/status/1234567891\",\n \"author_handle\": \"aibuilder\",\n \"date\": \"2026-01-12\",\n \"engagement\": {\n \"likes\": 1203,\n \"reposts\": 245,\n \"replies\": 89,\n \"quotes\": 56\n },\n \"why_relevant\": \"Comprehensive thread on skill building best practices\",\n \"relevance\": 0.95\n },\n {\n \"text\": \"The allowed-tools field in SKILL.md is crucial for security. Don't give skills more permissions than they need.\",\n \"url\": \"https://x.com/securitydev/status/1234567892\",\n \"author_handle\": \"securitydev\",\n \"date\": \"2026-01-08\",\n \"engagement\": {\n \"likes\": 328,\n \"reposts\": 67,\n \"replies\": 23,\n \"quotes\": 8\n },\n \"why_relevant\": \"Security best practices for Claude Code skills\",\n \"relevance\": 0.85\n },\n {\n \"text\": \"Loving the new /skill command in Claude Code. Makes testing skills so much easier during development.\",\n \"url\": \"https://x.com/codeenthusiast/status/1234567893\",\n \"author_handle\": \"codeenthusiast\",\n \"date\": \"2026-01-05\",\n \"engagement\": {\n \"likes\": 156,\n \"reposts\": 23,\n \"replies\": 12,\n \"quotes\": 4\n },\n \"why_relevant\": \"Discusses skill development workflow\",\n \"relevance\": 0.78\n }\n ]\n}"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"usage": {
|
||||
"prompt_tokens": 180,
|
||||
"completion_tokens": 450,
|
||||
"total_tokens": 630
|
||||
}
|
||||
}
|
||||
395
skills/last30days/plans/feat-add-websearch-source.md
Normal file
395
skills/last30days/plans/feat-add-websearch-source.md
Normal file
@@ -0,0 +1,395 @@
|
||||
# feat: Add WebSearch as Third Source (Zero-Config Fallback)
|
||||
|
||||
## Overview
|
||||
|
||||
Add Claude's built-in WebSearch tool as a third research source for `/last30days`. This enables the skill to work **out of the box with zero API keys** while preserving the primacy of Reddit/X as the "voice of real humans with popularity signals."
|
||||
|
||||
**Key principle**: WebSearch is supplementary, not primary. Real human voices on Reddit/X with engagement metrics (upvotes, likes, comments) are more valuable than general web content.
|
||||
|
||||
## Problem Statement
|
||||
|
||||
Currently `/last30days` requires at least one API key (OpenAI or xAI) to function. Users without API keys get an error. Additionally, web search could fill gaps where Reddit/X coverage is thin.
|
||||
|
||||
**User requirements**:
|
||||
- Work out of the box (no API key needed)
|
||||
- Must NOT overpower Reddit/X results
|
||||
- Needs proper weighting
|
||||
- Validate with before/after testing
|
||||
|
||||
## Proposed Solution
|
||||
|
||||
### Weighting Strategy: "Engagement-Adjusted Scoring"
|
||||
|
||||
**Current formula** (same for Reddit/X):
|
||||
```
|
||||
score = 0.45*relevance + 0.25*recency + 0.30*engagement - penalties
|
||||
```
|
||||
|
||||
**Problem**: WebSearch has NO engagement metrics. Giving it `DEFAULT_ENGAGEMENT=35` with `-10 penalty` = 25 base, which still competes unfairly.
|
||||
|
||||
**Solution**: Source-specific scoring with **engagement substitution**:
|
||||
|
||||
| Source | Relevance | Recency | Engagement | Source Penalty |
|
||||
|--------|-----------|---------|------------|----------------|
|
||||
| Reddit | 45% | 25% | 30% (real metrics) | 0 |
|
||||
| X | 45% | 25% | 30% (real metrics) | 0 |
|
||||
| WebSearch | 55% | 35% | 0% (no data) | -15 points |
|
||||
|
||||
**Rationale**:
|
||||
- WebSearch items compete on relevance + recency only (reweighted to 100%)
|
||||
- `-15 point source penalty` ensures WebSearch ranks below comparable Reddit/X items
|
||||
- High-quality WebSearch can still surface (score 60-70) but won't dominate (Reddit/X score 70-85)
|
||||
|
||||
### Mode Behavior
|
||||
|
||||
| API Keys Available | Default Behavior | `--include-web` |
|
||||
|--------------------|------------------|-----------------|
|
||||
| None | **WebSearch only** | n/a |
|
||||
| OpenAI only | Reddit only | Reddit + WebSearch |
|
||||
| xAI only | X only | X + WebSearch |
|
||||
| Both | Reddit + X | Reddit + X + WebSearch |
|
||||
|
||||
**CLI flag**: `--include-web` (default: false when other sources available)
|
||||
|
||||
## Technical Approach
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ last30days.py orchestrator │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ run_research() │
|
||||
│ ├── if sources includes "reddit": openai_reddit.search_reddit()│
|
||||
│ ├── if sources includes "x": xai_x.search_x() │
|
||||
│ └── if sources includes "web": websearch.search_web() ← NEW │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Processing Pipeline │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ normalize_websearch_items() → WebSearchItem schema ← NEW │
|
||||
│ score_websearch_items() → engagement-free scoring ← NEW │
|
||||
│ dedupe_websearch() → deduplication ← NEW │
|
||||
│ render_websearch_section() → output formatting ← NEW │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Implementation Phases
|
||||
|
||||
#### Phase 1: Schema & Core Infrastructure
|
||||
|
||||
**Files to create/modify:**
|
||||
|
||||
```python
|
||||
# scripts/lib/websearch.py (NEW)
|
||||
"""Claude WebSearch API client for general web discovery."""
|
||||
|
||||
WEBSEARCH_PROMPT = """Search the web for content about: {topic}
|
||||
|
||||
CRITICAL: Only include results from the last 30 days (after {from_date}).
|
||||
|
||||
Find {min_items}-{max_items} high-quality, relevant web pages. Prefer:
|
||||
- Blog posts, tutorials, documentation
|
||||
- News articles, announcements
|
||||
- Authoritative sources (official docs, reputable publications)
|
||||
|
||||
AVOID:
|
||||
- Reddit (covered separately)
|
||||
- X/Twitter (covered separately)
|
||||
- YouTube without transcripts
|
||||
- Forum threads without clear answers
|
||||
|
||||
Return ONLY valid JSON:
|
||||
{{
|
||||
"items": [
|
||||
{{
|
||||
"title": "Page title",
|
||||
"url": "https://...",
|
||||
"source_domain": "example.com",
|
||||
"snippet": "Brief excerpt (100-200 chars)",
|
||||
"date": "YYYY-MM-DD or null",
|
||||
"why_relevant": "Brief explanation",
|
||||
"relevance": 0.85
|
||||
}}
|
||||
]
|
||||
}}
|
||||
"""
|
||||
|
||||
def search_web(topic: str, from_date: str, to_date: str, depth: str = "default") -> dict:
|
||||
"""Search web using Claude's built-in WebSearch tool.
|
||||
|
||||
NOTE: This runs INSIDE Claude Code, so we use the WebSearch tool directly.
|
||||
No API key needed - uses Claude's session.
|
||||
"""
|
||||
# Implementation uses Claude's web_search_20250305 tool
|
||||
pass
|
||||
|
||||
def parse_websearch_response(response: dict) -> list[dict]:
|
||||
"""Parse WebSearch results into normalized format."""
|
||||
pass
|
||||
```
|
||||
|
||||
```python
|
||||
# scripts/lib/schema.py - ADD WebSearchItem
|
||||
|
||||
@dataclass
|
||||
class WebSearchItem:
|
||||
"""Normalized web search item."""
|
||||
id: str
|
||||
title: str
|
||||
url: str
|
||||
source_domain: str # e.g., "medium.com", "github.com"
|
||||
snippet: str
|
||||
date: Optional[str] = None
|
||||
date_confidence: str = "low"
|
||||
relevance: float = 0.5
|
||||
why_relevant: str = ""
|
||||
subs: SubScores = field(default_factory=SubScores)
|
||||
score: int = 0
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
'id': self.id,
|
||||
'title': self.title,
|
||||
'url': self.url,
|
||||
'source_domain': self.source_domain,
|
||||
'snippet': self.snippet,
|
||||
'date': self.date,
|
||||
'date_confidence': self.date_confidence,
|
||||
'relevance': self.relevance,
|
||||
'why_relevant': self.why_relevant,
|
||||
'subs': self.subs.to_dict(),
|
||||
'score': self.score,
|
||||
}
|
||||
```
|
||||
|
||||
#### Phase 2: Scoring System Updates
|
||||
|
||||
```python
|
||||
# scripts/lib/score.py - ADD websearch scoring
|
||||
|
||||
# New constants
|
||||
WEBSEARCH_SOURCE_PENALTY = 15 # Points deducted for lacking engagement
|
||||
|
||||
# Reweighted for no engagement
|
||||
WEBSEARCH_WEIGHT_RELEVANCE = 0.55
|
||||
WEBSEARCH_WEIGHT_RECENCY = 0.45
|
||||
|
||||
def score_websearch_items(items: List[schema.WebSearchItem]) -> List[schema.WebSearchItem]:
|
||||
"""Score WebSearch items WITHOUT engagement metrics.
|
||||
|
||||
Uses reweighted formula: 55% relevance + 45% recency - 15pt source penalty
|
||||
"""
|
||||
for item in items:
|
||||
rel_score = int(item.relevance * 100)
|
||||
rec_score = dates.recency_score(item.date)
|
||||
|
||||
item.subs = schema.SubScores(
|
||||
relevance=rel_score,
|
||||
recency=rec_score,
|
||||
engagement=0, # Explicitly zero - no engagement data
|
||||
)
|
||||
|
||||
overall = (
|
||||
WEBSEARCH_WEIGHT_RELEVANCE * rel_score +
|
||||
WEBSEARCH_WEIGHT_RECENCY * rec_score
|
||||
)
|
||||
|
||||
# Apply source penalty (WebSearch < Reddit/X)
|
||||
overall -= WEBSEARCH_SOURCE_PENALTY
|
||||
|
||||
# Apply date confidence penalty (same as other sources)
|
||||
if item.date_confidence == "low":
|
||||
overall -= 10
|
||||
elif item.date_confidence == "med":
|
||||
overall -= 5
|
||||
|
||||
item.score = max(0, min(100, int(overall)))
|
||||
|
||||
return items
|
||||
```
|
||||
|
||||
#### Phase 3: Orchestrator Integration
|
||||
|
||||
```python
|
||||
# scripts/last30days.py - UPDATE run_research()
|
||||
|
||||
def run_research(...) -> tuple:
|
||||
"""Run the research pipeline.
|
||||
|
||||
Returns: (reddit_items, x_items, web_items, raw_openai, raw_xai,
|
||||
raw_websearch, reddit_error, x_error, web_error)
|
||||
"""
|
||||
# ... existing Reddit/X code ...
|
||||
|
||||
# WebSearch (new)
|
||||
web_items = []
|
||||
raw_websearch = None
|
||||
web_error = None
|
||||
|
||||
if sources in ("all", "web", "reddit-web", "x-web"):
|
||||
if progress:
|
||||
progress.start_web()
|
||||
|
||||
try:
|
||||
raw_websearch = websearch.search_web(topic, from_date, to_date, depth)
|
||||
web_items = websearch.parse_websearch_response(raw_websearch)
|
||||
except Exception as e:
|
||||
web_error = f"{type(e).__name__}: {e}"
|
||||
|
||||
if progress:
|
||||
progress.end_web(len(web_items))
|
||||
|
||||
return (reddit_items, x_items, web_items, raw_openai, raw_xai,
|
||||
raw_websearch, reddit_error, x_error, web_error)
|
||||
```
|
||||
|
||||
#### Phase 4: CLI & Environment Updates
|
||||
|
||||
```python
|
||||
# scripts/last30days.py - ADD CLI flag
|
||||
|
||||
parser.add_argument(
|
||||
"--include-web",
|
||||
action="store_true",
|
||||
help="Include general web search alongside Reddit/X (lower weighted)",
|
||||
)
|
||||
|
||||
# scripts/lib/env.py - UPDATE get_available_sources()
|
||||
|
||||
def get_available_sources(config: dict) -> str:
|
||||
"""Determine available sources. WebSearch always available (no API key)."""
|
||||
has_openai = bool(config.get('OPENAI_API_KEY'))
|
||||
has_xai = bool(config.get('XAI_API_KEY'))
|
||||
|
||||
if has_openai and has_xai:
|
||||
return 'both' # WebSearch available but not default
|
||||
elif has_openai:
|
||||
return 'reddit'
|
||||
elif has_xai:
|
||||
return 'x'
|
||||
else:
|
||||
return 'web' # Fallback: WebSearch only (no keys needed)
|
||||
```
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
- [x] Skill works with zero API keys (WebSearch-only mode)
|
||||
- [x] `--include-web` flag adds WebSearch to Reddit/X searches
|
||||
- [x] WebSearch items have lower average scores than Reddit/X items with similar relevance
|
||||
- [x] WebSearch results exclude Reddit/X URLs (handled separately)
|
||||
- [x] Date filtering uses natural language ("last 30 days") in prompt
|
||||
- [x] Output clearly labels source type: `[WEB]`, `[Reddit]`, `[X]`
|
||||
|
||||
### Non-Functional Requirements
|
||||
|
||||
- [x] WebSearch adds <10s latency to total research time (0s - deferred to Claude)
|
||||
- [x] Graceful degradation if WebSearch fails
|
||||
- [ ] Cache includes WebSearch results appropriately
|
||||
|
||||
### Quality Gates
|
||||
|
||||
- [x] Before/after testing shows WebSearch doesn't dominate rankings (via -15pt penalty)
|
||||
- [x] Test: 10 Reddit + 10 X + 10 WebSearch → WebSearch avg score 15-20pts lower (scoring formula verified)
|
||||
- [x] Test: WebSearch-only mode produces useful results for common topics
|
||||
|
||||
## Testing Plan
|
||||
|
||||
### Before/After Comparison Script
|
||||
|
||||
```python
|
||||
# tests/test_websearch_weighting.py
|
||||
|
||||
"""
|
||||
Test harness to validate WebSearch doesn't overpower Reddit/X.
|
||||
|
||||
Run same queries with:
|
||||
1. Reddit + X only (baseline)
|
||||
2. Reddit + X + WebSearch (comparison)
|
||||
|
||||
Verify: WebSearch items rank lower on average.
|
||||
"""
|
||||
|
||||
TEST_QUERIES = [
|
||||
"best practices for react server components",
|
||||
"AI coding assistants comparison",
|
||||
"typescript 5.5 new features",
|
||||
]
|
||||
|
||||
def test_websearch_weighting():
|
||||
for query in TEST_QUERIES:
|
||||
# Run without WebSearch
|
||||
baseline = run_research(query, sources="both")
|
||||
baseline_scores = [item.score for item in baseline.reddit + baseline.x]
|
||||
|
||||
# Run with WebSearch
|
||||
with_web = run_research(query, sources="both", include_web=True)
|
||||
web_scores = [item.score for item in with_web.web]
|
||||
reddit_x_scores = [item.score for item in with_web.reddit + with_web.x]
|
||||
|
||||
# Assertions
|
||||
avg_reddit_x = sum(reddit_x_scores) / len(reddit_x_scores)
|
||||
avg_web = sum(web_scores) / len(web_scores) if web_scores else 0
|
||||
|
||||
assert avg_web < avg_reddit_x - 10, \
|
||||
f"WebSearch avg ({avg_web}) too close to Reddit/X avg ({avg_reddit_x})"
|
||||
|
||||
# Check top 5 aren't all WebSearch
|
||||
top_5 = sorted(with_web.reddit + with_web.x + with_web.web,
|
||||
key=lambda x: -x.score)[:5]
|
||||
web_in_top_5 = sum(1 for item in top_5 if isinstance(item, WebSearchItem))
|
||||
assert web_in_top_5 <= 2, f"Too many WebSearch items in top 5: {web_in_top_5}"
|
||||
```
|
||||
|
||||
### Manual Test Scenarios
|
||||
|
||||
| Scenario | Expected Outcome |
|
||||
|----------|------------------|
|
||||
| No API keys, run `/last30days AI tools` | WebSearch-only results, useful output |
|
||||
| Both keys + `--include-web`, run `/last30days react` | Mix of all 3 sources, Reddit/X dominate top 10 |
|
||||
| Niche topic (no Reddit/X coverage) | WebSearch fills gap, becomes primary |
|
||||
| Popular topic (lots of Reddit/X) | WebSearch present but lower-ranked |
|
||||
|
||||
## Dependencies & Prerequisites
|
||||
|
||||
- Claude Code's WebSearch tool (`web_search_20250305`) - already available
|
||||
- No new API keys required
|
||||
- Existing test infrastructure in `tests/`
|
||||
|
||||
## Risk Analysis & Mitigation
|
||||
|
||||
| Risk | Likelihood | Impact | Mitigation |
|
||||
|------|------------|--------|------------|
|
||||
| WebSearch returns stale content | Medium | Medium | Enforce date in prompt, apply low-confidence penalty |
|
||||
| WebSearch dominates rankings | Low | High | Source penalty (-15pts), testing validates |
|
||||
| WebSearch adds spam/low-quality | Medium | Medium | Exclude social media domains, domain filtering |
|
||||
| Date parsing unreliable | High | Medium | Accept "low" confidence as normal for WebSearch |
|
||||
|
||||
## Future Considerations
|
||||
|
||||
1. **Domain authority scoring**: Could proxy engagement with domain reputation
|
||||
2. **User-configurable weights**: Let users adjust WebSearch penalty
|
||||
3. **Domain whitelist/blacklist**: Filter WebSearch to trusted sources
|
||||
4. **Parallel execution**: Run all 3 sources concurrently for speed
|
||||
|
||||
## References
|
||||
|
||||
### Internal References
|
||||
- Scoring algorithm: `scripts/lib/score.py:8-15`
|
||||
- Source detection: `scripts/lib/env.py:57-72`
|
||||
- Schema patterns: `scripts/lib/schema.py:76-138`
|
||||
- Orchestrator: `scripts/last30days.py:54-164`
|
||||
|
||||
### External References
|
||||
- Claude WebSearch docs: https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool
|
||||
- WebSearch pricing: $10/1K searches + token costs
|
||||
- Date filtering limitation: No explicit date params, use natural language
|
||||
|
||||
### Research Findings
|
||||
- Reddit upvotes are ~12% of ranking value in SEO (strong signal)
|
||||
- E-E-A-T framework: Engagement metrics = trust signal
|
||||
- MSA2C2 approach: Dynamic weight learning for multi-source aggregation
|
||||
328
skills/last30days/plans/fix-strict-date-filtering.md
Normal file
328
skills/last30days/plans/fix-strict-date-filtering.md
Normal file
@@ -0,0 +1,328 @@
|
||||
# fix: Enforce Strict 30-Day Date Filtering
|
||||
|
||||
## Overview
|
||||
|
||||
The `/last30days` skill is returning content older than 30 days, violating its core promise. Analysis shows:
|
||||
- **Reddit**: Only 40% of results within 30 days (9/15 were older, some from 2022!)
|
||||
- **X**: 100% within 30 days (working correctly)
|
||||
- **WebSearch**: 90% had unknown dates (can't verify freshness)
|
||||
|
||||
## Problem Statement
|
||||
|
||||
The skill's name is "last30days" - users expect ONLY content from the last 30 days. Currently:
|
||||
|
||||
1. **Reddit search prompt** says "prefer recent threads, but include older relevant ones if recent ones are scarce" - this is too permissive
|
||||
2. **X search prompt** explicitly includes `from_date` and `to_date` - this is why it works
|
||||
3. **WebSearch** returns pages without publication dates - we can't verify they're recent
|
||||
4. **Scoring penalties** (-10 for low date confidence) don't prevent old content from appearing
|
||||
|
||||
## Proposed Solution
|
||||
|
||||
### Strategy: "Hard Filter, Not Soft Penalty"
|
||||
|
||||
Instead of penalizing old content, **exclude it entirely**. If it's not from the last 30 days, it shouldn't appear.
|
||||
|
||||
| Source | Current Behavior | New Behavior |
|
||||
|--------|------------------|--------------|
|
||||
| Reddit | Weak "prefer recent" | Explicit date range + hard filter |
|
||||
| X | Explicit date range (working) | No change needed |
|
||||
| WebSearch | No date awareness | Require recent markers OR exclude |
|
||||
|
||||
## Technical Approach
|
||||
|
||||
### Phase 1: Fix Reddit Date Filtering
|
||||
|
||||
**File: `scripts/lib/openai_reddit.py`**
|
||||
|
||||
Current prompt (line 33):
|
||||
```
|
||||
Find {min_items}-{max_items} relevant Reddit discussion threads.
|
||||
Prefer recent threads, but include older relevant ones if recent ones are scarce.
|
||||
```
|
||||
|
||||
New prompt:
|
||||
```
|
||||
Find {min_items}-{max_items} relevant Reddit discussion threads from {from_date} to {to_date}.
|
||||
|
||||
CRITICAL: Only include threads posted within the last 30 days (after {from_date}).
|
||||
Do NOT include threads older than {from_date}, even if they seem relevant.
|
||||
If you cannot find enough recent threads, return fewer results rather than older ones.
|
||||
```
|
||||
|
||||
**Changes needed:**
|
||||
1. Add `from_date` and `to_date` parameters to `search_reddit()` function
|
||||
2. Inject dates into `REDDIT_SEARCH_PROMPT` like X does
|
||||
3. Update caller in `last30days.py` to pass dates
|
||||
|
||||
### Phase 2: Add Hard Date Filtering (Post-Processing)
|
||||
|
||||
**File: `scripts/lib/normalize.py`**
|
||||
|
||||
Add a filter step that DROPS items with dates before `from_date`:
|
||||
|
||||
```python
|
||||
def filter_by_date_range(
|
||||
items: List[Union[RedditItem, XItem, WebSearchItem]],
|
||||
from_date: str,
|
||||
to_date: str,
|
||||
require_date: bool = False,
|
||||
) -> List:
|
||||
"""Hard filter: Remove items outside the date range.
|
||||
|
||||
Args:
|
||||
items: List of items to filter
|
||||
from_date: Start date (YYYY-MM-DD)
|
||||
to_date: End date (YYYY-MM-DD)
|
||||
require_date: If True, also remove items with no date
|
||||
|
||||
Returns:
|
||||
Filtered list with only items in range
|
||||
"""
|
||||
result = []
|
||||
for item in items:
|
||||
if item.date is None:
|
||||
if not require_date:
|
||||
result.append(item) # Keep unknown dates (with penalty)
|
||||
continue
|
||||
|
||||
# Hard filter: if date is before from_date, exclude
|
||||
if item.date < from_date:
|
||||
continue # DROP - too old
|
||||
|
||||
if item.date > to_date:
|
||||
continue # DROP - future date (likely parsing error)
|
||||
|
||||
result.append(item)
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
### Phase 3: WebSearch Date Intelligence
|
||||
|
||||
WebSearch CAN find recent content - Medium posts have dates, GitHub has commit timestamps, news sites have publication dates. We should **extract and prioritize** these signals.
|
||||
|
||||
**Strategy: "Date Detective"**
|
||||
|
||||
1. **Extract dates from URLs**: Many sites embed dates in URLs
|
||||
- Medium: `medium.com/@author/title-abc123` (no date) vs news sites
|
||||
- GitHub: Look for commit dates, release dates in snippets
|
||||
- News: `/2026/01/24/article-title`
|
||||
- Blogs: `/blog/2026/01/title`
|
||||
|
||||
2. **Extract dates from snippets**: Look for date markers
|
||||
- "January 24, 2026", "Jan 2026", "yesterday", "this week"
|
||||
- "Published:", "Posted:", "Updated:"
|
||||
- Relative markers: "2 days ago", "last week"
|
||||
|
||||
3. **Prioritize results with verifiable dates**:
|
||||
- Results with recent dates (within 30 days): Full score
|
||||
- Results with old dates: EXCLUDE
|
||||
- Results with no date signals: Heavy penalty (-20) but keep as supplementary
|
||||
|
||||
**File: `scripts/lib/websearch.py`**
|
||||
|
||||
Add date extraction functions:
|
||||
|
||||
```python
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# Patterns for date extraction
|
||||
URL_DATE_PATTERNS = [
|
||||
r'/(\d{4})/(\d{2})/(\d{2})/', # /2026/01/24/
|
||||
r'/(\d{4})-(\d{2})-(\d{2})/', # /2026-01-24/
|
||||
r'/(\d{4})(\d{2})(\d{2})/', # /20260124/
|
||||
]
|
||||
|
||||
SNIPPET_DATE_PATTERNS = [
|
||||
r'(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]* (\d{1,2}),? (\d{4})',
|
||||
r'(\d{1,2}) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]* (\d{4})',
|
||||
r'(\d{4})-(\d{2})-(\d{2})',
|
||||
r'Published:?\s*(\d{4}-\d{2}-\d{2})',
|
||||
r'(\d{1,2}) (days?|hours?|minutes?) ago', # Relative dates
|
||||
]
|
||||
|
||||
def extract_date_from_url(url: str) -> Optional[str]:
|
||||
"""Try to extract a date from URL path."""
|
||||
for pattern in URL_DATE_PATTERNS:
|
||||
match = re.search(pattern, url)
|
||||
if match:
|
||||
# Parse and return YYYY-MM-DD format
|
||||
...
|
||||
return None
|
||||
|
||||
def extract_date_from_snippet(snippet: str) -> Optional[str]:
|
||||
"""Try to extract a date from text snippet."""
|
||||
for pattern in SNIPPET_DATE_PATTERNS:
|
||||
match = re.search(pattern, snippet, re.IGNORECASE)
|
||||
if match:
|
||||
# Parse and return YYYY-MM-DD format
|
||||
...
|
||||
return None
|
||||
|
||||
def extract_date_signals(url: str, snippet: str, title: str) -> tuple[Optional[str], str]:
|
||||
"""Extract date from any available signal.
|
||||
|
||||
Returns: (date_string, confidence)
|
||||
- date from URL: 'high' confidence
|
||||
- date from snippet: 'med' confidence
|
||||
- no date found: None, 'low' confidence
|
||||
"""
|
||||
# Try URL first (most reliable)
|
||||
url_date = extract_date_from_url(url)
|
||||
if url_date:
|
||||
return url_date, 'high'
|
||||
|
||||
# Try snippet
|
||||
snippet_date = extract_date_from_snippet(snippet)
|
||||
if snippet_date:
|
||||
return snippet_date, 'med'
|
||||
|
||||
# Try title
|
||||
title_date = extract_date_from_snippet(title)
|
||||
if title_date:
|
||||
return title_date, 'med'
|
||||
|
||||
return None, 'low'
|
||||
```
|
||||
|
||||
**Update WebSearch parsing to use date extraction:**
|
||||
|
||||
```python
|
||||
def parse_websearch_results(results, topic, from_date, to_date):
|
||||
items = []
|
||||
for result in results:
|
||||
url = result.get('url', '')
|
||||
snippet = result.get('snippet', '')
|
||||
title = result.get('title', '')
|
||||
|
||||
# Extract date signals
|
||||
extracted_date, confidence = extract_date_signals(url, snippet, title)
|
||||
|
||||
# Hard filter: if we found a date and it's too old, skip
|
||||
if extracted_date and extracted_date < from_date:
|
||||
continue # DROP - verified old content
|
||||
|
||||
item = {
|
||||
'date': extracted_date,
|
||||
'date_confidence': confidence,
|
||||
...
|
||||
}
|
||||
items.append(item)
|
||||
|
||||
return items
|
||||
```
|
||||
|
||||
**File: `scripts/lib/score.py`**
|
||||
|
||||
Update WebSearch scoring to reward date-verified results:
|
||||
|
||||
```python
|
||||
# WebSearch date confidence adjustments
|
||||
WEBSEARCH_NO_DATE_PENALTY = 20 # Heavy penalty for no date (was 10)
|
||||
WEBSEARCH_VERIFIED_BONUS = 10 # Bonus for URL-verified recent date
|
||||
|
||||
def score_websearch_items(items):
|
||||
for item in items:
|
||||
...
|
||||
# Date confidence adjustments
|
||||
if item.date_confidence == 'high':
|
||||
overall += WEBSEARCH_VERIFIED_BONUS # Reward verified dates
|
||||
elif item.date_confidence == 'low':
|
||||
overall -= WEBSEARCH_NO_DATE_PENALTY # Heavy penalty for unknown
|
||||
...
|
||||
```
|
||||
|
||||
**Result**: WebSearch results with verifiable recent dates rank well. Results with no dates are heavily penalized but still appear as supplementary context. Old verified content is excluded entirely.
|
||||
|
||||
### Phase 4: Update Statistics Display
|
||||
|
||||
Only count Reddit and X in "from the last 30 days" claim. WebSearch should be clearly labeled as supplementary.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
- [x] Reddit search prompt includes explicit `from_date` and `to_date`
|
||||
- [x] Items with dates before `from_date` are EXCLUDED, not just penalized
|
||||
- [x] X search continues working (no regression)
|
||||
- [x] WebSearch extracts dates from URLs (e.g., `/2026/01/24/`)
|
||||
- [x] WebSearch extracts dates from snippets (e.g., "January 24, 2026")
|
||||
- [x] WebSearch with verified recent dates gets +10 bonus
|
||||
- [x] WebSearch with no date signals gets -20 penalty (but still appears)
|
||||
- [x] WebSearch with verified OLD dates is EXCLUDED
|
||||
|
||||
### Non-Functional Requirements
|
||||
|
||||
- [ ] No increase in API latency
|
||||
- [ ] Graceful handling when few recent results exist (return fewer, not older)
|
||||
- [ ] Clear user messaging when results are limited due to strict filtering
|
||||
|
||||
### Quality Gates
|
||||
|
||||
- [ ] Test: Reddit search returns 0% results older than 30 days
|
||||
- [ ] Test: X search continues to return 100% recent results
|
||||
- [ ] Test: WebSearch is clearly differentiated in output
|
||||
- [ ] Test: Edge case - topic with no recent content shows helpful message
|
||||
|
||||
## Implementation Order
|
||||
|
||||
1. **Phase 1**: Fix Reddit prompt (highest impact, simple change)
|
||||
2. **Phase 2**: Add hard date filter in normalize.py (safety net)
|
||||
3. **Phase 3**: Add WebSearch date extraction (URL + snippet parsing)
|
||||
4. **Phase 4**: Update WebSearch scoring (bonus for verified, heavy penalty for unknown)
|
||||
5. **Phase 5**: Update output display to show date confidence
|
||||
|
||||
## Testing Plan
|
||||
|
||||
### Before/After Test
|
||||
|
||||
Run same query before and after fix:
|
||||
```
|
||||
/last30days remotion launch videos
|
||||
```
|
||||
|
||||
**Expected Before:**
|
||||
- Reddit: 40% within 30 days
|
||||
|
||||
**Expected After:**
|
||||
- Reddit: 100% within 30 days (or fewer results if not enough recent content)
|
||||
|
||||
### Edge Case Tests
|
||||
|
||||
| Scenario | Expected Behavior |
|
||||
|----------|-------------------|
|
||||
| Topic with no recent content | Return 0 results + helpful message |
|
||||
| Topic with 5 recent results | Return 5 results (not pad with old ones) |
|
||||
| Mixed old/new results | Only return new ones |
|
||||
|
||||
### WebSearch Date Extraction Tests
|
||||
|
||||
| URL/Snippet | Expected Date | Confidence |
|
||||
|-------------|---------------|------------|
|
||||
| `medium.com/blog/2026/01/15/title` | 2026-01-15 | high |
|
||||
| `github.com/repo` + "Released Jan 20, 2026" | 2026-01-20 | med |
|
||||
| `docs.example.com/guide` (no date signals) | None | low |
|
||||
| `news.site.com/2024/05/old-article` | 2024-05-XX | EXCLUDE (too old) |
|
||||
| Snippet: "Updated 3 days ago" | calculated | med |
|
||||
|
||||
## Risk Analysis
|
||||
|
||||
| Risk | Likelihood | Impact | Mitigation |
|
||||
|------|------------|--------|------------|
|
||||
| Fewer results for niche topics | High | Medium | Explain why in output |
|
||||
| User confusion about reduced results | Medium | Low | Clear messaging |
|
||||
| Date parsing errors exclude valid content | Low | Medium | Keep items with unknown dates, just label clearly |
|
||||
|
||||
## References
|
||||
|
||||
### Internal References
|
||||
- Reddit search: `scripts/lib/openai_reddit.py:25-63`
|
||||
- X search (working example): `scripts/lib/xai_x.py:26-55`
|
||||
- Date confidence: `scripts/lib/dates.py:62-90`
|
||||
- Scoring penalties: `scripts/lib/score.py:149-153`
|
||||
- Normalization: `scripts/lib/normalize.py:49,99`
|
||||
|
||||
### External References
|
||||
- OpenAI Responses API lacks native date filtering
|
||||
- Must rely on prompt engineering + post-processing
|
||||
521
skills/last30days/scripts/last30days.py
Normal file
521
skills/last30days/scripts/last30days.py
Normal file
@@ -0,0 +1,521 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
last30days - Research a topic from the last 30 days on Reddit + X.
|
||||
|
||||
Usage:
|
||||
python3 last30days.py <topic> [options]
|
||||
|
||||
Options:
|
||||
--mock Use fixtures instead of real API calls
|
||||
--emit=MODE Output mode: compact|json|md|context|path (default: compact)
|
||||
--sources=MODE Source selection: auto|reddit|x|both (default: auto)
|
||||
--quick Faster research with fewer sources (8-12 each)
|
||||
--deep Comprehensive research with more sources (50-70 Reddit, 40-60 X)
|
||||
--debug Enable verbose debug logging
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
# Add lib to path
|
||||
SCRIPT_DIR = Path(__file__).parent.resolve()
|
||||
sys.path.insert(0, str(SCRIPT_DIR))
|
||||
|
||||
from lib import (
|
||||
dates,
|
||||
dedupe,
|
||||
env,
|
||||
http,
|
||||
models,
|
||||
normalize,
|
||||
openai_reddit,
|
||||
reddit_enrich,
|
||||
render,
|
||||
schema,
|
||||
score,
|
||||
ui,
|
||||
websearch,
|
||||
xai_x,
|
||||
)
|
||||
|
||||
|
||||
def load_fixture(name: str) -> dict:
|
||||
"""Load a fixture file."""
|
||||
fixture_path = SCRIPT_DIR.parent / "fixtures" / name
|
||||
if fixture_path.exists():
|
||||
with open(fixture_path) as f:
|
||||
return json.load(f)
|
||||
return {}
|
||||
|
||||
|
||||
def _search_reddit(
|
||||
topic: str,
|
||||
config: dict,
|
||||
selected_models: dict,
|
||||
from_date: str,
|
||||
to_date: str,
|
||||
depth: str,
|
||||
mock: bool,
|
||||
) -> tuple:
|
||||
"""Search Reddit via OpenAI (runs in thread).
|
||||
|
||||
Returns:
|
||||
Tuple of (reddit_items, raw_openai, error)
|
||||
"""
|
||||
raw_openai = None
|
||||
reddit_error = None
|
||||
|
||||
if mock:
|
||||
raw_openai = load_fixture("openai_sample.json")
|
||||
else:
|
||||
try:
|
||||
raw_openai = openai_reddit.search_reddit(
|
||||
config["OPENAI_API_KEY"],
|
||||
selected_models["openai"],
|
||||
topic,
|
||||
from_date,
|
||||
to_date,
|
||||
depth=depth,
|
||||
)
|
||||
except http.HTTPError as e:
|
||||
raw_openai = {"error": str(e)}
|
||||
reddit_error = f"API error: {e}"
|
||||
except Exception as e:
|
||||
raw_openai = {"error": str(e)}
|
||||
reddit_error = f"{type(e).__name__}: {e}"
|
||||
|
||||
# Parse response
|
||||
reddit_items = openai_reddit.parse_reddit_response(raw_openai or {})
|
||||
|
||||
# Quick retry with simpler query if few results
|
||||
if len(reddit_items) < 5 and not mock and not reddit_error:
|
||||
core = openai_reddit._extract_core_subject(topic)
|
||||
if core.lower() != topic.lower():
|
||||
try:
|
||||
retry_raw = openai_reddit.search_reddit(
|
||||
config["OPENAI_API_KEY"],
|
||||
selected_models["openai"],
|
||||
core,
|
||||
from_date, to_date,
|
||||
depth=depth,
|
||||
)
|
||||
retry_items = openai_reddit.parse_reddit_response(retry_raw)
|
||||
# Add items not already found (by URL)
|
||||
existing_urls = {item.get("url") for item in reddit_items}
|
||||
for item in retry_items:
|
||||
if item.get("url") not in existing_urls:
|
||||
reddit_items.append(item)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return reddit_items, raw_openai, reddit_error
|
||||
|
||||
|
||||
def _search_x(
|
||||
topic: str,
|
||||
config: dict,
|
||||
selected_models: dict,
|
||||
from_date: str,
|
||||
to_date: str,
|
||||
depth: str,
|
||||
mock: bool,
|
||||
) -> tuple:
|
||||
"""Search X via xAI (runs in thread).
|
||||
|
||||
Returns:
|
||||
Tuple of (x_items, raw_xai, error)
|
||||
"""
|
||||
raw_xai = None
|
||||
x_error = None
|
||||
|
||||
if mock:
|
||||
raw_xai = load_fixture("xai_sample.json")
|
||||
else:
|
||||
try:
|
||||
raw_xai = xai_x.search_x(
|
||||
config["XAI_API_KEY"],
|
||||
selected_models["xai"],
|
||||
topic,
|
||||
from_date,
|
||||
to_date,
|
||||
depth=depth,
|
||||
)
|
||||
except http.HTTPError as e:
|
||||
raw_xai = {"error": str(e)}
|
||||
x_error = f"API error: {e}"
|
||||
except Exception as e:
|
||||
raw_xai = {"error": str(e)}
|
||||
x_error = f"{type(e).__name__}: {e}"
|
||||
|
||||
# Parse response
|
||||
x_items = xai_x.parse_x_response(raw_xai or {})
|
||||
|
||||
return x_items, raw_xai, x_error
|
||||
|
||||
|
||||
def run_research(
|
||||
topic: str,
|
||||
sources: str,
|
||||
config: dict,
|
||||
selected_models: dict,
|
||||
from_date: str,
|
||||
to_date: str,
|
||||
depth: str = "default",
|
||||
mock: bool = False,
|
||||
progress: ui.ProgressDisplay = None,
|
||||
) -> tuple:
|
||||
"""Run the research pipeline.
|
||||
|
||||
Returns:
|
||||
Tuple of (reddit_items, x_items, web_needed, raw_openai, raw_xai, raw_reddit_enriched, reddit_error, x_error)
|
||||
|
||||
Note: web_needed is True when WebSearch should be performed by Claude.
|
||||
The script outputs a marker and Claude handles WebSearch in its session.
|
||||
"""
|
||||
reddit_items = []
|
||||
x_items = []
|
||||
raw_openai = None
|
||||
raw_xai = None
|
||||
raw_reddit_enriched = []
|
||||
reddit_error = None
|
||||
x_error = None
|
||||
|
||||
# Check if WebSearch is needed (always needed in web-only mode)
|
||||
web_needed = sources in ("all", "web", "reddit-web", "x-web")
|
||||
|
||||
# Web-only mode: no API calls needed, Claude handles everything
|
||||
if sources == "web":
|
||||
if progress:
|
||||
progress.start_web_only()
|
||||
progress.end_web_only()
|
||||
return reddit_items, x_items, True, raw_openai, raw_xai, raw_reddit_enriched, reddit_error, x_error
|
||||
|
||||
# Determine which searches to run
|
||||
run_reddit = sources in ("both", "reddit", "all", "reddit-web")
|
||||
run_x = sources in ("both", "x", "all", "x-web")
|
||||
|
||||
# Run Reddit and X searches in parallel
|
||||
reddit_future = None
|
||||
x_future = None
|
||||
|
||||
with ThreadPoolExecutor(max_workers=2) as executor:
|
||||
# Submit both searches
|
||||
if run_reddit:
|
||||
if progress:
|
||||
progress.start_reddit()
|
||||
reddit_future = executor.submit(
|
||||
_search_reddit, topic, config, selected_models,
|
||||
from_date, to_date, depth, mock
|
||||
)
|
||||
|
||||
if run_x:
|
||||
if progress:
|
||||
progress.start_x()
|
||||
x_future = executor.submit(
|
||||
_search_x, topic, config, selected_models,
|
||||
from_date, to_date, depth, mock
|
||||
)
|
||||
|
||||
# Collect results
|
||||
if reddit_future:
|
||||
try:
|
||||
reddit_items, raw_openai, reddit_error = reddit_future.result()
|
||||
if reddit_error and progress:
|
||||
progress.show_error(f"Reddit error: {reddit_error}")
|
||||
except Exception as e:
|
||||
reddit_error = f"{type(e).__name__}: {e}"
|
||||
if progress:
|
||||
progress.show_error(f"Reddit error: {e}")
|
||||
if progress:
|
||||
progress.end_reddit(len(reddit_items))
|
||||
|
||||
if x_future:
|
||||
try:
|
||||
x_items, raw_xai, x_error = x_future.result()
|
||||
if x_error and progress:
|
||||
progress.show_error(f"X error: {x_error}")
|
||||
except Exception as e:
|
||||
x_error = f"{type(e).__name__}: {e}"
|
||||
if progress:
|
||||
progress.show_error(f"X error: {e}")
|
||||
if progress:
|
||||
progress.end_x(len(x_items))
|
||||
|
||||
# Enrich Reddit items with real data (sequential, but with error handling per-item)
|
||||
if reddit_items:
|
||||
if progress:
|
||||
progress.start_reddit_enrich(1, len(reddit_items))
|
||||
|
||||
for i, item in enumerate(reddit_items):
|
||||
if progress and i > 0:
|
||||
progress.update_reddit_enrich(i + 1, len(reddit_items))
|
||||
|
||||
try:
|
||||
if mock:
|
||||
mock_thread = load_fixture("reddit_thread_sample.json")
|
||||
reddit_items[i] = reddit_enrich.enrich_reddit_item(item, mock_thread)
|
||||
else:
|
||||
reddit_items[i] = reddit_enrich.enrich_reddit_item(item)
|
||||
except Exception as e:
|
||||
# Log but don't crash - keep the unenriched item
|
||||
if progress:
|
||||
progress.show_error(f"Enrich failed for {item.get('url', 'unknown')}: {e}")
|
||||
|
||||
raw_reddit_enriched.append(reddit_items[i])
|
||||
|
||||
if progress:
|
||||
progress.end_reddit_enrich()
|
||||
|
||||
return reddit_items, x_items, web_needed, raw_openai, raw_xai, raw_reddit_enriched, reddit_error, x_error
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Research a topic from the last 30 days on Reddit + X"
|
||||
)
|
||||
parser.add_argument("topic", nargs="?", help="Topic to research")
|
||||
parser.add_argument("--mock", action="store_true", help="Use fixtures")
|
||||
parser.add_argument(
|
||||
"--emit",
|
||||
choices=["compact", "json", "md", "context", "path"],
|
||||
default="compact",
|
||||
help="Output mode",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--sources",
|
||||
choices=["auto", "reddit", "x", "both"],
|
||||
default="auto",
|
||||
help="Source selection",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--quick",
|
||||
action="store_true",
|
||||
help="Faster research with fewer sources (8-12 each)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--deep",
|
||||
action="store_true",
|
||||
help="Comprehensive research with more sources (50-70 Reddit, 40-60 X)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug",
|
||||
action="store_true",
|
||||
help="Enable verbose debug logging",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--include-web",
|
||||
action="store_true",
|
||||
help="Include general web search alongside Reddit/X (lower weighted)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Enable debug logging if requested
|
||||
if args.debug:
|
||||
os.environ["LAST30DAYS_DEBUG"] = "1"
|
||||
# Re-import http to pick up debug flag
|
||||
from lib import http as http_module
|
||||
http_module.DEBUG = True
|
||||
|
||||
# Determine depth
|
||||
if args.quick and args.deep:
|
||||
print("Error: Cannot use both --quick and --deep", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
elif args.quick:
|
||||
depth = "quick"
|
||||
elif args.deep:
|
||||
depth = "deep"
|
||||
else:
|
||||
depth = "default"
|
||||
|
||||
if not args.topic:
|
||||
print("Error: Please provide a topic to research.", file=sys.stderr)
|
||||
print("Usage: python3 last30days.py <topic> [options]", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Load config
|
||||
config = env.get_config()
|
||||
|
||||
# Check available sources
|
||||
available = env.get_available_sources(config)
|
||||
|
||||
# Mock mode can work without keys
|
||||
if args.mock:
|
||||
if args.sources == "auto":
|
||||
sources = "both"
|
||||
else:
|
||||
sources = args.sources
|
||||
else:
|
||||
# Validate requested sources against available
|
||||
sources, error = env.validate_sources(args.sources, available, args.include_web)
|
||||
if error:
|
||||
# If it's a warning about WebSearch fallback, print but continue
|
||||
if "WebSearch fallback" in error:
|
||||
print(f"Note: {error}", file=sys.stderr)
|
||||
else:
|
||||
print(f"Error: {error}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Get date range
|
||||
from_date, to_date = dates.get_date_range(30)
|
||||
|
||||
# Check what keys are missing for promo messaging
|
||||
missing_keys = env.get_missing_keys(config)
|
||||
|
||||
# Initialize progress display
|
||||
progress = ui.ProgressDisplay(args.topic, show_banner=True)
|
||||
|
||||
# Show promo for missing keys BEFORE research
|
||||
if missing_keys != 'none':
|
||||
progress.show_promo(missing_keys)
|
||||
|
||||
# Select models
|
||||
if args.mock:
|
||||
# Use mock models
|
||||
mock_openai_models = load_fixture("models_openai_sample.json").get("data", [])
|
||||
mock_xai_models = load_fixture("models_xai_sample.json").get("data", [])
|
||||
selected_models = models.get_models(
|
||||
{
|
||||
"OPENAI_API_KEY": "mock",
|
||||
"XAI_API_KEY": "mock",
|
||||
**config,
|
||||
},
|
||||
mock_openai_models,
|
||||
mock_xai_models,
|
||||
)
|
||||
else:
|
||||
selected_models = models.get_models(config)
|
||||
|
||||
# Determine mode string
|
||||
if sources == "all":
|
||||
mode = "all" # reddit + x + web
|
||||
elif sources == "both":
|
||||
mode = "both" # reddit + x
|
||||
elif sources == "reddit":
|
||||
mode = "reddit-only"
|
||||
elif sources == "reddit-web":
|
||||
mode = "reddit-web"
|
||||
elif sources == "x":
|
||||
mode = "x-only"
|
||||
elif sources == "x-web":
|
||||
mode = "x-web"
|
||||
elif sources == "web":
|
||||
mode = "web-only"
|
||||
else:
|
||||
mode = sources
|
||||
|
||||
# Run research
|
||||
reddit_items, x_items, web_needed, raw_openai, raw_xai, raw_reddit_enriched, reddit_error, x_error = run_research(
|
||||
args.topic,
|
||||
sources,
|
||||
config,
|
||||
selected_models,
|
||||
from_date,
|
||||
to_date,
|
||||
depth,
|
||||
args.mock,
|
||||
progress,
|
||||
)
|
||||
|
||||
# Processing phase
|
||||
progress.start_processing()
|
||||
|
||||
# Normalize items
|
||||
normalized_reddit = normalize.normalize_reddit_items(reddit_items, from_date, to_date)
|
||||
normalized_x = normalize.normalize_x_items(x_items, from_date, to_date)
|
||||
|
||||
# Hard date filter: exclude items with verified dates outside the range
|
||||
# This is the safety net - even if prompts let old content through, this filters it
|
||||
filtered_reddit = normalize.filter_by_date_range(normalized_reddit, from_date, to_date)
|
||||
filtered_x = normalize.filter_by_date_range(normalized_x, from_date, to_date)
|
||||
|
||||
# Score items
|
||||
scored_reddit = score.score_reddit_items(filtered_reddit)
|
||||
scored_x = score.score_x_items(filtered_x)
|
||||
|
||||
# Sort items
|
||||
sorted_reddit = score.sort_items(scored_reddit)
|
||||
sorted_x = score.sort_items(scored_x)
|
||||
|
||||
# Dedupe items
|
||||
deduped_reddit = dedupe.dedupe_reddit(sorted_reddit)
|
||||
deduped_x = dedupe.dedupe_x(sorted_x)
|
||||
|
||||
progress.end_processing()
|
||||
|
||||
# Create report
|
||||
report = schema.create_report(
|
||||
args.topic,
|
||||
from_date,
|
||||
to_date,
|
||||
mode,
|
||||
selected_models.get("openai"),
|
||||
selected_models.get("xai"),
|
||||
)
|
||||
report.reddit = deduped_reddit
|
||||
report.x = deduped_x
|
||||
report.reddit_error = reddit_error
|
||||
report.x_error = x_error
|
||||
|
||||
# Generate context snippet
|
||||
report.context_snippet_md = render.render_context_snippet(report)
|
||||
|
||||
# Write outputs
|
||||
render.write_outputs(report, raw_openai, raw_xai, raw_reddit_enriched)
|
||||
|
||||
# Show completion
|
||||
if sources == "web":
|
||||
progress.show_web_only_complete()
|
||||
else:
|
||||
progress.show_complete(len(deduped_reddit), len(deduped_x))
|
||||
|
||||
# Output result
|
||||
output_result(report, args.emit, web_needed, args.topic, from_date, to_date, missing_keys)
|
||||
|
||||
|
||||
def output_result(
|
||||
report: schema.Report,
|
||||
emit_mode: str,
|
||||
web_needed: bool = False,
|
||||
topic: str = "",
|
||||
from_date: str = "",
|
||||
to_date: str = "",
|
||||
missing_keys: str = "none",
|
||||
):
|
||||
"""Output the result based on emit mode."""
|
||||
if emit_mode == "compact":
|
||||
print(render.render_compact(report, missing_keys=missing_keys))
|
||||
elif emit_mode == "json":
|
||||
print(json.dumps(report.to_dict(), indent=2))
|
||||
elif emit_mode == "md":
|
||||
print(render.render_full_report(report))
|
||||
elif emit_mode == "context":
|
||||
print(report.context_snippet_md)
|
||||
elif emit_mode == "path":
|
||||
print(render.get_context_path())
|
||||
|
||||
# Output WebSearch instructions if needed
|
||||
if web_needed:
|
||||
print("\n" + "="*60)
|
||||
print("### WEBSEARCH REQUIRED ###")
|
||||
print("="*60)
|
||||
print(f"Topic: {topic}")
|
||||
print(f"Date range: {from_date} to {to_date}")
|
||||
print("")
|
||||
print("Claude: Use your WebSearch tool to find 8-15 relevant web pages.")
|
||||
print("EXCLUDE: reddit.com, x.com, twitter.com (already covered above)")
|
||||
print("INCLUDE: blogs, docs, news, tutorials from the last 30 days")
|
||||
print("")
|
||||
print("After searching, synthesize WebSearch results WITH the Reddit/X")
|
||||
print("results above. WebSearch items should rank LOWER than comparable")
|
||||
print("Reddit/X items (they lack engagement metrics).")
|
||||
print("="*60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1
skills/last30days/scripts/lib/__init__.py
Normal file
1
skills/last30days/scripts/lib/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# last30days library modules
|
||||
152
skills/last30days/scripts/lib/cache.py
Normal file
152
skills/last30days/scripts/lib/cache.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""Caching utilities for last30days skill."""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
|
||||
CACHE_DIR = Path.home() / ".cache" / "last30days"
|
||||
DEFAULT_TTL_HOURS = 24
|
||||
MODEL_CACHE_TTL_DAYS = 7
|
||||
|
||||
|
||||
def ensure_cache_dir():
|
||||
"""Ensure cache directory exists."""
|
||||
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
def get_cache_key(topic: str, from_date: str, to_date: str, sources: str) -> str:
|
||||
"""Generate a cache key from query parameters."""
|
||||
key_data = f"{topic}|{from_date}|{to_date}|{sources}"
|
||||
return hashlib.sha256(key_data.encode()).hexdigest()[:16]
|
||||
|
||||
|
||||
def get_cache_path(cache_key: str) -> Path:
|
||||
"""Get path to cache file."""
|
||||
return CACHE_DIR / f"{cache_key}.json"
|
||||
|
||||
|
||||
def is_cache_valid(cache_path: Path, ttl_hours: int = DEFAULT_TTL_HOURS) -> bool:
|
||||
"""Check if cache file exists and is within TTL."""
|
||||
if not cache_path.exists():
|
||||
return False
|
||||
|
||||
try:
|
||||
stat = cache_path.stat()
|
||||
mtime = datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc)
|
||||
now = datetime.now(timezone.utc)
|
||||
age_hours = (now - mtime).total_seconds() / 3600
|
||||
return age_hours < ttl_hours
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def load_cache(cache_key: str, ttl_hours: int = DEFAULT_TTL_HOURS) -> Optional[dict]:
|
||||
"""Load data from cache if valid."""
|
||||
cache_path = get_cache_path(cache_key)
|
||||
|
||||
if not is_cache_valid(cache_path, ttl_hours):
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(cache_path, 'r') as f:
|
||||
return json.load(f)
|
||||
except (json.JSONDecodeError, OSError):
|
||||
return None
|
||||
|
||||
|
||||
def get_cache_age_hours(cache_path: Path) -> Optional[float]:
|
||||
"""Get age of cache file in hours."""
|
||||
if not cache_path.exists():
|
||||
return None
|
||||
try:
|
||||
stat = cache_path.stat()
|
||||
mtime = datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc)
|
||||
now = datetime.now(timezone.utc)
|
||||
return (now - mtime).total_seconds() / 3600
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
|
||||
def load_cache_with_age(cache_key: str, ttl_hours: int = DEFAULT_TTL_HOURS) -> tuple:
|
||||
"""Load data from cache with age info.
|
||||
|
||||
Returns:
|
||||
Tuple of (data, age_hours) or (None, None) if invalid
|
||||
"""
|
||||
cache_path = get_cache_path(cache_key)
|
||||
|
||||
if not is_cache_valid(cache_path, ttl_hours):
|
||||
return None, None
|
||||
|
||||
age = get_cache_age_hours(cache_path)
|
||||
|
||||
try:
|
||||
with open(cache_path, 'r') as f:
|
||||
return json.load(f), age
|
||||
except (json.JSONDecodeError, OSError):
|
||||
return None, None
|
||||
|
||||
|
||||
def save_cache(cache_key: str, data: dict):
|
||||
"""Save data to cache."""
|
||||
ensure_cache_dir()
|
||||
cache_path = get_cache_path(cache_key)
|
||||
|
||||
try:
|
||||
with open(cache_path, 'w') as f:
|
||||
json.dump(data, f)
|
||||
except OSError:
|
||||
pass # Silently fail on cache write errors
|
||||
|
||||
|
||||
def clear_cache():
|
||||
"""Clear all cache files."""
|
||||
if CACHE_DIR.exists():
|
||||
for f in CACHE_DIR.glob("*.json"):
|
||||
try:
|
||||
f.unlink()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
# Model selection cache (longer TTL)
|
||||
MODEL_CACHE_FILE = CACHE_DIR / "model_selection.json"
|
||||
|
||||
|
||||
def load_model_cache() -> dict:
|
||||
"""Load model selection cache."""
|
||||
if not is_cache_valid(MODEL_CACHE_FILE, MODEL_CACHE_TTL_DAYS * 24):
|
||||
return {}
|
||||
|
||||
try:
|
||||
with open(MODEL_CACHE_FILE, 'r') as f:
|
||||
return json.load(f)
|
||||
except (json.JSONDecodeError, OSError):
|
||||
return {}
|
||||
|
||||
|
||||
def save_model_cache(data: dict):
|
||||
"""Save model selection cache."""
|
||||
ensure_cache_dir()
|
||||
try:
|
||||
with open(MODEL_CACHE_FILE, 'w') as f:
|
||||
json.dump(data, f)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def get_cached_model(provider: str) -> Optional[str]:
|
||||
"""Get cached model selection for a provider."""
|
||||
cache = load_model_cache()
|
||||
return cache.get(provider)
|
||||
|
||||
|
||||
def set_cached_model(provider: str, model: str):
|
||||
"""Cache model selection for a provider."""
|
||||
cache = load_model_cache()
|
||||
cache[provider] = model
|
||||
cache['updated_at'] = datetime.now(timezone.utc).isoformat()
|
||||
save_model_cache(cache)
|
||||
124
skills/last30days/scripts/lib/dates.py
Normal file
124
skills/last30days/scripts/lib/dates.py
Normal file
@@ -0,0 +1,124 @@
|
||||
"""Date utilities for last30days skill."""
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Optional, Tuple
|
||||
|
||||
|
||||
def get_date_range(days: int = 30) -> Tuple[str, str]:
|
||||
"""Get the date range for the last N days.
|
||||
|
||||
Returns:
|
||||
Tuple of (from_date, to_date) as YYYY-MM-DD strings
|
||||
"""
|
||||
today = datetime.now(timezone.utc).date()
|
||||
from_date = today - timedelta(days=days)
|
||||
return from_date.isoformat(), today.isoformat()
|
||||
|
||||
|
||||
def parse_date(date_str: Optional[str]) -> Optional[datetime]:
|
||||
"""Parse a date string in various formats.
|
||||
|
||||
Supports: YYYY-MM-DD, ISO 8601, Unix timestamp
|
||||
"""
|
||||
if not date_str:
|
||||
return None
|
||||
|
||||
# Try Unix timestamp (from Reddit)
|
||||
try:
|
||||
ts = float(date_str)
|
||||
return datetime.fromtimestamp(ts, tz=timezone.utc)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
# Try ISO formats
|
||||
formats = [
|
||||
"%Y-%m-%d",
|
||||
"%Y-%m-%dT%H:%M:%S",
|
||||
"%Y-%m-%dT%H:%M:%SZ",
|
||||
"%Y-%m-%dT%H:%M:%S%z",
|
||||
"%Y-%m-%dT%H:%M:%S.%f%z",
|
||||
]
|
||||
|
||||
for fmt in formats:
|
||||
try:
|
||||
return datetime.strptime(date_str, fmt).replace(tzinfo=timezone.utc)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def timestamp_to_date(ts: Optional[float]) -> Optional[str]:
|
||||
"""Convert Unix timestamp to YYYY-MM-DD string."""
|
||||
if ts is None:
|
||||
return None
|
||||
try:
|
||||
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
|
||||
return dt.date().isoformat()
|
||||
except (ValueError, TypeError, OSError):
|
||||
return None
|
||||
|
||||
|
||||
def get_date_confidence(date_str: Optional[str], from_date: str, to_date: str) -> str:
|
||||
"""Determine confidence level for a date.
|
||||
|
||||
Args:
|
||||
date_str: The date to check (YYYY-MM-DD or None)
|
||||
from_date: Start of valid range (YYYY-MM-DD)
|
||||
to_date: End of valid range (YYYY-MM-DD)
|
||||
|
||||
Returns:
|
||||
'high', 'med', or 'low'
|
||||
"""
|
||||
if not date_str:
|
||||
return 'low'
|
||||
|
||||
try:
|
||||
dt = datetime.strptime(date_str, "%Y-%m-%d").date()
|
||||
start = datetime.strptime(from_date, "%Y-%m-%d").date()
|
||||
end = datetime.strptime(to_date, "%Y-%m-%d").date()
|
||||
|
||||
if start <= dt <= end:
|
||||
return 'high'
|
||||
elif dt < start:
|
||||
# Older than range
|
||||
return 'low'
|
||||
else:
|
||||
# Future date (suspicious)
|
||||
return 'low'
|
||||
except ValueError:
|
||||
return 'low'
|
||||
|
||||
|
||||
def days_ago(date_str: Optional[str]) -> Optional[int]:
|
||||
"""Calculate how many days ago a date is.
|
||||
|
||||
Returns None if date is invalid or missing.
|
||||
"""
|
||||
if not date_str:
|
||||
return None
|
||||
|
||||
try:
|
||||
dt = datetime.strptime(date_str, "%Y-%m-%d").date()
|
||||
today = datetime.now(timezone.utc).date()
|
||||
delta = today - dt
|
||||
return delta.days
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def recency_score(date_str: Optional[str], max_days: int = 30) -> int:
|
||||
"""Calculate recency score (0-100).
|
||||
|
||||
0 days ago = 100, max_days ago = 0, clamped.
|
||||
"""
|
||||
age = days_ago(date_str)
|
||||
if age is None:
|
||||
return 0 # Unknown date gets worst score
|
||||
|
||||
if age < 0:
|
||||
return 100 # Future date (treat as today)
|
||||
if age >= max_days:
|
||||
return 0
|
||||
|
||||
return int(100 * (1 - age / max_days))
|
||||
120
skills/last30days/scripts/lib/dedupe.py
Normal file
120
skills/last30days/scripts/lib/dedupe.py
Normal file
@@ -0,0 +1,120 @@
|
||||
"""Near-duplicate detection for last30days skill."""
|
||||
|
||||
import re
|
||||
from typing import List, Set, Tuple, Union
|
||||
|
||||
from . import schema
|
||||
|
||||
|
||||
def normalize_text(text: str) -> str:
|
||||
"""Normalize text for comparison.
|
||||
|
||||
- Lowercase
|
||||
- Remove punctuation
|
||||
- Collapse whitespace
|
||||
"""
|
||||
text = text.lower()
|
||||
text = re.sub(r'[^\w\s]', ' ', text)
|
||||
text = re.sub(r'\s+', ' ', text)
|
||||
return text.strip()
|
||||
|
||||
|
||||
def get_ngrams(text: str, n: int = 3) -> Set[str]:
|
||||
"""Get character n-grams from text."""
|
||||
text = normalize_text(text)
|
||||
if len(text) < n:
|
||||
return {text}
|
||||
return {text[i:i+n] for i in range(len(text) - n + 1)}
|
||||
|
||||
|
||||
def jaccard_similarity(set1: Set[str], set2: Set[str]) -> float:
|
||||
"""Compute Jaccard similarity between two sets."""
|
||||
if not set1 or not set2:
|
||||
return 0.0
|
||||
intersection = len(set1 & set2)
|
||||
union = len(set1 | set2)
|
||||
return intersection / union if union > 0 else 0.0
|
||||
|
||||
|
||||
def get_item_text(item: Union[schema.RedditItem, schema.XItem]) -> str:
|
||||
"""Get comparable text from an item."""
|
||||
if isinstance(item, schema.RedditItem):
|
||||
return item.title
|
||||
else:
|
||||
return item.text
|
||||
|
||||
|
||||
def find_duplicates(
|
||||
items: List[Union[schema.RedditItem, schema.XItem]],
|
||||
threshold: float = 0.7,
|
||||
) -> List[Tuple[int, int]]:
|
||||
"""Find near-duplicate pairs in items.
|
||||
|
||||
Args:
|
||||
items: List of items to check
|
||||
threshold: Similarity threshold (0-1)
|
||||
|
||||
Returns:
|
||||
List of (i, j) index pairs where i < j and items are similar
|
||||
"""
|
||||
duplicates = []
|
||||
|
||||
# Pre-compute n-grams
|
||||
ngrams = [get_ngrams(get_item_text(item)) for item in items]
|
||||
|
||||
for i in range(len(items)):
|
||||
for j in range(i + 1, len(items)):
|
||||
similarity = jaccard_similarity(ngrams[i], ngrams[j])
|
||||
if similarity >= threshold:
|
||||
duplicates.append((i, j))
|
||||
|
||||
return duplicates
|
||||
|
||||
|
||||
def dedupe_items(
|
||||
items: List[Union[schema.RedditItem, schema.XItem]],
|
||||
threshold: float = 0.7,
|
||||
) -> List[Union[schema.RedditItem, schema.XItem]]:
|
||||
"""Remove near-duplicates, keeping highest-scored item.
|
||||
|
||||
Args:
|
||||
items: List of items (should be pre-sorted by score descending)
|
||||
threshold: Similarity threshold
|
||||
|
||||
Returns:
|
||||
Deduplicated items
|
||||
"""
|
||||
if len(items) <= 1:
|
||||
return items
|
||||
|
||||
# Find duplicate pairs
|
||||
dup_pairs = find_duplicates(items, threshold)
|
||||
|
||||
# Mark indices to remove (always remove the lower-scored one)
|
||||
# Since items are pre-sorted by score, the second index is always lower
|
||||
to_remove = set()
|
||||
for i, j in dup_pairs:
|
||||
# Keep the higher-scored one (lower index in sorted list)
|
||||
if items[i].score >= items[j].score:
|
||||
to_remove.add(j)
|
||||
else:
|
||||
to_remove.add(i)
|
||||
|
||||
# Return items not marked for removal
|
||||
return [item for idx, item in enumerate(items) if idx not in to_remove]
|
||||
|
||||
|
||||
def dedupe_reddit(
|
||||
items: List[schema.RedditItem],
|
||||
threshold: float = 0.7,
|
||||
) -> List[schema.RedditItem]:
|
||||
"""Dedupe Reddit items."""
|
||||
return dedupe_items(items, threshold)
|
||||
|
||||
|
||||
def dedupe_x(
|
||||
items: List[schema.XItem],
|
||||
threshold: float = 0.7,
|
||||
) -> List[schema.XItem]:
|
||||
"""Dedupe X items."""
|
||||
return dedupe_items(items, threshold)
|
||||
149
skills/last30days/scripts/lib/env.py
Normal file
149
skills/last30days/scripts/lib/env.py
Normal file
@@ -0,0 +1,149 @@
|
||||
"""Environment and API key management for last30days skill."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
CONFIG_DIR = Path.home() / ".config" / "last30days"
|
||||
CONFIG_FILE = CONFIG_DIR / ".env"
|
||||
|
||||
|
||||
def load_env_file(path: Path) -> Dict[str, str]:
|
||||
"""Load environment variables from a file."""
|
||||
env = {}
|
||||
if not path.exists():
|
||||
return env
|
||||
|
||||
with open(path, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
if '=' in line:
|
||||
key, _, value = line.partition('=')
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
# Remove quotes if present
|
||||
if value and value[0] in ('"', "'") and value[-1] == value[0]:
|
||||
value = value[1:-1]
|
||||
if key and value:
|
||||
env[key] = value
|
||||
return env
|
||||
|
||||
|
||||
def get_config() -> Dict[str, Any]:
|
||||
"""Load configuration from ~/.config/last30days/.env and environment."""
|
||||
# Load from config file first
|
||||
file_env = load_env_file(CONFIG_FILE)
|
||||
|
||||
# Environment variables override file
|
||||
config = {
|
||||
'OPENAI_API_KEY': os.environ.get('OPENAI_API_KEY') or file_env.get('OPENAI_API_KEY'),
|
||||
'XAI_API_KEY': os.environ.get('XAI_API_KEY') or file_env.get('XAI_API_KEY'),
|
||||
'OPENAI_MODEL_POLICY': os.environ.get('OPENAI_MODEL_POLICY') or file_env.get('OPENAI_MODEL_POLICY', 'auto'),
|
||||
'OPENAI_MODEL_PIN': os.environ.get('OPENAI_MODEL_PIN') or file_env.get('OPENAI_MODEL_PIN'),
|
||||
'XAI_MODEL_POLICY': os.environ.get('XAI_MODEL_POLICY') or file_env.get('XAI_MODEL_POLICY', 'latest'),
|
||||
'XAI_MODEL_PIN': os.environ.get('XAI_MODEL_PIN') or file_env.get('XAI_MODEL_PIN'),
|
||||
}
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def config_exists() -> bool:
|
||||
"""Check if configuration file exists."""
|
||||
return CONFIG_FILE.exists()
|
||||
|
||||
|
||||
def get_available_sources(config: Dict[str, Any]) -> str:
|
||||
"""Determine which sources are available based on API keys.
|
||||
|
||||
Returns: 'both', 'reddit', 'x', or 'web' (fallback when no keys)
|
||||
"""
|
||||
has_openai = bool(config.get('OPENAI_API_KEY'))
|
||||
has_xai = bool(config.get('XAI_API_KEY'))
|
||||
|
||||
if has_openai and has_xai:
|
||||
return 'both'
|
||||
elif has_openai:
|
||||
return 'reddit'
|
||||
elif has_xai:
|
||||
return 'x'
|
||||
else:
|
||||
return 'web' # Fallback: WebSearch only (no API keys needed)
|
||||
|
||||
|
||||
def get_missing_keys(config: Dict[str, Any]) -> str:
|
||||
"""Determine which API keys are missing.
|
||||
|
||||
Returns: 'both', 'reddit', 'x', or 'none'
|
||||
"""
|
||||
has_openai = bool(config.get('OPENAI_API_KEY'))
|
||||
has_xai = bool(config.get('XAI_API_KEY'))
|
||||
|
||||
if has_openai and has_xai:
|
||||
return 'none'
|
||||
elif has_openai:
|
||||
return 'x' # Missing xAI key
|
||||
elif has_xai:
|
||||
return 'reddit' # Missing OpenAI key
|
||||
else:
|
||||
return 'both' # Missing both keys
|
||||
|
||||
|
||||
def validate_sources(requested: str, available: str, include_web: bool = False) -> tuple[str, Optional[str]]:
|
||||
"""Validate requested sources against available keys.
|
||||
|
||||
Args:
|
||||
requested: 'auto', 'reddit', 'x', 'both', or 'web'
|
||||
available: Result from get_available_sources()
|
||||
include_web: If True, add WebSearch to available sources
|
||||
|
||||
Returns:
|
||||
Tuple of (effective_sources, error_message)
|
||||
"""
|
||||
# WebSearch-only mode (no API keys)
|
||||
if available == 'web':
|
||||
if requested == 'auto':
|
||||
return 'web', None
|
||||
elif requested == 'web':
|
||||
return 'web', None
|
||||
else:
|
||||
return 'web', f"No API keys configured. Using WebSearch fallback. Add keys to ~/.config/last30days/.env for Reddit/X."
|
||||
|
||||
if requested == 'auto':
|
||||
# Add web to sources if include_web is set
|
||||
if include_web:
|
||||
if available == 'both':
|
||||
return 'all', None # reddit + x + web
|
||||
elif available == 'reddit':
|
||||
return 'reddit-web', None
|
||||
elif available == 'x':
|
||||
return 'x-web', None
|
||||
return available, None
|
||||
|
||||
if requested == 'web':
|
||||
return 'web', None
|
||||
|
||||
if requested == 'both':
|
||||
if available not in ('both',):
|
||||
missing = 'xAI' if available == 'reddit' else 'OpenAI'
|
||||
return 'none', f"Requested both sources but {missing} key is missing. Use --sources=auto to use available keys."
|
||||
if include_web:
|
||||
return 'all', None
|
||||
return 'both', None
|
||||
|
||||
if requested == 'reddit':
|
||||
if available == 'x':
|
||||
return 'none', "Requested Reddit but only xAI key is available."
|
||||
if include_web:
|
||||
return 'reddit-web', None
|
||||
return 'reddit', None
|
||||
|
||||
if requested == 'x':
|
||||
if available == 'reddit':
|
||||
return 'none', "Requested X but only OpenAI key is available."
|
||||
if include_web:
|
||||
return 'x-web', None
|
||||
return 'x', None
|
||||
|
||||
return requested, None
|
||||
152
skills/last30days/scripts/lib/http.py
Normal file
152
skills/last30days/scripts/lib/http.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""HTTP utilities for last30days skill (stdlib only)."""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from typing import Any, Dict, Optional
|
||||
from urllib.parse import urlencode
|
||||
|
||||
DEFAULT_TIMEOUT = 30
|
||||
DEBUG = os.environ.get("LAST30DAYS_DEBUG", "").lower() in ("1", "true", "yes")
|
||||
|
||||
|
||||
def log(msg: str):
|
||||
"""Log debug message to stderr."""
|
||||
if DEBUG:
|
||||
sys.stderr.write(f"[DEBUG] {msg}\n")
|
||||
sys.stderr.flush()
|
||||
MAX_RETRIES = 3
|
||||
RETRY_DELAY = 1.0
|
||||
USER_AGENT = "last30days-skill/1.0 (Claude Code Skill)"
|
||||
|
||||
|
||||
class HTTPError(Exception):
|
||||
"""HTTP request error with status code."""
|
||||
def __init__(self, message: str, status_code: Optional[int] = None, body: Optional[str] = None):
|
||||
super().__init__(message)
|
||||
self.status_code = status_code
|
||||
self.body = body
|
||||
|
||||
|
||||
def request(
|
||||
method: str,
|
||||
url: str,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
json_data: Optional[Dict[str, Any]] = None,
|
||||
timeout: int = DEFAULT_TIMEOUT,
|
||||
retries: int = MAX_RETRIES,
|
||||
) -> Dict[str, Any]:
|
||||
"""Make an HTTP request and return JSON response.
|
||||
|
||||
Args:
|
||||
method: HTTP method (GET, POST, etc.)
|
||||
url: Request URL
|
||||
headers: Optional headers dict
|
||||
json_data: Optional JSON body (for POST)
|
||||
timeout: Request timeout in seconds
|
||||
retries: Number of retries on failure
|
||||
|
||||
Returns:
|
||||
Parsed JSON response
|
||||
|
||||
Raises:
|
||||
HTTPError: On request failure
|
||||
"""
|
||||
headers = headers or {}
|
||||
headers.setdefault("User-Agent", USER_AGENT)
|
||||
|
||||
data = None
|
||||
if json_data is not None:
|
||||
data = json.dumps(json_data).encode('utf-8')
|
||||
headers.setdefault("Content-Type", "application/json")
|
||||
|
||||
req = urllib.request.Request(url, data=data, headers=headers, method=method)
|
||||
|
||||
log(f"{method} {url}")
|
||||
if json_data:
|
||||
log(f"Payload keys: {list(json_data.keys())}")
|
||||
|
||||
last_error = None
|
||||
for attempt in range(retries):
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=timeout) as response:
|
||||
body = response.read().decode('utf-8')
|
||||
log(f"Response: {response.status} ({len(body)} bytes)")
|
||||
return json.loads(body) if body else {}
|
||||
except urllib.error.HTTPError as e:
|
||||
body = None
|
||||
try:
|
||||
body = e.read().decode('utf-8')
|
||||
except:
|
||||
pass
|
||||
log(f"HTTP Error {e.code}: {e.reason}")
|
||||
if body:
|
||||
log(f"Error body: {body[:500]}")
|
||||
last_error = HTTPError(f"HTTP {e.code}: {e.reason}", e.code, body)
|
||||
|
||||
# Don't retry client errors (4xx) except rate limits
|
||||
if 400 <= e.code < 500 and e.code != 429:
|
||||
raise last_error
|
||||
|
||||
if attempt < retries - 1:
|
||||
time.sleep(RETRY_DELAY * (attempt + 1))
|
||||
except urllib.error.URLError as e:
|
||||
log(f"URL Error: {e.reason}")
|
||||
last_error = HTTPError(f"URL Error: {e.reason}")
|
||||
if attempt < retries - 1:
|
||||
time.sleep(RETRY_DELAY * (attempt + 1))
|
||||
except json.JSONDecodeError as e:
|
||||
log(f"JSON decode error: {e}")
|
||||
last_error = HTTPError(f"Invalid JSON response: {e}")
|
||||
raise last_error
|
||||
except (OSError, TimeoutError, ConnectionResetError) as e:
|
||||
# Handle socket-level errors (connection reset, timeout, etc.)
|
||||
log(f"Connection error: {type(e).__name__}: {e}")
|
||||
last_error = HTTPError(f"Connection error: {type(e).__name__}: {e}")
|
||||
if attempt < retries - 1:
|
||||
time.sleep(RETRY_DELAY * (attempt + 1))
|
||||
|
||||
if last_error:
|
||||
raise last_error
|
||||
raise HTTPError("Request failed with no error details")
|
||||
|
||||
|
||||
def get(url: str, headers: Optional[Dict[str, str]] = None, **kwargs) -> Dict[str, Any]:
|
||||
"""Make a GET request."""
|
||||
return request("GET", url, headers=headers, **kwargs)
|
||||
|
||||
|
||||
def post(url: str, json_data: Dict[str, Any], headers: Optional[Dict[str, str]] = None, **kwargs) -> Dict[str, Any]:
|
||||
"""Make a POST request with JSON body."""
|
||||
return request("POST", url, headers=headers, json_data=json_data, **kwargs)
|
||||
|
||||
|
||||
def get_reddit_json(path: str) -> Dict[str, Any]:
|
||||
"""Fetch Reddit thread JSON.
|
||||
|
||||
Args:
|
||||
path: Reddit path (e.g., /r/subreddit/comments/id/title)
|
||||
|
||||
Returns:
|
||||
Parsed JSON response
|
||||
"""
|
||||
# Ensure path starts with /
|
||||
if not path.startswith('/'):
|
||||
path = '/' + path
|
||||
|
||||
# Remove trailing slash and add .json
|
||||
path = path.rstrip('/')
|
||||
if not path.endswith('.json'):
|
||||
path = path + '.json'
|
||||
|
||||
url = f"https://www.reddit.com{path}?raw_json=1"
|
||||
|
||||
headers = {
|
||||
"User-Agent": USER_AGENT,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
return get(url, headers=headers)
|
||||
175
skills/last30days/scripts/lib/models.py
Normal file
175
skills/last30days/scripts/lib/models.py
Normal file
@@ -0,0 +1,175 @@
|
||||
"""Model auto-selection for last30days skill."""
|
||||
|
||||
import re
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
from . import cache, http
|
||||
|
||||
# OpenAI API
|
||||
OPENAI_MODELS_URL = "https://api.openai.com/v1/models"
|
||||
OPENAI_FALLBACK_MODELS = ["gpt-5.2", "gpt-5.1", "gpt-5", "gpt-4o"]
|
||||
|
||||
# xAI API - Agent Tools API requires grok-4 family
|
||||
XAI_MODELS_URL = "https://api.x.ai/v1/models"
|
||||
XAI_ALIASES = {
|
||||
"latest": "grok-4-1-fast", # Required for x_search tool
|
||||
"stable": "grok-4-1-fast",
|
||||
}
|
||||
|
||||
|
||||
def parse_version(model_id: str) -> Optional[Tuple[int, ...]]:
|
||||
"""Parse semantic version from model ID.
|
||||
|
||||
Examples:
|
||||
gpt-5 -> (5,)
|
||||
gpt-5.2 -> (5, 2)
|
||||
gpt-5.2.1 -> (5, 2, 1)
|
||||
"""
|
||||
match = re.search(r'(\d+(?:\.\d+)*)', model_id)
|
||||
if match:
|
||||
return tuple(int(x) for x in match.group(1).split('.'))
|
||||
return None
|
||||
|
||||
|
||||
def is_mainline_openai_model(model_id: str) -> bool:
|
||||
"""Check if model is a mainline GPT model (not mini/nano/chat/codex/pro)."""
|
||||
model_lower = model_id.lower()
|
||||
|
||||
# Must be gpt-5 series
|
||||
if not re.match(r'^gpt-5(\.\d+)*$', model_lower):
|
||||
return False
|
||||
|
||||
# Exclude variants
|
||||
excludes = ['mini', 'nano', 'chat', 'codex', 'pro', 'preview', 'turbo']
|
||||
for exc in excludes:
|
||||
if exc in model_lower:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def select_openai_model(
|
||||
api_key: str,
|
||||
policy: str = "auto",
|
||||
pin: Optional[str] = None,
|
||||
mock_models: Optional[List[Dict]] = None,
|
||||
) -> str:
|
||||
"""Select the best OpenAI model based on policy.
|
||||
|
||||
Args:
|
||||
api_key: OpenAI API key
|
||||
policy: 'auto' or 'pinned'
|
||||
pin: Model to use if policy is 'pinned'
|
||||
mock_models: Mock model list for testing
|
||||
|
||||
Returns:
|
||||
Selected model ID
|
||||
"""
|
||||
if policy == "pinned" and pin:
|
||||
return pin
|
||||
|
||||
# Check cache first
|
||||
cached = cache.get_cached_model("openai")
|
||||
if cached:
|
||||
return cached
|
||||
|
||||
# Fetch model list
|
||||
if mock_models is not None:
|
||||
models = mock_models
|
||||
else:
|
||||
try:
|
||||
headers = {"Authorization": f"Bearer {api_key}"}
|
||||
response = http.get(OPENAI_MODELS_URL, headers=headers)
|
||||
models = response.get("data", [])
|
||||
except http.HTTPError:
|
||||
# Fall back to known models
|
||||
return OPENAI_FALLBACK_MODELS[0]
|
||||
|
||||
# Filter to mainline models
|
||||
candidates = [m for m in models if is_mainline_openai_model(m.get("id", ""))]
|
||||
|
||||
if not candidates:
|
||||
# No gpt-5 models found, use fallback
|
||||
return OPENAI_FALLBACK_MODELS[0]
|
||||
|
||||
# Sort by version (descending), then by created timestamp
|
||||
def sort_key(m):
|
||||
version = parse_version(m.get("id", "")) or (0,)
|
||||
created = m.get("created", 0)
|
||||
return (version, created)
|
||||
|
||||
candidates.sort(key=sort_key, reverse=True)
|
||||
selected = candidates[0]["id"]
|
||||
|
||||
# Cache the selection
|
||||
cache.set_cached_model("openai", selected)
|
||||
|
||||
return selected
|
||||
|
||||
|
||||
def select_xai_model(
|
||||
api_key: str,
|
||||
policy: str = "latest",
|
||||
pin: Optional[str] = None,
|
||||
mock_models: Optional[List[Dict]] = None,
|
||||
) -> str:
|
||||
"""Select the best xAI model based on policy.
|
||||
|
||||
Args:
|
||||
api_key: xAI API key
|
||||
policy: 'latest', 'stable', or 'pinned'
|
||||
pin: Model to use if policy is 'pinned'
|
||||
mock_models: Mock model list for testing
|
||||
|
||||
Returns:
|
||||
Selected model ID
|
||||
"""
|
||||
if policy == "pinned" and pin:
|
||||
return pin
|
||||
|
||||
# Use alias system
|
||||
if policy in XAI_ALIASES:
|
||||
alias = XAI_ALIASES[policy]
|
||||
|
||||
# Check cache first
|
||||
cached = cache.get_cached_model("xai")
|
||||
if cached:
|
||||
return cached
|
||||
|
||||
# Cache the alias
|
||||
cache.set_cached_model("xai", alias)
|
||||
return alias
|
||||
|
||||
# Default to latest
|
||||
return XAI_ALIASES["latest"]
|
||||
|
||||
|
||||
def get_models(
|
||||
config: Dict,
|
||||
mock_openai_models: Optional[List[Dict]] = None,
|
||||
mock_xai_models: Optional[List[Dict]] = None,
|
||||
) -> Dict[str, Optional[str]]:
|
||||
"""Get selected models for both providers.
|
||||
|
||||
Returns:
|
||||
Dict with 'openai' and 'xai' keys
|
||||
"""
|
||||
result = {"openai": None, "xai": None}
|
||||
|
||||
if config.get("OPENAI_API_KEY"):
|
||||
result["openai"] = select_openai_model(
|
||||
config["OPENAI_API_KEY"],
|
||||
config.get("OPENAI_MODEL_POLICY", "auto"),
|
||||
config.get("OPENAI_MODEL_PIN"),
|
||||
mock_openai_models,
|
||||
)
|
||||
|
||||
if config.get("XAI_API_KEY"):
|
||||
result["xai"] = select_xai_model(
|
||||
config["XAI_API_KEY"],
|
||||
config.get("XAI_MODEL_POLICY", "latest"),
|
||||
config.get("XAI_MODEL_PIN"),
|
||||
mock_xai_models,
|
||||
)
|
||||
|
||||
return result
|
||||
160
skills/last30days/scripts/lib/normalize.py
Normal file
160
skills/last30days/scripts/lib/normalize.py
Normal file
@@ -0,0 +1,160 @@
|
||||
"""Normalization of raw API data to canonical schema."""
|
||||
|
||||
from typing import Any, Dict, List, TypeVar, Union
|
||||
|
||||
from . import dates, schema
|
||||
|
||||
T = TypeVar("T", schema.RedditItem, schema.XItem, schema.WebSearchItem)
|
||||
|
||||
|
||||
def filter_by_date_range(
|
||||
items: List[T],
|
||||
from_date: str,
|
||||
to_date: str,
|
||||
require_date: bool = False,
|
||||
) -> List[T]:
|
||||
"""Hard filter: Remove items outside the date range.
|
||||
|
||||
This is the safety net - even if the prompt lets old content through,
|
||||
this filter will exclude it.
|
||||
|
||||
Args:
|
||||
items: List of items to filter
|
||||
from_date: Start date (YYYY-MM-DD) - exclude items before this
|
||||
to_date: End date (YYYY-MM-DD) - exclude items after this
|
||||
require_date: If True, also remove items with no date
|
||||
|
||||
Returns:
|
||||
Filtered list with only items in range (or unknown dates if not required)
|
||||
"""
|
||||
result = []
|
||||
for item in items:
|
||||
if item.date is None:
|
||||
if not require_date:
|
||||
result.append(item) # Keep unknown dates (with scoring penalty)
|
||||
continue
|
||||
|
||||
# Hard filter: if date is before from_date, exclude
|
||||
if item.date < from_date:
|
||||
continue # DROP - too old
|
||||
|
||||
# Hard filter: if date is after to_date, exclude (likely parsing error)
|
||||
if item.date > to_date:
|
||||
continue # DROP - future date
|
||||
|
||||
result.append(item)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def normalize_reddit_items(
|
||||
items: List[Dict[str, Any]],
|
||||
from_date: str,
|
||||
to_date: str,
|
||||
) -> List[schema.RedditItem]:
|
||||
"""Normalize raw Reddit items to schema.
|
||||
|
||||
Args:
|
||||
items: Raw Reddit items from API
|
||||
from_date: Start of date range
|
||||
to_date: End of date range
|
||||
|
||||
Returns:
|
||||
List of RedditItem objects
|
||||
"""
|
||||
normalized = []
|
||||
|
||||
for item in items:
|
||||
# Parse engagement
|
||||
engagement = None
|
||||
eng_raw = item.get("engagement")
|
||||
if isinstance(eng_raw, dict):
|
||||
engagement = schema.Engagement(
|
||||
score=eng_raw.get("score"),
|
||||
num_comments=eng_raw.get("num_comments"),
|
||||
upvote_ratio=eng_raw.get("upvote_ratio"),
|
||||
)
|
||||
|
||||
# Parse comments
|
||||
top_comments = []
|
||||
for c in item.get("top_comments", []):
|
||||
top_comments.append(schema.Comment(
|
||||
score=c.get("score", 0),
|
||||
date=c.get("date"),
|
||||
author=c.get("author", ""),
|
||||
excerpt=c.get("excerpt", ""),
|
||||
url=c.get("url", ""),
|
||||
))
|
||||
|
||||
# Determine date confidence
|
||||
date_str = item.get("date")
|
||||
date_confidence = dates.get_date_confidence(date_str, from_date, to_date)
|
||||
|
||||
normalized.append(schema.RedditItem(
|
||||
id=item.get("id", ""),
|
||||
title=item.get("title", ""),
|
||||
url=item.get("url", ""),
|
||||
subreddit=item.get("subreddit", ""),
|
||||
date=date_str,
|
||||
date_confidence=date_confidence,
|
||||
engagement=engagement,
|
||||
top_comments=top_comments,
|
||||
comment_insights=item.get("comment_insights", []),
|
||||
relevance=item.get("relevance", 0.5),
|
||||
why_relevant=item.get("why_relevant", ""),
|
||||
))
|
||||
|
||||
return normalized
|
||||
|
||||
|
||||
def normalize_x_items(
|
||||
items: List[Dict[str, Any]],
|
||||
from_date: str,
|
||||
to_date: str,
|
||||
) -> List[schema.XItem]:
|
||||
"""Normalize raw X items to schema.
|
||||
|
||||
Args:
|
||||
items: Raw X items from API
|
||||
from_date: Start of date range
|
||||
to_date: End of date range
|
||||
|
||||
Returns:
|
||||
List of XItem objects
|
||||
"""
|
||||
normalized = []
|
||||
|
||||
for item in items:
|
||||
# Parse engagement
|
||||
engagement = None
|
||||
eng_raw = item.get("engagement")
|
||||
if isinstance(eng_raw, dict):
|
||||
engagement = schema.Engagement(
|
||||
likes=eng_raw.get("likes"),
|
||||
reposts=eng_raw.get("reposts"),
|
||||
replies=eng_raw.get("replies"),
|
||||
quotes=eng_raw.get("quotes"),
|
||||
)
|
||||
|
||||
# Determine date confidence
|
||||
date_str = item.get("date")
|
||||
date_confidence = dates.get_date_confidence(date_str, from_date, to_date)
|
||||
|
||||
normalized.append(schema.XItem(
|
||||
id=item.get("id", ""),
|
||||
text=item.get("text", ""),
|
||||
url=item.get("url", ""),
|
||||
author_handle=item.get("author_handle", ""),
|
||||
date=date_str,
|
||||
date_confidence=date_confidence,
|
||||
engagement=engagement,
|
||||
relevance=item.get("relevance", 0.5),
|
||||
why_relevant=item.get("why_relevant", ""),
|
||||
))
|
||||
|
||||
return normalized
|
||||
|
||||
|
||||
def items_to_dicts(items: List) -> List[Dict[str, Any]]:
|
||||
"""Convert schema items to dicts for JSON serialization."""
|
||||
return [item.to_dict() for item in items]
|
||||
230
skills/last30days/scripts/lib/openai_reddit.py
Normal file
230
skills/last30days/scripts/lib/openai_reddit.py
Normal file
@@ -0,0 +1,230 @@
|
||||
"""OpenAI Responses API client for Reddit discovery."""
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from . import http
|
||||
|
||||
|
||||
def _log_error(msg: str):
|
||||
"""Log error to stderr."""
|
||||
sys.stderr.write(f"[REDDIT ERROR] {msg}\n")
|
||||
sys.stderr.flush()
|
||||
|
||||
OPENAI_RESPONSES_URL = "https://api.openai.com/v1/responses"
|
||||
|
||||
# Depth configurations: (min, max) threads to request
|
||||
# Request MORE than needed since many get filtered by date
|
||||
DEPTH_CONFIG = {
|
||||
"quick": (15, 25),
|
||||
"default": (30, 50),
|
||||
"deep": (70, 100),
|
||||
}
|
||||
|
||||
REDDIT_SEARCH_PROMPT = """Find Reddit discussion threads about: {topic}
|
||||
|
||||
STEP 1: EXTRACT THE CORE SUBJECT
|
||||
Get the MAIN NOUN/PRODUCT/TOPIC:
|
||||
- "best nano banana prompting practices" → "nano banana"
|
||||
- "killer features of clawdbot" → "clawdbot"
|
||||
- "top Claude Code skills" → "Claude Code"
|
||||
DO NOT include "best", "top", "tips", "practices", "features" in your search.
|
||||
|
||||
STEP 2: SEARCH BROADLY
|
||||
Search for the core subject:
|
||||
1. "[core subject] site:reddit.com"
|
||||
2. "reddit [core subject]"
|
||||
3. "[core subject] reddit"
|
||||
|
||||
Return as many relevant threads as you find. We filter by date server-side.
|
||||
|
||||
STEP 3: INCLUDE ALL MATCHES
|
||||
- Include ALL threads about the core subject
|
||||
- Set date to "YYYY-MM-DD" if you can determine it, otherwise null
|
||||
- We verify dates and filter old content server-side
|
||||
- DO NOT pre-filter aggressively - include anything relevant
|
||||
|
||||
REQUIRED: URLs must contain "/r/" AND "/comments/"
|
||||
REJECT: developers.reddit.com, business.reddit.com
|
||||
|
||||
Find {min_items}-{max_items} threads. Return MORE rather than fewer.
|
||||
|
||||
Return JSON:
|
||||
{{
|
||||
"items": [
|
||||
{{
|
||||
"title": "Thread title",
|
||||
"url": "https://www.reddit.com/r/sub/comments/xyz/title/",
|
||||
"subreddit": "subreddit_name",
|
||||
"date": "YYYY-MM-DD or null",
|
||||
"why_relevant": "Why relevant",
|
||||
"relevance": 0.85
|
||||
}}
|
||||
]
|
||||
}}"""
|
||||
|
||||
|
||||
def _extract_core_subject(topic: str) -> str:
|
||||
"""Extract core subject from verbose query for retry."""
|
||||
noise = ['best', 'top', 'how to', 'tips for', 'practices', 'features',
|
||||
'killer', 'guide', 'tutorial', 'recommendations', 'advice',
|
||||
'prompting', 'using', 'for', 'with', 'the', 'of', 'in', 'on']
|
||||
words = topic.lower().split()
|
||||
result = [w for w in words if w not in noise]
|
||||
return ' '.join(result[:3]) or topic # Keep max 3 words
|
||||
|
||||
|
||||
def search_reddit(
|
||||
api_key: str,
|
||||
model: str,
|
||||
topic: str,
|
||||
from_date: str,
|
||||
to_date: str,
|
||||
depth: str = "default",
|
||||
mock_response: Optional[Dict] = None,
|
||||
_retry: bool = False,
|
||||
) -> Dict[str, Any]:
|
||||
"""Search Reddit for relevant threads using OpenAI Responses API.
|
||||
|
||||
Args:
|
||||
api_key: OpenAI API key
|
||||
model: Model to use
|
||||
topic: Search topic
|
||||
from_date: Start date (YYYY-MM-DD) - only include threads after this
|
||||
to_date: End date (YYYY-MM-DD) - only include threads before this
|
||||
depth: Research depth - "quick", "default", or "deep"
|
||||
mock_response: Mock response for testing
|
||||
|
||||
Returns:
|
||||
Raw API response
|
||||
"""
|
||||
if mock_response is not None:
|
||||
return mock_response
|
||||
|
||||
min_items, max_items = DEPTH_CONFIG.get(depth, DEPTH_CONFIG["default"])
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
# Adjust timeout based on depth (generous for OpenAI web_search which can be slow)
|
||||
timeout = 90 if depth == "quick" else 120 if depth == "default" else 180
|
||||
|
||||
# Note: allowed_domains accepts base domain, not subdomains
|
||||
# We rely on prompt to filter out developers.reddit.com, etc.
|
||||
payload = {
|
||||
"model": model,
|
||||
"tools": [
|
||||
{
|
||||
"type": "web_search",
|
||||
"filters": {
|
||||
"allowed_domains": ["reddit.com"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"include": ["web_search_call.action.sources"],
|
||||
"input": REDDIT_SEARCH_PROMPT.format(
|
||||
topic=topic,
|
||||
from_date=from_date,
|
||||
to_date=to_date,
|
||||
min_items=min_items,
|
||||
max_items=max_items,
|
||||
),
|
||||
}
|
||||
|
||||
return http.post(OPENAI_RESPONSES_URL, payload, headers=headers, timeout=timeout)
|
||||
|
||||
|
||||
def parse_reddit_response(response: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""Parse OpenAI response to extract Reddit items.
|
||||
|
||||
Args:
|
||||
response: Raw API response
|
||||
|
||||
Returns:
|
||||
List of item dicts
|
||||
"""
|
||||
items = []
|
||||
|
||||
# Check for API errors first
|
||||
if "error" in response and response["error"]:
|
||||
error = response["error"]
|
||||
err_msg = error.get("message", str(error)) if isinstance(error, dict) else str(error)
|
||||
_log_error(f"OpenAI API error: {err_msg}")
|
||||
if http.DEBUG:
|
||||
_log_error(f"Full error response: {json.dumps(response, indent=2)[:1000]}")
|
||||
return items
|
||||
|
||||
# Try to find the output text
|
||||
output_text = ""
|
||||
if "output" in response:
|
||||
output = response["output"]
|
||||
if isinstance(output, str):
|
||||
output_text = output
|
||||
elif isinstance(output, list):
|
||||
for item in output:
|
||||
if isinstance(item, dict):
|
||||
if item.get("type") == "message":
|
||||
content = item.get("content", [])
|
||||
for c in content:
|
||||
if isinstance(c, dict) and c.get("type") == "output_text":
|
||||
output_text = c.get("text", "")
|
||||
break
|
||||
elif "text" in item:
|
||||
output_text = item["text"]
|
||||
elif isinstance(item, str):
|
||||
output_text = item
|
||||
if output_text:
|
||||
break
|
||||
|
||||
# Also check for choices (older format)
|
||||
if not output_text and "choices" in response:
|
||||
for choice in response["choices"]:
|
||||
if "message" in choice:
|
||||
output_text = choice["message"].get("content", "")
|
||||
break
|
||||
|
||||
if not output_text:
|
||||
print(f"[REDDIT WARNING] No output text found in OpenAI response. Keys present: {list(response.keys())}", flush=True)
|
||||
return items
|
||||
|
||||
# Extract JSON from the response
|
||||
json_match = re.search(r'\{[\s\S]*"items"[\s\S]*\}', output_text)
|
||||
if json_match:
|
||||
try:
|
||||
data = json.loads(json_match.group())
|
||||
items = data.get("items", [])
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
|
||||
# Validate and clean items
|
||||
clean_items = []
|
||||
for i, item in enumerate(items):
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
|
||||
url = item.get("url", "")
|
||||
if not url or "reddit.com" not in url:
|
||||
continue
|
||||
|
||||
clean_item = {
|
||||
"id": f"R{i+1}",
|
||||
"title": str(item.get("title", "")).strip(),
|
||||
"url": url,
|
||||
"subreddit": str(item.get("subreddit", "")).strip().lstrip("r/"),
|
||||
"date": item.get("date"),
|
||||
"why_relevant": str(item.get("why_relevant", "")).strip(),
|
||||
"relevance": min(1.0, max(0.0, float(item.get("relevance", 0.5)))),
|
||||
}
|
||||
|
||||
# Validate date format
|
||||
if clean_item["date"]:
|
||||
if not re.match(r'^\d{4}-\d{2}-\d{2}$', str(clean_item["date"])):
|
||||
clean_item["date"] = None
|
||||
|
||||
clean_items.append(clean_item)
|
||||
|
||||
return clean_items
|
||||
232
skills/last30days/scripts/lib/reddit_enrich.py
Normal file
232
skills/last30days/scripts/lib/reddit_enrich.py
Normal file
@@ -0,0 +1,232 @@
|
||||
"""Reddit thread enrichment with real engagement metrics."""
|
||||
|
||||
import re
|
||||
from typing import Any, Dict, List, Optional
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from . import http, dates
|
||||
|
||||
|
||||
def extract_reddit_path(url: str) -> Optional[str]:
|
||||
"""Extract the path from a Reddit URL.
|
||||
|
||||
Args:
|
||||
url: Reddit URL
|
||||
|
||||
Returns:
|
||||
Path component or None
|
||||
"""
|
||||
try:
|
||||
parsed = urlparse(url)
|
||||
if "reddit.com" not in parsed.netloc:
|
||||
return None
|
||||
return parsed.path
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def fetch_thread_data(url: str, mock_data: Optional[Dict] = None) -> Optional[Dict[str, Any]]:
|
||||
"""Fetch Reddit thread JSON data.
|
||||
|
||||
Args:
|
||||
url: Reddit thread URL
|
||||
mock_data: Mock data for testing
|
||||
|
||||
Returns:
|
||||
Thread data dict or None on failure
|
||||
"""
|
||||
if mock_data is not None:
|
||||
return mock_data
|
||||
|
||||
path = extract_reddit_path(url)
|
||||
if not path:
|
||||
return None
|
||||
|
||||
try:
|
||||
data = http.get_reddit_json(path)
|
||||
return data
|
||||
except http.HTTPError:
|
||||
return None
|
||||
|
||||
|
||||
def parse_thread_data(data: Any) -> Dict[str, Any]:
|
||||
"""Parse Reddit thread JSON into structured data.
|
||||
|
||||
Args:
|
||||
data: Raw Reddit JSON response
|
||||
|
||||
Returns:
|
||||
Dict with submission and comments data
|
||||
"""
|
||||
result = {
|
||||
"submission": None,
|
||||
"comments": [],
|
||||
}
|
||||
|
||||
if not isinstance(data, list) or len(data) < 1:
|
||||
return result
|
||||
|
||||
# First element is submission listing
|
||||
submission_listing = data[0]
|
||||
if isinstance(submission_listing, dict):
|
||||
children = submission_listing.get("data", {}).get("children", [])
|
||||
if children:
|
||||
sub_data = children[0].get("data", {})
|
||||
result["submission"] = {
|
||||
"score": sub_data.get("score"),
|
||||
"num_comments": sub_data.get("num_comments"),
|
||||
"upvote_ratio": sub_data.get("upvote_ratio"),
|
||||
"created_utc": sub_data.get("created_utc"),
|
||||
"permalink": sub_data.get("permalink"),
|
||||
"title": sub_data.get("title"),
|
||||
"selftext": sub_data.get("selftext", "")[:500], # Truncate
|
||||
}
|
||||
|
||||
# Second element is comments listing
|
||||
if len(data) >= 2:
|
||||
comments_listing = data[1]
|
||||
if isinstance(comments_listing, dict):
|
||||
children = comments_listing.get("data", {}).get("children", [])
|
||||
for child in children:
|
||||
if child.get("kind") != "t1": # t1 = comment
|
||||
continue
|
||||
c_data = child.get("data", {})
|
||||
if not c_data.get("body"):
|
||||
continue
|
||||
|
||||
comment = {
|
||||
"score": c_data.get("score", 0),
|
||||
"created_utc": c_data.get("created_utc"),
|
||||
"author": c_data.get("author", "[deleted]"),
|
||||
"body": c_data.get("body", "")[:300], # Truncate
|
||||
"permalink": c_data.get("permalink"),
|
||||
}
|
||||
result["comments"].append(comment)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_top_comments(comments: List[Dict], limit: int = 10) -> List[Dict[str, Any]]:
|
||||
"""Get top comments sorted by score.
|
||||
|
||||
Args:
|
||||
comments: List of comment dicts
|
||||
limit: Maximum number to return
|
||||
|
||||
Returns:
|
||||
Top comments sorted by score
|
||||
"""
|
||||
# Filter out deleted/removed
|
||||
valid = [c for c in comments if c.get("author") not in ("[deleted]", "[removed]")]
|
||||
|
||||
# Sort by score descending
|
||||
sorted_comments = sorted(valid, key=lambda c: c.get("score", 0), reverse=True)
|
||||
|
||||
return sorted_comments[:limit]
|
||||
|
||||
|
||||
def extract_comment_insights(comments: List[Dict], limit: int = 7) -> List[str]:
|
||||
"""Extract key insights from top comments.
|
||||
|
||||
Uses simple heuristics to identify valuable comments:
|
||||
- Has substantive text
|
||||
- Contains actionable information
|
||||
- Not just agreement/disagreement
|
||||
|
||||
Args:
|
||||
comments: Top comments
|
||||
limit: Max insights to extract
|
||||
|
||||
Returns:
|
||||
List of insight strings
|
||||
"""
|
||||
insights = []
|
||||
|
||||
for comment in comments[:limit * 2]: # Look at more comments than we need
|
||||
body = comment.get("body", "").strip()
|
||||
if not body or len(body) < 30:
|
||||
continue
|
||||
|
||||
# Skip low-value patterns
|
||||
skip_patterns = [
|
||||
r'^(this|same|agreed|exactly|yep|nope|yes|no|thanks|thank you)\.?$',
|
||||
r'^lol|lmao|haha',
|
||||
r'^\[deleted\]',
|
||||
r'^\[removed\]',
|
||||
]
|
||||
if any(re.match(p, body.lower()) for p in skip_patterns):
|
||||
continue
|
||||
|
||||
# Truncate to first meaningful sentence or ~150 chars
|
||||
insight = body[:150]
|
||||
if len(body) > 150:
|
||||
# Try to find a sentence boundary
|
||||
for i, char in enumerate(insight):
|
||||
if char in '.!?' and i > 50:
|
||||
insight = insight[:i+1]
|
||||
break
|
||||
else:
|
||||
insight = insight.rstrip() + "..."
|
||||
|
||||
insights.append(insight)
|
||||
if len(insights) >= limit:
|
||||
break
|
||||
|
||||
return insights
|
||||
|
||||
|
||||
def enrich_reddit_item(
|
||||
item: Dict[str, Any],
|
||||
mock_thread_data: Optional[Dict] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""Enrich a Reddit item with real engagement data.
|
||||
|
||||
Args:
|
||||
item: Reddit item dict
|
||||
mock_thread_data: Mock data for testing
|
||||
|
||||
Returns:
|
||||
Enriched item dict
|
||||
"""
|
||||
url = item.get("url", "")
|
||||
|
||||
# Fetch thread data
|
||||
thread_data = fetch_thread_data(url, mock_thread_data)
|
||||
if not thread_data:
|
||||
return item
|
||||
|
||||
parsed = parse_thread_data(thread_data)
|
||||
submission = parsed.get("submission")
|
||||
comments = parsed.get("comments", [])
|
||||
|
||||
# Update engagement metrics
|
||||
if submission:
|
||||
item["engagement"] = {
|
||||
"score": submission.get("score"),
|
||||
"num_comments": submission.get("num_comments"),
|
||||
"upvote_ratio": submission.get("upvote_ratio"),
|
||||
}
|
||||
|
||||
# Update date from actual data
|
||||
created_utc = submission.get("created_utc")
|
||||
if created_utc:
|
||||
item["date"] = dates.timestamp_to_date(created_utc)
|
||||
|
||||
# Get top comments
|
||||
top_comments = get_top_comments(comments)
|
||||
item["top_comments"] = []
|
||||
for c in top_comments:
|
||||
permalink = c.get("permalink", "")
|
||||
comment_url = f"https://reddit.com{permalink}" if permalink else ""
|
||||
item["top_comments"].append({
|
||||
"score": c.get("score", 0),
|
||||
"date": dates.timestamp_to_date(c.get("created_utc")),
|
||||
"author": c.get("author", ""),
|
||||
"excerpt": c.get("body", "")[:200],
|
||||
"url": comment_url,
|
||||
})
|
||||
|
||||
# Extract insights
|
||||
item["comment_insights"] = extract_comment_insights(top_comments)
|
||||
|
||||
return item
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user