Compare commits

..

80 Commits

Author SHA1 Message Date
sck_0
3dded33731 chore: finalize v3.4.0 versioning in README 2026-01-27 09:20:39 +01:00
sck_0
cc0f4a2ec4 chore: sync generated files (fix CI drift in v3.4.0) 2026-01-27 09:18:26 +01:00
sck_0
1b606d851d chore(release): v3.4.0 - Voice AI & Categorization 2026-01-27 09:16:41 +01:00
sck_0
7e2f243bfa chore: fixes CI drift (sync generated files +1 skill) 2026-01-27 09:11:06 +01:00
sck_0
3688425884 chore: sync generated files and apply categorization 2026-01-27 08:59:59 +01:00
sickn33
8801592bd2 Merge pull request #33 from taksrules/feat/voice-ai-engine-development
feat: add voice-ai-engine-development skill for building real-time co…
2026-01-27 08:54:35 +01:00
taksrules
d972c4fa3a feat: add voice-ai-engine-development skill for building real-time conversational AI 2026-01-27 07:24:06 +02:00
sck_0
e9783892c1 chore: fixes ci drift in generated files 2026-01-26 20:06:02 +01:00
sck_0
d8d8e70ebb chore: standardize maintenance rules and sync docs (v3.3.0 audit) 2026-01-26 20:04:54 +01:00
sck_0
deafaa6e77 chore: fix drift in generated files (CI sync) 2026-01-26 19:28:32 +01:00
sck_0
790573472c chore: sync generated files and stats 2026-01-26 19:25:20 +01:00
sck_0
66b777a937 chore: move new contributors to community section 2026-01-26 19:23:09 +01:00
sck_0
63d98348d2 chore: fix skill count in readme intro 2026-01-26 19:22:14 +01:00
sck_0
79f2642f4e chore: fix readme title and contributors 2026-01-26 19:19:29 +01:00
sck_0
48d458ce0b chore: fix ci drift in generated files 2026-01-26 19:12:38 +01:00
sck_0
9df73a8e56 chore: release v3.3.0 2026-01-26 19:09:09 +01:00
sck_0
2d7529b613 chore: formatting fixes 2026-01-26 19:07:27 +01:00
sck_0
283c4e6ae7 chore: sync generated files 2026-01-26 19:06:44 +01:00
sck_0
c7f7f23bd7 feat: integrate last30days and daily-news-report skills 2026-01-26 19:05:37 +01:00
sck_0
d2569f2107 chore(release): prepare for v3.2.0 2026-01-26 18:39:10 +01:00
sck_0
4c272bfcbf chore: sync generated files 2026-01-26 18:35:10 +01:00
sck_0
256bfeee73 Merge branch 'pr-31' into main 2026-01-26 18:34:39 +01:00
sck_0
f57a068782 fix(skills): repair invalid YAML frontmatter in SEO skills 2026-01-26 18:33:39 +01:00
Munir Abbasi
0c93e28ace Update SKILL.md 2026-01-26 13:53:07 +05:00
sck_0
899c8a01da docs: detailed v3.1.0 changelog with specific registry restores 2026-01-26 08:52:29 +01:00
sck_0
4ff7187be6 docs: use CHANGELOG.md for release notes and cleanup 2026-01-26 08:50:13 +01:00
sck_0
d19edbebfb docs: add critical CI drift fixation guide and update maintenance routine 2026-01-26 08:46:15 +01:00
sck_0
2001965e52 fix(ci): sync README.md with generation scripts to resolve drift 2026-01-26 08:44:51 +01:00
sck_0
866d6954f7 chore(release): prepare v3.1.0 artifacts 2026-01-26 08:39:45 +01:00
sck_0
7e5d8d52a1 fix(ci): update README.md to match deterministic index sorting 2026-01-26 08:36:58 +01:00
sck_0
b55e7e39cc fix(ci): make index sorting deterministic (sort by name + id) 2026-01-26 08:35:32 +01:00
sck_0
f728d0d816 fix(ci): install pyyaml dependency for index generation 2026-01-26 08:33:41 +01:00
Munir Abbasi
c8de7f50f8 Update SKILL.md 2026-01-26 12:32:22 +05:00
sck_0
9891cb28ed fix(ci): update generate_index.py to support YAML frontmatter and sync skills_index.json 2026-01-26 08:30:16 +01:00
Munir Abbasi
4d32a3e2af Revise frontend development guidelines description
Updated the description to clarify the guidelines and standards for frontend development in React and TypeScript applications. Enhanced the structure and content for better readability and understanding.
2026-01-26 12:29:00 +05:00
Munir Abbasi
53927c5aec Revise frontend design skill description and guidelines
Updated the description and guidelines for frontend design to emphasize intentional aesthetics and high craft. Enhanced clarity on design thinking, implementation standards, and anti-patterns.
2026-01-26 12:26:39 +05:00
sck_0
699ceabd57 fix(skills): correct YAML frontmatter syntax and remove debris from PR #30 2026-01-26 08:26:16 +01:00
Munir Abbasi
c8e7424ea6 Revise marketing psychology skill description and content
Updated the description to clarify the application of behavioral science and mental models in marketing. Revised the content structure to enhance clarity and usability for users seeking psychological insights in marketing.
2026-01-26 12:22:55 +05:00
Munir Abbasi
14fb3b5159 Update SKILL.md 2026-01-26 12:20:25 +05:00
Munir Abbasi
691b02c817 Add related skills section to SKILL.md
Added related skills for pricing strategy.
2026-01-26 12:17:28 +05:00
Munir Abbasi
acc6dbc84f Update SKILL.md 2026-01-26 12:02:37 +05:00
Munir Abbasi
d8453057df Revise popup-cro skill description and content
Updated the description and content structure for the popup-cro skill to enhance clarity and user engagement strategies.
2026-01-26 11:59:25 +05:00
Munir Abbasi
f45abe634d Refactor SKILL.md for clarity and conciseness
Removed unnecessary lines and improved formatting.
2026-01-26 11:47:08 +05:00
Munir Abbasi
85480f4ce4 Refactor SKILL.md by removing YAML block
Removed YAML code block formatting from SKILL.md.
2026-01-26 11:44:16 +05:00
Munir Abbasi
e5d2a7e1ec Refactor SKILL.md by removing YAML block
Removed YAML code block from SKILL.md and adjusted formatting.
2026-01-26 11:42:31 +05:00
Munir Abbasi
c04d59d91d Refactor SKILL.md for form optimization clarity
Removed YAML code block and adjusted formatting.
2026-01-26 11:41:57 +05:00
Munir Abbasi
7d061238e6 Revise SKILL.md for form optimization guidance
Updated the description for form optimization and revised the structure of the document for clarity and effectiveness. Added sections on core principles, field-by-field optimization, and measurement metrics.
2026-01-26 11:09:05 +05:00
Munir Abbasi
805ef578f4 Revise analytics tracking skill for clarity and focus
Updated the analytics tracking skill description and structure to focus on measurement strategy, signal quality, and validation. Removed outdated sections and streamlined content for clarity.
2026-01-26 10:58:45 +05:00
Munir Abbasi
0792c9a505 Revise page-cro skill description and structure
Updated the description for the page-cro skill to focus on analyzing and optimizing conversion performance. Added YAML metadata for clarity and structured the content for better readability.
2026-01-26 10:53:03 +05:00
Munir Abbasi
86c74656aa Revise schema-markup documentation for clarity
Updated schema-markup documentation to enhance clarity and detail regarding schema implementation, eligibility, and validation processes.
2026-01-26 10:47:40 +05:00
Munir Abbasi
a11280426c Enhance programmatic SEO guidelines in SKILL.md
Add detailed guidelines and principles for programmatic SEO strategies, including feasibility assessments, core principles, and playbooks for creating SEO-driven pages at scale.
2026-01-26 10:41:23 +05:00
Munir Abbasi
99fbad717f Revise SEO fundamentals skill content and structure
Updated the SEO fundamentals skill document to enhance descriptions, clarify principles, and improve formatting.
2026-01-26 10:35:22 +05:00
Munir Abbasi
706a84b873 Revise SEO audit skill description and framework
Updated the SEO audit skill description and framework for clarity and detail. Enhanced the structure and content of the SEO audit guidelines.
2026-01-26 10:31:50 +05:00
sck_0
0f4a1b2fd7 docs: update visual guide and skill anatomy for V3 specs [skip ci] 2026-01-25 20:25:44 +01:00
sck_0
c0348ca1b5 docs: add Changelog update to post-merge maintenance steps [skip ci] 2026-01-25 20:23:32 +01:00
sck_0
441189cd90 docs: create comprehensive V3 Maintenance Guide (TOC rules, Contributors sync, Quality Bar) [skip ci] 2026-01-25 20:19:44 +01:00
sck_0
e242186fe2 docs: restore VERY detailed documentation while keeping V3 updates [skip ci] 2026-01-25 20:17:00 +01:00
sck_0
45e2049663 docs: restore detailed guides mixed with V3 updates (reverting aggressive pruning) [skip ci] 2026-01-25 20:15:44 +01:00
sck_0
c96815ed7c docs: update CONTRIBUTING and FAQ for V3 Quality Bar and Security [skip ci] 2026-01-25 20:14:27 +01:00
sck_0
1e03172075 docs: rewrite Getting Started guide for V3 (bundles, safety badges, updated counts) [skip ci] 2026-01-25 20:12:26 +01:00
sck_0
7280be2d63 docs: add missing contributor Munir Abbasi [skip ci] 2026-01-25 20:10:39 +01:00
sck_0
b3c75a3ab0 docs: remove remaining emojis from headers to fix TOC anchors [skip ci] 2026-01-25 20:09:22 +01:00
sck_0
0b9d17a95f docs: reorder TOC to match document flow (License before Contributors) [skip ci] 2026-01-25 20:08:25 +01:00
sck_0
c51ca4a4bf docs: fix TOC anchors by simplifying headers and add missing sections [skip ci] 2026-01-25 20:06:15 +01:00
sck_0
f155a8ff24 docs: fix broken TOC links (remove emoji anchors) [skip ci] 2026-01-25 20:03:48 +01:00
sck_0
f7b16b436b docs: modernize TOC and Start Here section for V3 [skip ci] 2026-01-25 20:00:54 +01:00
sck_0
79ed5ead64 docs: fix README inconsistencies (duplicate topics, broken links, footer) [skip ci] 2026-01-25 19:59:22 +01:00
sck_0
d75824bfd0 chore: move Code of Conduct to docs/COMMUNITY_GUIDELINES.md to hide from repo header [skip ci] 2026-01-25 19:57:55 +01:00
sck_0
173c634b46 docs: consolidate Release Notes into Changelog and remove temp file [skip ci] 2026-01-25 19:56:09 +01:00
sck_0
41309cfd7d feat: add 6 new bundles (Game Dev, DevOps, Data, Testing, Design, Creative) [skip ci] 2026-01-25 19:50:28 +01:00
sck_0
36107a5cae chore: enable Soft Launch mode (disable strict CI for legacy skills) [skip ci] 2026-01-25 19:37:45 +01:00
sck_0
238cfc6933 feat: implement Phase 5 Documentation (EXAMPLES.md, README details) [skip ci] 2026-01-25 19:33:27 +01:00
sck_0
f28591e648 feat: implement Phase 4 Security & Compliance (SOURCES.md, SECURITY.md) [skip ci] 2026-01-25 19:30:51 +01:00
sck_0
d38e2eeab1 feat: implement Phase 3 Experience & Usability (BUNDLES.md, README collections, Risk column) [skip ci] 2026-01-25 19:24:24 +01:00
sck_0
4fe8a1e6a4 feat: implement Phase 2 Automation & CI (validate_skills, generate_index, ci.yml) [skip ci] 2026-01-25 19:19:51 +01:00
sck_0
1557826c5d feat: implement Phase 1 Foundation & Governance (Quality Bar, Security, CoC) [skip ci] 2026-01-25 19:13:00 +01:00
sck_0
bec54d7abb chore: move MAINTENANCE.md to .github/ 2026-01-25 19:04:57 +01:00
sck_0
23f9ad547c docs: update MAINTENANCE.md with strict SOP/Push protocols 2026-01-25 19:01:09 +01:00
sck_0
28def60eec docs: add Star History chart to README 2026-01-25 18:27:51 +01:00
sck_0
902063fd0a docs: add release management procedure to MAINTENANCE.md 2026-01-25 18:01:02 +01:00
91 changed files with 17450 additions and 7550 deletions

230
.github/MAINTENANCE.md vendored Normal file
View File

@@ -0,0 +1,230 @@
# 🛠️ 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**.
---
## 0. 🤖 Agent Protocol (THE BIBLE)
**AGENTS MUST READ AND FOLLOW THIS SECTION BEFORE MARKING ANY TASK AS COMPLETE.**
There are 3 things that usually fail/get forgotten. **DO NOT FORGET THEM:**
### 1. 📤 ALWAYS PUSH (Non-Negotiable)
Committing is NOT enough. You must PUSH to the remote.
- **BAD**: `git commit -m "feat: new skill"` (User sees nothing)
- **GOOD**: `git commit -m "..." && git push origin main`
### 2. 🔄 SYNC GENERATED FILES (Avoid CI Drift)
If you touch `skills/`, you **MUST** run the validation chain.
- Running `validate_skills.py` is NOT optional.
- Running `generate_index.py` is NOT optional.
- Running `update_readme.py` is NOT optional.
_If CI fails because of drift, you have failed._
### 3. 📝 EVIDENCE OF WORK
- You must create/update `walkthrough.md` or `RELEASE_NOTES.md` to document what changed.
- If you made something new, **link it** in the artifacts.
### 4. 🚫 NO BRANCHES
- **ALWAYS use the `main` branch.**
- NEVER create feature branches (e.g., `feat/new-skill`).
- We commit directly to `main` to keep history linear and simple.
---
## 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 Consistency (CRITICAL)
If you add/remove skills, you **MUST** ensure the total count is identical in ALL locations.
**Do not allow drift** (e.g., 356 in title, 354 in header).
Locations to check:
1. **Title of `README.md`**: "356+ Agentic Skills..."
2. **`## Full Skill Registry (356/356)` header**.
3. **`GETTING_STARTED.md` intro**.
### D. Credits Policy (Who goes where?)
- **Credits & Sources**: Use this for **External Repos**.
- _Rule_: "I extracted skills from this link you sent me." -> Add to `## Credits & Sources`.
- **Repo Contributors**: Use this for **Pull Requests**.
- _Rule_: "This user sent a PR." -> Add to `## Repo Contributors`.
### E. 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
```
### 📋 Release Note Template
All changeslogs/release notes MUST follow this structure to ensure professionalism and quality:
```markdown
# Release vX.Y.Z: [Theme Name]
> **[One-line catchy summary of the release]**
[Brief 2-3 sentence intro about the release's impact]
## 🚀 New Skills
### [Emoji] [Skill Name](skills/skill-name/)
**[Bold high-level benefit]**
[Description of what it does]
- **Key Feature 1**: [Detail]
- **Key Feature 2**: [Detail]
> **Try it:** `(User Prompt) ...`
---
## 📦 Improvements
- **Registry Update**: Now tracking [N] skills.
- **[Component]**: [Change detail]
## 👥 Credits
A huge shoutout to our community contributors:
- **@username** for `skill-name`
- **@username** for `fix-name`
---
_Upgrade now: `git pull origin main` to fetch the latest skills._
```
---
## 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**.

View File

@@ -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
View 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)

View File

@@ -9,6 +9,98 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
---
## [3.4.0] - 2026-01-27 - "Voice Intelligence & Categorization"
### Added
- **New Skill**: `voice-ai-engine-development` - Complete toolkit for building real-time voice agents (OpenAI Realtime, Vapi, Deepgram, ElevenLabs).
- **Categorization**: Major README update introducing a concise "Features & Categories" summary table.
### Changed
- **README**: Replaced text-heavy category lists with a high-level summary table.
- **Registry**: Synced generic skill count (256) across documentation.
### Contributors
- [@sickn33](https://github.com/sickn33) - Voice AI Engine (PR #33)
- [@community](https://github.com/community) - Categorization Initiative (PR #32)
## [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

View File

@@ -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!

509
FAQ.md
View File

@@ -9,54 +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 233 skills?
**No!** When you clone the repository, all skills are available, but your AI only loads them when you explicitly invoke them with `@skill-name` or `/skill-name`.
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?
@@ -68,37 +70,22 @@ 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/`
- OpenCode: `.opencode/skills/` or `.claude/skills/`
---
### Does this work with Windows?
### Can I install skills in multiple projects?
**Yes!** You have two options:
**Option 1: Global Installation** (recommended)
Install once in your home directory, works for all projects:
**Yes**, but some "Official" skills use **symlinks** which Windows handles poorly by default.
Run git with:
```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:
Or enable "Developer Mode" in Windows Settings.
```bash
cd /path/to/your/project
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
```
---
### How do I update skills to the latest version?
### How do I update skills?
Navigate to your skills directory and pull the latest changes:
@@ -109,436 +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-233233) organized by category
**Method 2: Search by keyword**
```bash
ls skills/ | grep "keyword"
```
**Method 3: Ask your AI**
```
What skills are available for [topic]?
```
---
### 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-255255).
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:
### I'm new to open source. Can I contribute?
- ✅ Modify skills for your needs
- ✅ Create private versions
- ✅ Customize for your team
**Absolutely!** We welcome beginners.
**To modify:**
- Fix typos
- Add examples
- Improve docs
Check out [CONTRIBUTING.md](CONTRIBUTING.md) for instructions.
1. Copy the skill to a new location
2. Edit the SKILL.md file
3. Use your modified version
### My PR failed "Quality Bar" check. Why?
**Consider contributing improvements back!**
V3 introduces automated quality control. Your skill might be missing:
---
1. A valid `description`.
2. Usage examples.
Run `python3 scripts/validate_skills.py` locally to check before you push.
## Statistics & Info
### Can I update an "Official" skill?
### How many skills are there?
**233 skills** across 10+ categories as of the latest update.
---
### 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.
---
@@ -548,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! 🙌

View File

@@ -1,231 +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 **233 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 255+ 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
### 2. Pick Your Persona
In your AI chat, mention the skill:
Find the bundle that matches your role (see [docs/BUNDLES.md](docs/BUNDLES.md)):
```
@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!
| 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-255255) for risk labels._
---
## How to Find the Right Skill
## ❓ FAQ
### Method 1: Browse by Category
**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!
Check the [Full Skill Registry](README.md#full-skill-registry-233233) in the main README
**Q: Can I make my own skills?**
A: Yes! Use the **@skill-creator** skill to build your own.
### Method 2: Search by Keyword
Use your file explorer or terminal:
```bash
# Find skills related to "testing"
ls skills/ | grep test
# 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 233 skills?
**A:** No! Clone the whole repo, and your AI will only load skills when you use them.
### Q: Can I create my own skills?
**A:** Yes! Check out the `@skill-creator` skill or read [CONTRIBUTING.md](CONTRIBUTING.md)
### Q: What if my AI tool isn't listed?
**A:** If it supports the `SKILL.md` format, try `.agent/skills/` - it's the universal path.
### Q: Are these skills free?
**A:** Yes! MIT License. Use them however you want.
### Q: Do skills work offline?
**A:** The skill files are local, but your AI assistant needs internet to function.
---
## 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)

View File

@@ -1,54 +0,0 @@
# Repository Maintenance Protocol
To ensure consistency and quality, the following steps MUST be performed for **every single change** involving skills or documentation.
## 1. Skill Creation & Modification
- [ ] **Check Duplicates**: Before adding a skill, check `skills_index.json` or `ls skills/` to ensure it doesn't exist.
- [ ] **Folder Structure**: Each skill must have its own folder in `skills/<skill-name>`.
- [ ] **SKILL.md**: Every skill directory MUST contain a `SKILL.md` file with valid frontmatter:
```markdown
---
name: Skill Name
description: Brief description.
---
```
## 2. Validation & Indexing (CRITICAL)
Running the scripts is **MANDATORY** after any change to `skills/`.
- [ ] **Validate Skills**: Run the validation script to check for formatting errors.
```bash
python3 scripts/validate_skills.py
```
- [ ] **Generate Index**: Update `skills_index.json`. This is the source of truth for the agent.
```bash
python3 scripts/generate_index.py
```
## 3. Documentation Updates
- [ ] **Update README**: Run the automation script to sync counts and the registry table and also the number of skills
```bash
python3 scripts/update_readme.py
```
- [ ] **Credits & Sources**: If the skill was imported from a community repo, add a credit link in `# Credits & Sources` manually if needed.
- Example: `- **[repo-name](url)**: Source for [skill-name].`
## 4. Git Operations
- [ ] **Check Status**: `git status` to see what changed.
- [ ] **Add All Files**: Ensure new skill folders are added (`git add skills/`).
- [ ] **Commit**: Use a descriptive Conventional Commit message (e.g., `feat: add new security skills`, `docs: update readme count`).
- [ ] **Push**: `git push` to origin. **NEVER FORGET THIS.**
## 5. Agent Artifacts (Internal)
- [ ] **Walkthrough**: Update `walkthrough.md` in the brain/artifact directory to reflect the session's achievements.

702
README.md
View File

@@ -1,6 +1,6 @@
# 🌌 Antigravity Awesome Skills: 253+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
# 🌌 Antigravity Awesome Skills: 256+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
> **The Ultimate Collection of 253+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode**
> **The Ultimate Collection of 256+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode**
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Claude Code](https://img.shields.io/badge/Claude%20Code-Anthropic-purple)](https://claude.ai)
@@ -9,9 +9,9 @@
[![Cursor](https://img.shields.io/badge/Cursor-AI%20IDE-orange)](https://cursor.sh)
[![Copilot](https://img.shields.io/badge/GitHub%20Copilot-VSCode-lightblue)](https://github.com/features/copilot)
[![OpenCode](https://img.shields.io/badge/OpenCode-CLI-gray)](https://github.com/opencode-ai/opencode)
[![Antigravity](https://img.shields.io/badge/Antigravity-DeepMind-red)](https://github.com/anthropics/antigravity)
[![Antigravity](https://img.shields.io/badge/Antigravity-DeepMind-red)](https://github.com/sickn33/antigravity-awesome-skills)
**Antigravity Awesome Skills** is a curated, battle-tested library of **251 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
**Antigravity Awesome Skills** is a curated, battle-tested library of **256 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
- 🟣 **Claude Code** (Anthropic CLI)
- 🔵 **Gemini CLI** (Google DeepMind)
@@ -25,67 +25,72 @@ This repository provides essential skills to transform your AI assistant into a
## 📍 Table of Contents
- [🌌 Antigravity Awesome Skills: 251+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot \& More](#-antigravity-awesome-skills-251-agentic-skills-for-claude-code-gemini-cli-cursor-copilot--more)
- [📍 Table of Contents](#-table-of-contents)
- [New Here? Start Here!](#new-here-start-here)
- [🔌 Compatibility](#-compatibility)
- [Features \& Categories](#features--categories)
- [Full Skill Registry (251/251)](#full-skill-registry-251251)
- [Installation](#installation)
- [How to Contribute](#how-to-contribute)
- [Credits \& Sources](#credits--sources)
- [Official Sources](#official-sources)
- [Community Contributors](#community-contributors)
- [Inspirations](#inspirations)
- [License](#license)
- [🏷️ GitHub Topics](#-github-topics)
- [🚀 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-256256)
- [🛠️ 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 251 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 `.claude/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/...`
---
@@ -99,281 +104,290 @@ The repository is organized into several key areas of expertise:
| Category | Skills Count | Key Skills Included |
| :-------------------------- | :----------- | :--------------------------------------------------------------------------------------------------------------------------- |
| **🛸 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** | **~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** | **~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** | **~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 |
| **📈 Product & Strategy** | **~8** | Product Manager Toolkit, Content Creator, ASO, Doc Co-authoring, Brainstorming, Internal Comms |
| **📣 Marketing & Growth** | **~23** | Page CRO, Copywriting, SEO Audit, Paid Ads, Email Sequence, Pricing Strategy, Referral Program, Launch Strategy |
| **🚀 Maker Tools** | **~11** | Micro-SaaS Launcher, Browser Extension Builder, Telegram Bot, AI Wrapper Product, Viral Generator, 3D Web Experience |
| **🛸 Autonomous & Agentic** | **(13)** | Loki Mode (Startup-in-a-box), Subagent Driven Dev, Dispatching Parallel Agents, Planning With Files, Skill Creator/Developer |
| **🔌 Integrations & APIs** | **(35)** | Stripe, Firebase, Supabase, Vercel, Clerk Auth, Twilio, Discord Bot, Slack Bot, GraphQL, AWS Serverless |
| **🛡️ Cybersecurity** | **(32)** | Ethical Hacking, Metasploit, Burp Suite, SQLMap, Active Directory, AWS/Cloud Pentesting, OWASP Top 100, Red Team Tools |
| **🎨 Creative & Design** | **(21)** | UI/UX Pro Max, Frontend Design, Canvas, Algorithmic Art, Theme Factory, D3 Viz, Web Artifacts |
| **🛠️ Development** | **(44)** | TDD, Systematic Debugging, React Patterns, Backend/Frontend Guidelines, Senior Fullstack, Software Architecture |
| **🏗️ Infrastructure & Git** | **(13)** | Linux Shell Scripting, Git Worktrees, Git Pushing, Conventional Commits, File Organization, GitHub Workflow Automation |
| **🤖 AI Agents & LLM** | **(27)** | Voice AI Engine, LangGraph, CrewAI, Langfuse, RAG Engineer, Prompt Engineer, Browser Automation, Agent Memory Systems |
| **🔄 Workflow & Planning** | **(19)** | Writing Plans, Executing Plans, Concise Planning, Verification Before Completion, Code Review (Requesting/Receiving) |
| **📄 Document Processing** | **(5)** | DOCX (Official), PDF (Official), PPTX (Official), XLSX (Official) |
| **🧪 Testing & QA** | **(8)** | Webapp Testing, Playwright Automation, Test Fixing, Testing Patterns |
| **📈 Product & Strategy** | **(4)** | Product Manager Toolkit, Content Creator, ASO, Doc Co-authoring, Brainstorming, Internal Comms |
| **📣 Marketing & Growth** | **(26)** | Page CRO, Copywriting, SEO Audit, Paid Ads, Email Sequence, Pricing Strategy, Referral Program, Launch Strategy |
| **🚀 Maker Tools** | **(8)** | Micro-SaaS Launcher, Browser Extension Builder, Telegram Bot, AI Wrapper Product, Viral Generator, 3D Web Experience |
---
## Curated Collections
## Full Skill Registry (253/253)
[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 (256/256)
> [!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 |
| :--- | :--- | :--- |
| **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** | When the user wants to set up, improve, or audit analytics tracking and measurement. Also use when the user mentions "set up tracking," "GA4," "Google Analytics," "conversion tracking," "event tracking," "UTM parameters," "tag manager," "GTM," "analytics implementation," or "tracking plan." For A/B test measurement, see ab-test-setup. | `skills/analytics-tracking` |
| **API 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** | Comprehensive backend development guide for Node.js/Express/TypeScript microservices. Use when creating routes, controllers, services, repositories, middleware, or working with Express APIs, Prisma database access, Sentry error tracking, Zod validation, unifiedConfig, dependency injection, or async patterns. Covers layered architecture (routes → controllers → services → repositories), BaseController pattern, error handling, performance monitoring, testing strategies, and migration from legacy patterns. | `skills/backend-dev-guidelines` |
| **backend-patterns** | Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes. | `skills/cc-skill-backend-patterns` |
| **bash-linux** | Bash/Linux terminal patterns. Critical commands, piping, error handling, scripting. Use when working on macOS or Linux systems. | `skills/bash-linux` |
| **behavioral-modes** | AI operational modes (brainstorm, implement, debug, review, teach, ship, orchestrate). Use to adapt behavior based on task type. | `skills/behavioral-modes` |
| **blockrun** | Use when user needs capabilities Claude lacks (image generation, real-time X/Twitter data) or explicitly requests external models ("blockrun", "use grok", "use gpt", "dall-e", "deepseek") | `skills/blockrun` |
| **brainstorming** | > | `skills/brainstorming` |
| **brand-guidelines** | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply. | `skills/brand-guidelines-community` |
| **brand-guidelines** | Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply. | `skills/brand-guidelines-anthropic` |
| **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** | > | `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` |
| **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** | > | `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** | When the user wants to optimize any form that is NOT signup/registration — including lead capture forms, contact forms, demo request forms, application forms, survey forms, or checkout forms. Also use when the user mentions "form optimization," "lead form conversions," "form friction," "form fields," "form completion rate," or "contact form." For signup/registration forms, see signup-flow-cro. For popups containing forms, see popup-cro. | `skills/form-cro` |
| **free-tool-strategy** | When the user wants to plan, evaluate, or build a free tool for marketing purposes — lead generation, SEO value, or brand awareness. Also use when the user mentions "engineering as marketing," "free tool," "marketing tool," "calculator," "generator," "interactive tool," "lead gen tool," "build a tool for leads," or "free resource." This skill bridges engineering and marketing — useful for founders and technical marketers. | `skills/free-tool-strategy` |
| **frontend-design** | Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics. | `skills/frontend-design` |
| **frontend-dev-guidelines** | Frontend development guidelines for React/TypeScript applications. Modern patterns including Suspense, lazy loading, useSuspenseQuery, file organization with features directory, MUI v7 styling, TanStack Router, performance optimization, and TypeScript best practices. Use when creating components, pages, features, fetching data, styling, routing, or working with frontend code. | `skills/frontend-dev-guidelines` |
| **frontend-patterns** | Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices. | `skills/cc-skill-frontend-patterns` |
| **game-art** | Game art principles. Visual style selection, asset pipeline, animation workflow. | `skills/game-development/game-art` |
| **game-audio** | Game audio principles. Sound design, music integration, adaptive audio systems. | `skills/game-development/game-audio` |
| **game-design** | Game design principles. GDD structure, balancing, player psychology, progression. | `skills/game-development/game-design` |
| **game-development** | Game development orchestrator. Routes to platform-specific skills based on project needs. | `skills/game-development` |
| **gcp-cloud-run** | "Specialized skill for building production-ready serverless applications on GCP. Covers Cloud Run services (containerized), Cloud Run Functions (event-driven), cold start optimization, and event-driven architecture with Pub/Sub." | `skills/gcp-cloud-run` |
| **geo-fundamentals** | Generative Engine Optimization for AI search engines (ChatGPT, Claude, Perplexity). | `skills/geo-fundamentals` |
| **git-pushing** | Stage, commit, and push git changes with conventional commit messages. Use when user wants to commit and push changes, mentions pushing to remote, or asks to save and push their work. Also activates when user says "push changes", "commit and push", "push this", "push to github", or similar git workflow requests. | `skills/git-pushing` |
| **github-workflow-automation** | "Automate GitHub workflows with AI assistance. Includes PR reviews, issue triage, CI/CD integration, and Git operations. Use when automating GitHub workflows, setting up PR review automation, creating GitHub Actions, or triaging issues." | `skills/github-workflow-automation` |
| **graphql** | "GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully." | `skills/graphql` |
| **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` |
| **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** | "When the user needs marketing ideas, inspiration, or strategies for their SaaS or software product. Also use when the user asks for 'marketing ideas,' 'growth ideas,' 'how to market,' 'marketing strategies,' 'marketing tactics,' 'ways to promote,' or 'ideas to grow.' This skill provides 140 proven marketing approaches organized by category." | `skills/marketing-ideas` |
| **marketing-psychology** | "When the user wants to apply psychological principles, mental models, or behavioral science to marketing. Also use when the user mentions 'psychology,' 'mental models,' 'cognitive bias,' 'persuasion,' 'behavioral science,' 'why people buy,' 'decision-making,' or 'consumer behavior.' This skill provides 70+ mental models organized for marketing application." | `skills/marketing-psychology` |
| **mcp-builder** | Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK). | `skills/mcp-builder` |
| **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 thinking and decision-making for iOS and Android apps. Touch interaction, performance patterns, platform conventions. Teaches principles, not fixed values. Use when building React Native, Flutter, or native mobile apps. | `skills/mobile-design` |
| **mobile-games** | Mobile game development principles. Touch input, battery, performance, app stores. | `skills/game-development/mobile-games` |
| **moodle-external-api-development** | Create custom external web service APIs for Moodle LMS. Use when implementing web services for course management, user tracking, quiz operations, or custom plugin functionality. Covers parameter validation, database operations, error handling, service registration, and Moodle coding standards. | `skills/moodle-external-api-development` |
| **multi-agent-brainstorming** | > | `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** | When the user wants to optimize, improve, or increase conversions on any marketing page — including homepage, landing pages, pricing pages, feature pages, or blog posts. Also use when the user says "CRO," "conversion rate optimization," "this page isn't converting," "improve conversions," or "why isn't this page working." For signup/registration flows, see signup-flow-cro. For post-signup activation, see onboarding-cro. For forms outside of signup, see form-cro. For popups/modals, see popup-cro. | `skills/page-cro` |
| **paid-ads** | "When the user wants help with paid advertising campaigns on Google Ads, Meta (Facebook/Instagram), LinkedIn, Twitter/X, or other ad platforms. Also use when the user mentions 'PPC,' 'paid media,' 'ad copy,' 'ad creative,' 'ROAS,' 'CPA,' 'ad campaign,' 'retargeting,' or 'audience targeting.' This skill covers campaign strategy, ad creation, audience targeting, and optimization." | `skills/paid-ads` |
| **parallel-agents** | Multi-agent orchestration patterns. Use when multiple independent tasks can run with different domain expertise or when comprehensive analysis requires multiple perspectives. | `skills/parallel-agents` |
| **paywall-upgrade-cro** | When the user wants to create or optimize in-app paywalls, upgrade screens, upsell modals, or feature gates. Also use when the user mentions "paywall," "upgrade screen," "upgrade modal," "upsell," "feature gate," "convert free to paid," "freemium conversion," "trial expiration screen," "limit reached screen," "plan upgrade prompt," or "in-app pricing." Distinct from public pricing pages (see page-cro) — this skill focuses on in-product upgrade moments where the user has already experienced value. | `skills/paywall-upgrade-cro` |
| **pc-games** | PC and console game development principles. Engine selection, platform features, optimization strategies. | `skills/game-development/pc-games` |
| **pdf** | Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. When Claude needs to fill in a PDF form or programmatically process, generate, or analyze PDF documents at scale. | `skills/pdf-official` |
| **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** | When the user wants to create or optimize popups, modals, overlays, slide-ins, or banners for conversion purposes. Also use when the user mentions "exit intent," "popup conversions," "modal optimization," "lead capture popup," "email popup," "announcement banner," or "overlay." For forms outside of popups, see form-cro. For general page conversion optimization, see page-cro. | `skills/popup-cro` |
| **powershell-windows** | PowerShell Windows patterns. Critical pitfalls, operator syntax, error handling. | `skills/powershell-windows` |
| **pptx** | "Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks" | `skills/pptx-official` |
| **pricing-strategy** | "When the user wants help with pricing decisions, packaging, or monetization strategy. Also use when the user mentions 'pricing,' 'pricing tiers,' 'freemium,' 'free trial,' 'packaging,' 'price increase,' 'value metric,' 'Van Westendorp,' 'willingness to pay,' or 'monetization.' This skill covers pricing research, tier structure, and packaging strategy." | `skills/pricing-strategy` |
| **prisma-expert** | Prisma ORM expert for schema design, migrations, query optimization, relations modeling, and database operations. Use PROACTIVELY for Prisma schema issues, migration problems, query performance, relation design, or database connection issues. | `skills/prisma-expert` |
| **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** | When the user wants to create SEO-driven pages at scale using templates and data. Also use when the user mentions "programmatic SEO," "template pages," "pages at scale," "directory pages," "location pages," "[keyword] + [city] pages," "comparison pages," "integration pages," or "building many pages for SEO." For auditing existing SEO issues, see seo-audit. | `skills/programmatic-seo` |
| **prompt-caching** | "Caching strategies for LLM prompts including Anthropic prompt caching, response caching, and CAG (Cache Augmented Generation) Use when: prompt caching, cache prompt, response cache, cag, cache augmented." | `skills/prompt-caching` |
| **prompt-engineer** | "Expert in designing effective prompts for LLM-powered applications. Masters prompt structure, context management, output formatting, and prompt evaluation. Use when: prompt engineering, system prompt, few-shot, chain of thought, prompt design." | `skills/prompt-engineer` |
| **prompt-engineering** | Expert guide on prompt engineering patterns, best practices, and optimization techniques. Use when user wants to improve prompts, learn prompting strategies, or debug agent behavior. | `skills/prompt-engineering` |
| **prompt-library** | "Curated collection of high-quality prompts for various use cases. Includes role-based prompts, task-specific templates, and prompt refinement techniques. Use when user needs prompt templates, role-play prompts, or ready-to-use prompt examples for coding, writing, analysis, or creative tasks." | `skills/prompt-library` |
| **python-patterns** | Python development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying. | `skills/python-patterns` |
| **rag-engineer** | "Expert in building Retrieval-Augmented Generation systems. Masters embedding models, vector databases, chunking strategies, and retrieval optimization for LLM applications. Use when: building RAG, vector search, embeddings, semantic search, document retrieval." | `skills/rag-engineer` |
| **rag-implementation** | "Retrieval-Augmented Generation patterns including chunking, embeddings, vector stores, and retrieval optimization Use when: rag, retrieval augmented, vector search, embeddings, semantic search." | `skills/rag-implementation` |
| **react-patterns** | Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices. | `skills/react-patterns` |
| **react-ui-patterns** | Modern React UI patterns for loading states, error handling, and data fetching. Use when building UI components, handling async data, or managing UI states. | `skills/react-ui-patterns` |
| **receiving-code-review** | Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation | `skills/receiving-code-review` |
| **Red Team 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** | When the user wants to add, fix, or optimize schema markup and structured data on their site. Also use when the user mentions "schema markup," "structured data," "JSON-LD," "rich snippets," "schema.org," "FAQ schema," "product schema," "review schema," or "breadcrumb schema." For broader SEO issues, see seo-audit. | `skills/schema-markup` |
| **scroll-experience** | "Expert in building immersive scroll-driven experiences - parallax storytelling, scroll animations, interactive narratives, and cinematic web experiences. Like NY Times interactives, Apple product pages, and award-winning web experiences. Makes websites feel like experiences, not just pages. Use when: scroll animation, parallax, scroll storytelling, interactive story, cinematic website." | `skills/scroll-experience` |
| **Security 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** | When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," or "SEO health check." For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema-markup. | `skills/seo-audit` |
| **seo-fundamentals** | SEO fundamentals, E-E-A-T, Core Web Vitals, and Google algorithm principles. | `skills/seo-fundamentals` |
| **server-management** | Server management principles and decision-making. Process management, monitoring strategy, and scaling decisions. Teaches thinking, not commands. | `skills/server-management` |
| **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** | \| | `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** | >- | `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` |
| 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` |
| **voice-ai-engine-development** | ⚪ | Build real-time conversational AI voice engines using async worker pipelines, streaming transcription, LLM agents, and TTS synthesis with interrupt handling and multi-provider support | `skills/voice-ai-engine-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
@@ -411,6 +425,17 @@ 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
@@ -438,6 +463,8 @@ This collection would not be possible without the incredible work of the Claude
- **[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
@@ -450,13 +477,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:
@@ -464,30 +494,40 @@ 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
## 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)
- [arathiesh](https://github.com/arathiesh)
- [BenedictKing](https://github.com/BenedictKing)
- [GuppyTheCat](https://github.com/GuppyTheCat)
- [Ianj332](https://github.com/Ianj332)
- [krisnasantosa15](https://github.com/krisnasantosa15)
- [Mohammad Faiz](https://github.com/mohdfaiz2k9)
- [Nguyen Huu Loc](https://github.com/LocNguyenSGU)
- [Owen Wu](https://github.com/yubing744)
- [sck_0](https://github.com/sck_0)
- [sickn33](https://github.com/sickn33)
- [SuperJMN](https://github.com/SuperJMN)
- [Tiger-Foxx](https://github.com/Tiger-Foxx)
- [Viktor Ferenczi](https://github.com/viktor-ferenczi)
- [vuth-dogo](https://github.com/vuth-dogo)
- [krisnasantosa15](https://github.com/krisnasantosa15)
- [zebbern](https://github.com/zebbern)
- [vuth-dogo](https://github.com/vuth-dogo)
## 👥 Repo Contributors
Thanks to the people who have contributed to this project:
- [@sickn33](https://github.com/sickn33) - Voice AI Engine (PR #33)
- [@community](https://github.com/community) - Categorization Initiative (PR #32)
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=sickn33/antigravity-awesome-skills&type=date&legend=top-left)](https://www.star-history.com/#sickn33/antigravity-awesome-skills&type=date&legend=top-left)

19
SECURITY.md Normal file
View 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
View 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
View 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.

View 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

View File

@@ -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
View 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
```

View 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.

View File

@@ -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
View 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).

View File

@@ -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

View File

@@ -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"].lower())
# 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__":

View File

@@ -20,7 +20,6 @@ def update_readme():
content = f.read()
# 1. Update Title Count
# Pattern: # 🌌 Antigravity Awesome Skills: [NUM]+ Agentic Skills
content = re.sub(
r'(# 🌌 Antigravity Awesome Skills: )\d+(\+ Agentic Skills)',
f'\\g<1>{total_skills}\\g<2>',
@@ -28,7 +27,6 @@ def update_readme():
)
# 2. Update Blockquote Count
# Pattern: Collection of [NUM]+ Universal
content = re.sub(
r'(Collection of )\d+(\+ Universal)',
f'\\g<1>{total_skills}\\g<2>',
@@ -36,7 +34,6 @@ def update_readme():
)
# 3. Update Intro Text Count
# Pattern: library of **[NUM] high-performance skills**
content = re.sub(
r'(library of \*\*)\d+( high-performance skills\*\*)',
f'\\g<1>{total_skills}\\g<2>',
@@ -44,14 +41,21 @@ def update_readme():
)
# 4. Update Registry Header Count
# Pattern: ## Full Skill Registry ([NUM]/[NUM])
content = re.sub(
r'(## Full Skill Registry \()\d+/\d+(\))',
f'\\g<1>{total_skills}/{total_skills}\\g<2>',
content
)
# 5. Generate New Registry Table
# 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
@@ -61,30 +65,34 @@ def update_readme():
if note_match:
note_block = note_match.group(1)
else:
# Fallback default note if not found (though it should be there)
note_block = "> [!NOTE] > **Document Skills**: We provide both **community** and **official Anthropic** versions for DOCX, PDF, PPTX, and XLSX. Locally, the official versions are used by default (via symlinks). In the repository, both versions are available for flexibility."
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 | Description | Path |\n| :--- | :--- | :--- |"
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')
# Escape pipes in description to strictly avoid breaking the table
desc = desc.replace('|', '\|')
# 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 = "🔴"
row = f"| **{name}** | {desc} | `{path}` |"
# 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
# We look for the start of the section and the end (which is either the next H2 or EOF)
# The section starts after "## Full Skill Registry (X/X)"
# First, find the header position
header_pattern = r'## Full Skill Registry \(\d+/\d+\)'
header_match = re.search(header_pattern, content)
@@ -99,18 +107,10 @@ def update_readme():
if next_section_match:
end_pos = start_pos + next_section_match.start()
# Keep everything after the table
rest_of_file = content[end_pos:]
else:
# Table goes to end of file
rest_of_file = ""
# Check for text between Header and Table (usually just newlines or the Note)
# We replace everything from Header End to Next Section with our New Table Section
# but we need to supply the pre-table Note which we extracted/re-generated above.
# Simplification: We construct the top part (before header), add header, add new table section, add rest.
before_header = content[:header_match.start()]
new_header = f"## Full Skill Registry ({total_skills}/{total_skills})"
@@ -119,7 +119,7 @@ def update_readme():
with open(readme_path, 'w', encoding='utf-8') as f:
f.write(new_content)
print("✅ README.md updated successfully.")
print("✅ README.md updated successfully with Collections link and Risk columns.")
if __name__ == "__main__":
update_readme()

View File

@@ -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)

View File

@@ -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: **0100**
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 (025)
* Clear business questions defined
* Each tracked event maps to a decision
* No events tracked “just in case”
---
#### 2. Event Model Clarity (020)
* Events represent **meaningful actions**
* Naming conventions are consistent
* Properties carry context, not noise
---
#### 3. Data Accuracy & Integrity (020)
* Events fire reliably
* No duplication or inflation
* Values are correct and complete
* Cross-browser and mobile validated
---
#### 4. Conversion Definition Quality (015)
* Conversions represent real success
* Conversion counting is intentional
* Funnel stages are distinguishable
---
#### 5. Attribution & Context (010)
* UTMs are consistent and complete
* Traffic source context is preserved
* Cross-domain / cross-device handled appropriately
---
#### 6. Governance & Maintenance (010)
* Tracking is documented
* Ownership is clear
* Changes are versioned and monitored
---
### Readiness Bands (Required)
| Score | Verdict | Interpretation |
| ------ | --------------------- | --------------------------------- |
| 85100 | **Measurement-Ready** | Safe to optimize and experiment |
| 7084 | **Usable with Gaps** | Fix issues before major decisions |
| 5569 | **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, **dont track it**.
---
### 2. Start with Questions, Work Backwards
Define:
* What you need to know
* What action youll 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
---

View File

@@ -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 (15)
### 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 |
| -------- | --------- | ---------------------- |
| **610** | Safe | Proceed |
| **35** | Moderate | Add tests + monitoring |
| **02** | 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 ✅

View 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 ReportYYYY-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. **用户提示**:
- 必须在生成的日报开头(引用块部分)包含明显的警告信息,提示用户当前正在运行于降级模式。

View 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": []
}
}

View 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
}
}

View File

@@ -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: **0100**
This is a **diagnostic score**, not a KPI.
---
### Scoring Categories & Weights
| Category | Weight |
| ---------------------------- | ------- |
| Field Necessity & Efficiency | 30 |
| ValueEffort 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 (030)
* Every required field is justified
* No unused or “nice-to-have” fields
* No duplicated or inferable data
---
#### 2. ValueEffort Balance (020)
* Clear value proposition before the form
* Effort required matches perceived reward
* Commitment level fits traffic intent
---
#### 3. Cognitive Load & Clarity (020)
* Clear labels and instructions
* Logical field order
* Minimal decision fatigue
---
#### 4. Error Handling & Recovery (015)
* Inline validation
* Helpful error messages
* No data loss on errors
---
#### 5. Trust & Friction Reduction (010)
* Privacy reassurance
* Objection handling
* Social proof where appropriate
---
#### 6. Mobile Usability (05)
* Touch-friendly
* Proper keyboards
* No horizontal scrolling or cramped fields
---
### Health Bands (Required)
| Score | Verdict | Interpretation |
| ------ | ------------------------ | -------------------------------- |
| 85100 | **High-Performing** | Optimize incrementally |
| 7084 | **Usable with Friction** | Clear optimization opportunities |
| 5569 | **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
* 46 fields → 1025%
* 7+ fields → 2550%+
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
---

View File

@@ -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 (15)
| 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 |
| --------- | --------- | --------------------------- |
| **1215** | Excellent | Execute fully |
| **811** | Strong | Proceed with discipline |
| **47** | 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 isnt 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?
---

View File

@@ -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 (15)
| 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 |
| --------- | ---------- | ----------------- |
| **1015** | Excellent | Proceed |
| **69** | Acceptable | Proceed with care |
| **35** | 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 (300500ms)
* 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
View 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"/>
&nbsp;&nbsp;→&nbsp;&nbsp;
<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
View 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
View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View 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"
}
]
}

View 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"
}
]
}

View 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
}
}

View 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/"
}
}
]
}
}
]

View 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
}
}

View 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

View 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

View 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()

View File

@@ -0,0 +1 @@
# last30days library modules

View 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)

View 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))

View 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)

View 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

View 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)

View 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

View 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]

View 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

View 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

View File

@@ -0,0 +1,383 @@
"""Output rendering for last30days skill."""
import json
from pathlib import Path
from typing import List, Optional
from . import schema
OUTPUT_DIR = Path.home() / ".local" / "share" / "last30days" / "out"
def ensure_output_dir():
"""Ensure output directory exists."""
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
def _assess_data_freshness(report: schema.Report) -> dict:
"""Assess how much data is actually from the last 30 days."""
reddit_recent = sum(1 for r in report.reddit if r.date and r.date >= report.range_from)
x_recent = sum(1 for x in report.x if x.date and x.date >= report.range_from)
web_recent = sum(1 for w in report.web if w.date and w.date >= report.range_from)
total_recent = reddit_recent + x_recent + web_recent
total_items = len(report.reddit) + len(report.x) + len(report.web)
return {
"reddit_recent": reddit_recent,
"x_recent": x_recent,
"web_recent": web_recent,
"total_recent": total_recent,
"total_items": total_items,
"is_sparse": total_recent < 5,
"mostly_evergreen": total_items > 0 and total_recent < total_items * 0.3,
}
def render_compact(report: schema.Report, limit: int = 15, missing_keys: str = "none") -> str:
"""Render compact output for Claude to synthesize.
Args:
report: Report data
limit: Max items per source
missing_keys: 'both', 'reddit', 'x', or 'none'
Returns:
Compact markdown string
"""
lines = []
# Header
lines.append(f"## Research Results: {report.topic}")
lines.append("")
# Assess data freshness and add honesty warning if needed
freshness = _assess_data_freshness(report)
if freshness["is_sparse"]:
lines.append("**⚠️ LIMITED RECENT DATA** - Few discussions from the last 30 days.")
lines.append(f"Only {freshness['total_recent']} item(s) confirmed from {report.range_from} to {report.range_to}.")
lines.append("Results below may include older/evergreen content. Be transparent with the user about this.")
lines.append("")
# Web-only mode banner (when no API keys)
if report.mode == "web-only":
lines.append("**🌐 WEB SEARCH MODE** - Claude will search blogs, docs & news")
lines.append("")
lines.append("---")
lines.append("**⚡ Want better results?** Add API keys to unlock Reddit & X data:")
lines.append("- `OPENAI_API_KEY` → Reddit threads with real upvotes & comments")
lines.append("- `XAI_API_KEY` → X posts with real likes & reposts")
lines.append("- Edit `~/.config/last30days/.env` to add keys")
lines.append("---")
lines.append("")
# Cache indicator
if report.from_cache:
age_str = f"{report.cache_age_hours:.1f}h old" if report.cache_age_hours else "cached"
lines.append(f"**⚡ CACHED RESULTS** ({age_str}) - use `--refresh` for fresh data")
lines.append("")
lines.append(f"**Date Range:** {report.range_from} to {report.range_to}")
lines.append(f"**Mode:** {report.mode}")
if report.openai_model_used:
lines.append(f"**OpenAI Model:** {report.openai_model_used}")
if report.xai_model_used:
lines.append(f"**xAI Model:** {report.xai_model_used}")
lines.append("")
# Coverage note for partial coverage
if report.mode == "reddit-only" and missing_keys == "x":
lines.append("*💡 Tip: Add XAI_API_KEY for X/Twitter data and better triangulation.*")
lines.append("")
elif report.mode == "x-only" and missing_keys == "reddit":
lines.append("*💡 Tip: Add OPENAI_API_KEY for Reddit data and better triangulation.*")
lines.append("")
# Reddit items
if report.reddit_error:
lines.append("### Reddit Threads")
lines.append("")
lines.append(f"**ERROR:** {report.reddit_error}")
lines.append("")
elif report.mode in ("both", "reddit-only") and not report.reddit:
lines.append("### Reddit Threads")
lines.append("")
lines.append("*No relevant Reddit threads found for this topic.*")
lines.append("")
elif report.reddit:
lines.append("### Reddit Threads")
lines.append("")
for item in report.reddit[:limit]:
eng_str = ""
if item.engagement:
eng = item.engagement
parts = []
if eng.score is not None:
parts.append(f"{eng.score}pts")
if eng.num_comments is not None:
parts.append(f"{eng.num_comments}cmt")
if parts:
eng_str = f" [{', '.join(parts)}]"
date_str = f" ({item.date})" if item.date else " (date unknown)"
conf_str = f" [date:{item.date_confidence}]" if item.date_confidence != "high" else ""
lines.append(f"**{item.id}** (score:{item.score}) r/{item.subreddit}{date_str}{conf_str}{eng_str}")
lines.append(f" {item.title}")
lines.append(f" {item.url}")
lines.append(f" *{item.why_relevant}*")
# Top comment insights
if item.comment_insights:
lines.append(f" Insights:")
for insight in item.comment_insights[:3]:
lines.append(f" - {insight}")
lines.append("")
# X items
if report.x_error:
lines.append("### X Posts")
lines.append("")
lines.append(f"**ERROR:** {report.x_error}")
lines.append("")
elif report.mode in ("both", "x-only", "all", "x-web") and not report.x:
lines.append("### X Posts")
lines.append("")
lines.append("*No relevant X posts found for this topic.*")
lines.append("")
elif report.x:
lines.append("### X Posts")
lines.append("")
for item in report.x[:limit]:
eng_str = ""
if item.engagement:
eng = item.engagement
parts = []
if eng.likes is not None:
parts.append(f"{eng.likes}likes")
if eng.reposts is not None:
parts.append(f"{eng.reposts}rt")
if parts:
eng_str = f" [{', '.join(parts)}]"
date_str = f" ({item.date})" if item.date else " (date unknown)"
conf_str = f" [date:{item.date_confidence}]" if item.date_confidence != "high" else ""
lines.append(f"**{item.id}** (score:{item.score}) @{item.author_handle}{date_str}{conf_str}{eng_str}")
lines.append(f" {item.text[:200]}...")
lines.append(f" {item.url}")
lines.append(f" *{item.why_relevant}*")
lines.append("")
# Web items (if any - populated by Claude)
if report.web_error:
lines.append("### Web Results")
lines.append("")
lines.append(f"**ERROR:** {report.web_error}")
lines.append("")
elif report.web:
lines.append("### Web Results")
lines.append("")
for item in report.web[:limit]:
date_str = f" ({item.date})" if item.date else " (date unknown)"
conf_str = f" [date:{item.date_confidence}]" if item.date_confidence != "high" else ""
lines.append(f"**{item.id}** [WEB] (score:{item.score}) {item.source_domain}{date_str}{conf_str}")
lines.append(f" {item.title}")
lines.append(f" {item.url}")
lines.append(f" {item.snippet[:150]}...")
lines.append(f" *{item.why_relevant}*")
lines.append("")
return "\n".join(lines)
def render_context_snippet(report: schema.Report) -> str:
"""Render reusable context snippet.
Args:
report: Report data
Returns:
Context markdown string
"""
lines = []
lines.append(f"# Context: {report.topic} (Last 30 Days)")
lines.append("")
lines.append(f"*Generated: {report.generated_at[:10]} | Sources: {report.mode}*")
lines.append("")
# Key sources summary
lines.append("## Key Sources")
lines.append("")
all_items = []
for item in report.reddit[:5]:
all_items.append((item.score, "Reddit", item.title, item.url))
for item in report.x[:5]:
all_items.append((item.score, "X", item.text[:50] + "...", item.url))
for item in report.web[:5]:
all_items.append((item.score, "Web", item.title[:50] + "...", item.url))
all_items.sort(key=lambda x: -x[0])
for score, source, text, url in all_items[:7]:
lines.append(f"- [{source}] {text}")
lines.append("")
lines.append("## Summary")
lines.append("")
lines.append("*See full report for best practices, prompt pack, and detailed sources.*")
lines.append("")
return "\n".join(lines)
def render_full_report(report: schema.Report) -> str:
"""Render full markdown report.
Args:
report: Report data
Returns:
Full report markdown
"""
lines = []
# Title
lines.append(f"# {report.topic} - Last 30 Days Research Report")
lines.append("")
lines.append(f"**Generated:** {report.generated_at}")
lines.append(f"**Date Range:** {report.range_from} to {report.range_to}")
lines.append(f"**Mode:** {report.mode}")
lines.append("")
# Models
lines.append("## Models Used")
lines.append("")
if report.openai_model_used:
lines.append(f"- **OpenAI:** {report.openai_model_used}")
if report.xai_model_used:
lines.append(f"- **xAI:** {report.xai_model_used}")
lines.append("")
# Reddit section
if report.reddit:
lines.append("## Reddit Threads")
lines.append("")
for item in report.reddit:
lines.append(f"### {item.id}: {item.title}")
lines.append("")
lines.append(f"- **Subreddit:** r/{item.subreddit}")
lines.append(f"- **URL:** {item.url}")
lines.append(f"- **Date:** {item.date or 'Unknown'} (confidence: {item.date_confidence})")
lines.append(f"- **Score:** {item.score}/100")
lines.append(f"- **Relevance:** {item.why_relevant}")
if item.engagement:
eng = item.engagement
lines.append(f"- **Engagement:** {eng.score or '?'} points, {eng.num_comments or '?'} comments")
if item.comment_insights:
lines.append("")
lines.append("**Key Insights from Comments:**")
for insight in item.comment_insights:
lines.append(f"- {insight}")
lines.append("")
# X section
if report.x:
lines.append("## X Posts")
lines.append("")
for item in report.x:
lines.append(f"### {item.id}: @{item.author_handle}")
lines.append("")
lines.append(f"- **URL:** {item.url}")
lines.append(f"- **Date:** {item.date or 'Unknown'} (confidence: {item.date_confidence})")
lines.append(f"- **Score:** {item.score}/100")
lines.append(f"- **Relevance:** {item.why_relevant}")
if item.engagement:
eng = item.engagement
lines.append(f"- **Engagement:** {eng.likes or '?'} likes, {eng.reposts or '?'} reposts")
lines.append("")
lines.append(f"> {item.text}")
lines.append("")
# Web section
if report.web:
lines.append("## Web Results")
lines.append("")
for item in report.web:
lines.append(f"### {item.id}: {item.title}")
lines.append("")
lines.append(f"- **Source:** {item.source_domain}")
lines.append(f"- **URL:** {item.url}")
lines.append(f"- **Date:** {item.date or 'Unknown'} (confidence: {item.date_confidence})")
lines.append(f"- **Score:** {item.score}/100")
lines.append(f"- **Relevance:** {item.why_relevant}")
lines.append("")
lines.append(f"> {item.snippet}")
lines.append("")
# Placeholders for Claude synthesis
lines.append("## Best Practices")
lines.append("")
lines.append("*To be synthesized by Claude*")
lines.append("")
lines.append("## Prompt Pack")
lines.append("")
lines.append("*To be synthesized by Claude*")
lines.append("")
return "\n".join(lines)
def write_outputs(
report: schema.Report,
raw_openai: Optional[dict] = None,
raw_xai: Optional[dict] = None,
raw_reddit_enriched: Optional[list] = None,
):
"""Write all output files.
Args:
report: Report data
raw_openai: Raw OpenAI API response
raw_xai: Raw xAI API response
raw_reddit_enriched: Raw enriched Reddit thread data
"""
ensure_output_dir()
# report.json
with open(OUTPUT_DIR / "report.json", 'w') as f:
json.dump(report.to_dict(), f, indent=2)
# report.md
with open(OUTPUT_DIR / "report.md", 'w') as f:
f.write(render_full_report(report))
# last30days.context.md
with open(OUTPUT_DIR / "last30days.context.md", 'w') as f:
f.write(render_context_snippet(report))
# Raw responses
if raw_openai:
with open(OUTPUT_DIR / "raw_openai.json", 'w') as f:
json.dump(raw_openai, f, indent=2)
if raw_xai:
with open(OUTPUT_DIR / "raw_xai.json", 'w') as f:
json.dump(raw_xai, f, indent=2)
if raw_reddit_enriched:
with open(OUTPUT_DIR / "raw_reddit_threads_enriched.json", 'w') as f:
json.dump(raw_reddit_enriched, f, indent=2)
def get_context_path() -> str:
"""Get path to context file."""
return str(OUTPUT_DIR / "last30days.context.md")

View File

@@ -0,0 +1,336 @@
"""Data schemas for last30days skill."""
from dataclasses import dataclass, field, asdict
from typing import Any, Dict, List, Optional
from datetime import datetime, timezone
@dataclass
class Engagement:
"""Engagement metrics."""
# Reddit fields
score: Optional[int] = None
num_comments: Optional[int] = None
upvote_ratio: Optional[float] = None
# X fields
likes: Optional[int] = None
reposts: Optional[int] = None
replies: Optional[int] = None
quotes: Optional[int] = None
def to_dict(self) -> Dict[str, Any]:
d = {}
if self.score is not None:
d['score'] = self.score
if self.num_comments is not None:
d['num_comments'] = self.num_comments
if self.upvote_ratio is not None:
d['upvote_ratio'] = self.upvote_ratio
if self.likes is not None:
d['likes'] = self.likes
if self.reposts is not None:
d['reposts'] = self.reposts
if self.replies is not None:
d['replies'] = self.replies
if self.quotes is not None:
d['quotes'] = self.quotes
return d if d else None
@dataclass
class Comment:
"""Reddit comment."""
score: int
date: Optional[str]
author: str
excerpt: str
url: str
def to_dict(self) -> Dict[str, Any]:
return {
'score': self.score,
'date': self.date,
'author': self.author,
'excerpt': self.excerpt,
'url': self.url,
}
@dataclass
class SubScores:
"""Component scores."""
relevance: int = 0
recency: int = 0
engagement: int = 0
def to_dict(self) -> Dict[str, int]:
return {
'relevance': self.relevance,
'recency': self.recency,
'engagement': self.engagement,
}
@dataclass
class RedditItem:
"""Normalized Reddit item."""
id: str
title: str
url: str
subreddit: str
date: Optional[str] = None
date_confidence: str = "low"
engagement: Optional[Engagement] = None
top_comments: List[Comment] = field(default_factory=list)
comment_insights: List[str] = field(default_factory=list)
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,
'subreddit': self.subreddit,
'date': self.date,
'date_confidence': self.date_confidence,
'engagement': self.engagement.to_dict() if self.engagement else None,
'top_comments': [c.to_dict() for c in self.top_comments],
'comment_insights': self.comment_insights,
'relevance': self.relevance,
'why_relevant': self.why_relevant,
'subs': self.subs.to_dict(),
'score': self.score,
}
@dataclass
class XItem:
"""Normalized X item."""
id: str
text: str
url: str
author_handle: str
date: Optional[str] = None
date_confidence: str = "low"
engagement: Optional[Engagement] = None
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,
'text': self.text,
'url': self.url,
'author_handle': self.author_handle,
'date': self.date,
'date_confidence': self.date_confidence,
'engagement': self.engagement.to_dict() if self.engagement else None,
'relevance': self.relevance,
'why_relevant': self.why_relevant,
'subs': self.subs.to_dict(),
'score': self.score,
}
@dataclass
class WebSearchItem:
"""Normalized web search item (no engagement metrics)."""
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,
}
@dataclass
class Report:
"""Full research report."""
topic: str
range_from: str
range_to: str
generated_at: str
mode: str # 'reddit-only', 'x-only', 'both', 'web-only', etc.
openai_model_used: Optional[str] = None
xai_model_used: Optional[str] = None
reddit: List[RedditItem] = field(default_factory=list)
x: List[XItem] = field(default_factory=list)
web: List[WebSearchItem] = field(default_factory=list)
best_practices: List[str] = field(default_factory=list)
prompt_pack: List[str] = field(default_factory=list)
context_snippet_md: str = ""
# Status tracking
reddit_error: Optional[str] = None
x_error: Optional[str] = None
web_error: Optional[str] = None
# Cache info
from_cache: bool = False
cache_age_hours: Optional[float] = None
def to_dict(self) -> Dict[str, Any]:
d = {
'topic': self.topic,
'range': {
'from': self.range_from,
'to': self.range_to,
},
'generated_at': self.generated_at,
'mode': self.mode,
'openai_model_used': self.openai_model_used,
'xai_model_used': self.xai_model_used,
'reddit': [r.to_dict() for r in self.reddit],
'x': [x.to_dict() for x in self.x],
'web': [w.to_dict() for w in self.web],
'best_practices': self.best_practices,
'prompt_pack': self.prompt_pack,
'context_snippet_md': self.context_snippet_md,
}
if self.reddit_error:
d['reddit_error'] = self.reddit_error
if self.x_error:
d['x_error'] = self.x_error
if self.web_error:
d['web_error'] = self.web_error
if self.from_cache:
d['from_cache'] = self.from_cache
if self.cache_age_hours is not None:
d['cache_age_hours'] = self.cache_age_hours
return d
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "Report":
"""Create Report from serialized dict (handles cache format)."""
# Handle range field conversion
range_data = data.get('range', {})
range_from = range_data.get('from', data.get('range_from', ''))
range_to = range_data.get('to', data.get('range_to', ''))
# Reconstruct Reddit items
reddit_items = []
for r in data.get('reddit', []):
eng = None
if r.get('engagement'):
eng = Engagement(**r['engagement'])
comments = [Comment(**c) for c in r.get('top_comments', [])]
subs = SubScores(**r.get('subs', {})) if r.get('subs') else SubScores()
reddit_items.append(RedditItem(
id=r['id'],
title=r['title'],
url=r['url'],
subreddit=r['subreddit'],
date=r.get('date'),
date_confidence=r.get('date_confidence', 'low'),
engagement=eng,
top_comments=comments,
comment_insights=r.get('comment_insights', []),
relevance=r.get('relevance', 0.5),
why_relevant=r.get('why_relevant', ''),
subs=subs,
score=r.get('score', 0),
))
# Reconstruct X items
x_items = []
for x in data.get('x', []):
eng = None
if x.get('engagement'):
eng = Engagement(**x['engagement'])
subs = SubScores(**x.get('subs', {})) if x.get('subs') else SubScores()
x_items.append(XItem(
id=x['id'],
text=x['text'],
url=x['url'],
author_handle=x['author_handle'],
date=x.get('date'),
date_confidence=x.get('date_confidence', 'low'),
engagement=eng,
relevance=x.get('relevance', 0.5),
why_relevant=x.get('why_relevant', ''),
subs=subs,
score=x.get('score', 0),
))
# Reconstruct Web items
web_items = []
for w in data.get('web', []):
subs = SubScores(**w.get('subs', {})) if w.get('subs') else SubScores()
web_items.append(WebSearchItem(
id=w['id'],
title=w['title'],
url=w['url'],
source_domain=w.get('source_domain', ''),
snippet=w.get('snippet', ''),
date=w.get('date'),
date_confidence=w.get('date_confidence', 'low'),
relevance=w.get('relevance', 0.5),
why_relevant=w.get('why_relevant', ''),
subs=subs,
score=w.get('score', 0),
))
return cls(
topic=data['topic'],
range_from=range_from,
range_to=range_to,
generated_at=data['generated_at'],
mode=data['mode'],
openai_model_used=data.get('openai_model_used'),
xai_model_used=data.get('xai_model_used'),
reddit=reddit_items,
x=x_items,
web=web_items,
best_practices=data.get('best_practices', []),
prompt_pack=data.get('prompt_pack', []),
context_snippet_md=data.get('context_snippet_md', ''),
reddit_error=data.get('reddit_error'),
x_error=data.get('x_error'),
web_error=data.get('web_error'),
from_cache=data.get('from_cache', False),
cache_age_hours=data.get('cache_age_hours'),
)
def create_report(
topic: str,
from_date: str,
to_date: str,
mode: str,
openai_model: Optional[str] = None,
xai_model: Optional[str] = None,
) -> Report:
"""Create a new report with metadata."""
return Report(
topic=topic,
range_from=from_date,
range_to=to_date,
generated_at=datetime.now(timezone.utc).isoformat(),
mode=mode,
openai_model_used=openai_model,
xai_model_used=xai_model,
)

View File

@@ -0,0 +1,311 @@
"""Popularity-aware scoring for last30days skill."""
import math
from typing import List, Optional, Union
from . import dates, schema
# Score weights for Reddit/X (has engagement)
WEIGHT_RELEVANCE = 0.45
WEIGHT_RECENCY = 0.25
WEIGHT_ENGAGEMENT = 0.30
# WebSearch weights (no engagement, reweighted to 100%)
WEBSEARCH_WEIGHT_RELEVANCE = 0.55
WEBSEARCH_WEIGHT_RECENCY = 0.45
WEBSEARCH_SOURCE_PENALTY = 15 # Points deducted for lacking engagement
# WebSearch date confidence adjustments
WEBSEARCH_VERIFIED_BONUS = 10 # Bonus for URL-verified recent date (high confidence)
WEBSEARCH_NO_DATE_PENALTY = 20 # Heavy penalty for no date signals (low confidence)
# Default engagement score for unknown
DEFAULT_ENGAGEMENT = 35
UNKNOWN_ENGAGEMENT_PENALTY = 10
def log1p_safe(x: Optional[int]) -> float:
"""Safe log1p that handles None and negative values."""
if x is None or x < 0:
return 0.0
return math.log1p(x)
def compute_reddit_engagement_raw(engagement: Optional[schema.Engagement]) -> Optional[float]:
"""Compute raw engagement score for Reddit item.
Formula: 0.55*log1p(score) + 0.40*log1p(num_comments) + 0.05*(upvote_ratio*10)
"""
if engagement is None:
return None
if engagement.score is None and engagement.num_comments is None:
return None
score = log1p_safe(engagement.score)
comments = log1p_safe(engagement.num_comments)
ratio = (engagement.upvote_ratio or 0.5) * 10
return 0.55 * score + 0.40 * comments + 0.05 * ratio
def compute_x_engagement_raw(engagement: Optional[schema.Engagement]) -> Optional[float]:
"""Compute raw engagement score for X item.
Formula: 0.55*log1p(likes) + 0.25*log1p(reposts) + 0.15*log1p(replies) + 0.05*log1p(quotes)
"""
if engagement is None:
return None
if engagement.likes is None and engagement.reposts is None:
return None
likes = log1p_safe(engagement.likes)
reposts = log1p_safe(engagement.reposts)
replies = log1p_safe(engagement.replies)
quotes = log1p_safe(engagement.quotes)
return 0.55 * likes + 0.25 * reposts + 0.15 * replies + 0.05 * quotes
def normalize_to_100(values: List[float], default: float = 50) -> List[float]:
"""Normalize a list of values to 0-100 scale.
Args:
values: Raw values (None values are preserved)
default: Default value for None entries
Returns:
Normalized values
"""
# Filter out None
valid = [v for v in values if v is not None]
if not valid:
return [default if v is None else 50 for v in values]
min_val = min(valid)
max_val = max(valid)
range_val = max_val - min_val
if range_val == 0:
return [50 if v is None else 50 for v in values]
result = []
for v in values:
if v is None:
result.append(None)
else:
normalized = ((v - min_val) / range_val) * 100
result.append(normalized)
return result
def score_reddit_items(items: List[schema.RedditItem]) -> List[schema.RedditItem]:
"""Compute scores for Reddit items.
Args:
items: List of Reddit items
Returns:
Items with updated scores
"""
if not items:
return items
# Compute raw engagement scores
eng_raw = [compute_reddit_engagement_raw(item.engagement) for item in items]
# Normalize engagement to 0-100
eng_normalized = normalize_to_100(eng_raw)
for i, item in enumerate(items):
# Relevance subscore (model-provided, convert to 0-100)
rel_score = int(item.relevance * 100)
# Recency subscore
rec_score = dates.recency_score(item.date)
# Engagement subscore
if eng_normalized[i] is not None:
eng_score = int(eng_normalized[i])
else:
eng_score = DEFAULT_ENGAGEMENT
# Store subscores
item.subs = schema.SubScores(
relevance=rel_score,
recency=rec_score,
engagement=eng_score,
)
# Compute overall score
overall = (
WEIGHT_RELEVANCE * rel_score +
WEIGHT_RECENCY * rec_score +
WEIGHT_ENGAGEMENT * eng_score
)
# Apply penalty for unknown engagement
if eng_raw[i] is None:
overall -= UNKNOWN_ENGAGEMENT_PENALTY
# Apply penalty for low date confidence
if item.date_confidence == "low":
overall -= 10
elif item.date_confidence == "med":
overall -= 5
item.score = max(0, min(100, int(overall)))
return items
def score_x_items(items: List[schema.XItem]) -> List[schema.XItem]:
"""Compute scores for X items.
Args:
items: List of X items
Returns:
Items with updated scores
"""
if not items:
return items
# Compute raw engagement scores
eng_raw = [compute_x_engagement_raw(item.engagement) for item in items]
# Normalize engagement to 0-100
eng_normalized = normalize_to_100(eng_raw)
for i, item in enumerate(items):
# Relevance subscore (model-provided, convert to 0-100)
rel_score = int(item.relevance * 100)
# Recency subscore
rec_score = dates.recency_score(item.date)
# Engagement subscore
if eng_normalized[i] is not None:
eng_score = int(eng_normalized[i])
else:
eng_score = DEFAULT_ENGAGEMENT
# Store subscores
item.subs = schema.SubScores(
relevance=rel_score,
recency=rec_score,
engagement=eng_score,
)
# Compute overall score
overall = (
WEIGHT_RELEVANCE * rel_score +
WEIGHT_RECENCY * rec_score +
WEIGHT_ENGAGEMENT * eng_score
)
# Apply penalty for unknown engagement
if eng_raw[i] is None:
overall -= UNKNOWN_ENGAGEMENT_PENALTY
# Apply penalty for low date confidence
if item.date_confidence == "low":
overall -= 10
elif item.date_confidence == "med":
overall -= 5
item.score = max(0, min(100, int(overall)))
return items
def score_websearch_items(items: List[schema.WebSearchItem]) -> List[schema.WebSearchItem]:
"""Compute scores for WebSearch items WITHOUT engagement metrics.
Uses reweighted formula: 55% relevance + 45% recency - 15pt source penalty.
This ensures WebSearch items rank below comparable Reddit/X items.
Date confidence adjustments:
- High confidence (URL-verified date): +10 bonus
- Med confidence (snippet-extracted date): no change
- Low confidence (no date signals): -20 penalty
Args:
items: List of WebSearch items
Returns:
Items with updated scores
"""
if not items:
return items
for item in items:
# Relevance subscore (model-provided, convert to 0-100)
rel_score = int(item.relevance * 100)
# Recency subscore
rec_score = dates.recency_score(item.date)
# Store subscores (engagement is 0 for WebSearch - no data)
item.subs = schema.SubScores(
relevance=rel_score,
recency=rec_score,
engagement=0, # Explicitly zero - no engagement data available
)
# Compute overall score using WebSearch weights
overall = (
WEBSEARCH_WEIGHT_RELEVANCE * rel_score +
WEBSEARCH_WEIGHT_RECENCY * rec_score
)
# Apply source penalty (WebSearch < Reddit/X for same relevance/recency)
overall -= WEBSEARCH_SOURCE_PENALTY
# Apply date confidence adjustments
# High confidence (URL-verified): reward with bonus
# Med confidence (snippet-extracted): neutral
# Low confidence (no date signals): heavy penalty
if item.date_confidence == "high":
overall += WEBSEARCH_VERIFIED_BONUS # Reward verified recent dates
elif item.date_confidence == "low":
overall -= WEBSEARCH_NO_DATE_PENALTY # Heavy penalty for unknown
item.score = max(0, min(100, int(overall)))
return items
def sort_items(items: List[Union[schema.RedditItem, schema.XItem, schema.WebSearchItem]]) -> List:
"""Sort items by score (descending), then date, then source priority.
Args:
items: List of items to sort
Returns:
Sorted items
"""
def sort_key(item):
# Primary: score descending (negate for descending)
score = -item.score
# Secondary: date descending (recent first)
date = item.date or "0000-00-00"
date_key = -int(date.replace("-", ""))
# Tertiary: source priority (Reddit > X > WebSearch)
if isinstance(item, schema.RedditItem):
source_priority = 0
elif isinstance(item, schema.XItem):
source_priority = 1
else: # WebSearchItem
source_priority = 2
# Quaternary: title/text for stability
text = getattr(item, "title", "") or getattr(item, "text", "")
return (score, date_key, source_priority, text)
return sorted(items, key=sort_key)

View File

@@ -0,0 +1,324 @@
"""Terminal UI utilities for last30days skill."""
import os
import sys
import time
import threading
import random
from typing import Optional
# Check if we're in a real terminal (not captured by Claude Code)
IS_TTY = sys.stderr.isatty()
# ANSI color codes
class Colors:
PURPLE = '\033[95m'
BLUE = '\033[94m'
CYAN = '\033[96m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
DIM = '\033[2m'
RESET = '\033[0m'
BANNER = f"""{Colors.PURPLE}{Colors.BOLD}
██╗ █████╗ ███████╗████████╗██████╗ ██████╗ ██████╗ █████╗ ██╗ ██╗███████╗
██║ ██╔══██╗██╔════╝╚══██╔══╝╚════██╗██╔═████╗██╔══██╗██╔══██╗╚██╗ ██╔╝██╔════╝
██║ ███████║███████╗ ██║ █████╔╝██║██╔██║██║ ██║███████║ ╚████╔╝ ███████╗
██║ ██╔══██║╚════██║ ██║ ╚═══██╗████╔╝██║██║ ██║██╔══██║ ╚██╔╝ ╚════██║
███████╗██║ ██║███████║ ██║ ██████╔╝╚██████╔╝██████╔╝██║ ██║ ██║ ███████║
╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝
{Colors.RESET}{Colors.DIM} 30 days of research. 30 seconds of work.{Colors.RESET}
"""
MINI_BANNER = f"""{Colors.PURPLE}{Colors.BOLD}/last30days{Colors.RESET} {Colors.DIM}· researching...{Colors.RESET}"""
# Fun status messages for each phase
REDDIT_MESSAGES = [
"Diving into Reddit threads...",
"Scanning subreddits for gold...",
"Reading what Redditors are saying...",
"Exploring the front page of the internet...",
"Finding the good discussions...",
"Upvoting mentally...",
"Scrolling through comments...",
]
X_MESSAGES = [
"Checking what X is buzzing about...",
"Reading the timeline...",
"Finding the hot takes...",
"Scanning tweets and threads...",
"Discovering trending insights...",
"Following the conversation...",
"Reading between the posts...",
]
ENRICHING_MESSAGES = [
"Getting the juicy details...",
"Fetching engagement metrics...",
"Reading top comments...",
"Extracting insights...",
"Analyzing discussions...",
]
PROCESSING_MESSAGES = [
"Crunching the data...",
"Scoring and ranking...",
"Finding patterns...",
"Removing duplicates...",
"Organizing findings...",
]
WEB_ONLY_MESSAGES = [
"Searching the web...",
"Finding blogs and docs...",
"Crawling news sites...",
"Discovering tutorials...",
]
# Promo message for users without API keys
PROMO_MESSAGE = f"""
{Colors.YELLOW}{Colors.BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{Colors.RESET}
{Colors.YELLOW}⚡ UNLOCK THE FULL POWER OF /last30days{Colors.RESET}
{Colors.DIM}Right now you're using web search only. Add API keys to unlock:{Colors.RESET}
{Colors.YELLOW}🟠 Reddit{Colors.RESET} - Real upvotes, comments, and community insights
└─ Add OPENAI_API_KEY (uses OpenAI's web_search for Reddit)
{Colors.CYAN}🔵 X (Twitter){Colors.RESET} - Real-time posts, likes, reposts from creators
└─ Add XAI_API_KEY (uses xAI's live X search)
{Colors.DIM}Setup:{Colors.RESET} Edit {Colors.BOLD}~/.config/last30days/.env{Colors.RESET}
{Colors.YELLOW}{Colors.BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{Colors.RESET}
"""
PROMO_MESSAGE_PLAIN = """
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚡ UNLOCK THE FULL POWER OF /last30days
Right now you're using web search only. Add API keys to unlock:
🟠 Reddit - Real upvotes, comments, and community insights
└─ Add OPENAI_API_KEY (uses OpenAI's web_search for Reddit)
🔵 X (Twitter) - Real-time posts, likes, reposts from creators
└─ Add XAI_API_KEY (uses xAI's live X search)
Setup: Edit ~/.config/last30days/.env
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
"""
# Shorter promo for single missing key
PROMO_SINGLE_KEY = {
"reddit": f"""
{Colors.DIM}💡 Tip: Add {Colors.YELLOW}OPENAI_API_KEY{Colors.RESET}{Colors.DIM} to ~/.config/last30days/.env for Reddit data with real engagement metrics!{Colors.RESET}
""",
"x": f"""
{Colors.DIM}💡 Tip: Add {Colors.CYAN}XAI_API_KEY{Colors.RESET}{Colors.DIM} to ~/.config/last30days/.env for X/Twitter data with real likes & reposts!{Colors.RESET}
""",
}
PROMO_SINGLE_KEY_PLAIN = {
"reddit": "\n💡 Tip: Add OPENAI_API_KEY to ~/.config/last30days/.env for Reddit data with real engagement metrics!\n",
"x": "\n💡 Tip: Add XAI_API_KEY to ~/.config/last30days/.env for X/Twitter data with real likes & reposts!\n",
}
# Spinner frames
SPINNER_FRAMES = ['', '', '', '', '', '', '', '', '', '']
DOTS_FRAMES = [' ', '. ', '.. ', '...']
class Spinner:
"""Animated spinner for long-running operations."""
def __init__(self, message: str = "Working", color: str = Colors.CYAN):
self.message = message
self.color = color
self.running = False
self.thread: Optional[threading.Thread] = None
self.frame_idx = 0
self.shown_static = False
def _spin(self):
while self.running:
frame = SPINNER_FRAMES[self.frame_idx % len(SPINNER_FRAMES)]
sys.stderr.write(f"\r{self.color}{frame}{Colors.RESET} {self.message} ")
sys.stderr.flush()
self.frame_idx += 1
time.sleep(0.08)
def start(self):
self.running = True
if IS_TTY:
# Real terminal - animate
self.thread = threading.Thread(target=self._spin, daemon=True)
self.thread.start()
else:
# Not a TTY (Claude Code) - just print once
if not self.shown_static:
sys.stderr.write(f"{self.message}\n")
sys.stderr.flush()
self.shown_static = True
def update(self, message: str):
self.message = message
if not IS_TTY and not self.shown_static:
# Print update in non-TTY mode
sys.stderr.write(f"{message}\n")
sys.stderr.flush()
def stop(self, final_message: str = ""):
self.running = False
if self.thread:
self.thread.join(timeout=0.2)
if IS_TTY:
# Clear the line in real terminal
sys.stderr.write("\r" + " " * 80 + "\r")
if final_message:
sys.stderr.write(f"{final_message}\n")
sys.stderr.flush()
class ProgressDisplay:
"""Progress display for research phases."""
def __init__(self, topic: str, show_banner: bool = True):
self.topic = topic
self.spinner: Optional[Spinner] = None
self.start_time = time.time()
if show_banner:
self._show_banner()
def _show_banner(self):
if IS_TTY:
sys.stderr.write(MINI_BANNER + "\n")
sys.stderr.write(f"{Colors.DIM}Topic: {Colors.RESET}{Colors.BOLD}{self.topic}{Colors.RESET}\n\n")
else:
# Simple text for non-TTY
sys.stderr.write(f"/last30days · researching: {self.topic}\n")
sys.stderr.flush()
def start_reddit(self):
msg = random.choice(REDDIT_MESSAGES)
self.spinner = Spinner(f"{Colors.YELLOW}Reddit{Colors.RESET} {msg}", Colors.YELLOW)
self.spinner.start()
def end_reddit(self, count: int):
if self.spinner:
self.spinner.stop(f"{Colors.YELLOW}Reddit{Colors.RESET} Found {count} threads")
def start_reddit_enrich(self, current: int, total: int):
if self.spinner:
self.spinner.stop()
msg = random.choice(ENRICHING_MESSAGES)
self.spinner = Spinner(f"{Colors.YELLOW}Reddit{Colors.RESET} [{current}/{total}] {msg}", Colors.YELLOW)
self.spinner.start()
def update_reddit_enrich(self, current: int, total: int):
if self.spinner:
msg = random.choice(ENRICHING_MESSAGES)
self.spinner.update(f"{Colors.YELLOW}Reddit{Colors.RESET} [{current}/{total}] {msg}")
def end_reddit_enrich(self):
if self.spinner:
self.spinner.stop(f"{Colors.YELLOW}Reddit{Colors.RESET} Enriched with engagement data")
def start_x(self):
msg = random.choice(X_MESSAGES)
self.spinner = Spinner(f"{Colors.CYAN}X{Colors.RESET} {msg}", Colors.CYAN)
self.spinner.start()
def end_x(self, count: int):
if self.spinner:
self.spinner.stop(f"{Colors.CYAN}X{Colors.RESET} Found {count} posts")
def start_processing(self):
msg = random.choice(PROCESSING_MESSAGES)
self.spinner = Spinner(f"{Colors.PURPLE}Processing{Colors.RESET} {msg}", Colors.PURPLE)
self.spinner.start()
def end_processing(self):
if self.spinner:
self.spinner.stop()
def show_complete(self, reddit_count: int, x_count: int):
elapsed = time.time() - self.start_time
if IS_TTY:
sys.stderr.write(f"\n{Colors.GREEN}{Colors.BOLD}✓ Research complete{Colors.RESET} ")
sys.stderr.write(f"{Colors.DIM}({elapsed:.1f}s){Colors.RESET}\n")
sys.stderr.write(f" {Colors.YELLOW}Reddit:{Colors.RESET} {reddit_count} threads ")
sys.stderr.write(f"{Colors.CYAN}X:{Colors.RESET} {x_count} posts\n\n")
else:
sys.stderr.write(f"✓ Research complete ({elapsed:.1f}s) - Reddit: {reddit_count} threads, X: {x_count} posts\n")
sys.stderr.flush()
def show_cached(self, age_hours: float = None):
if age_hours is not None:
age_str = f" ({age_hours:.1f}h old)"
else:
age_str = ""
sys.stderr.write(f"{Colors.GREEN}{Colors.RESET} {Colors.DIM}Using cached results{age_str} - use --refresh for fresh data{Colors.RESET}\n\n")
sys.stderr.flush()
def show_error(self, message: str):
sys.stderr.write(f"{Colors.RED}✗ Error:{Colors.RESET} {message}\n")
sys.stderr.flush()
def start_web_only(self):
"""Show web-only mode indicator."""
msg = random.choice(WEB_ONLY_MESSAGES)
self.spinner = Spinner(f"{Colors.GREEN}Web{Colors.RESET} {msg}", Colors.GREEN)
self.spinner.start()
def end_web_only(self):
"""End web-only spinner."""
if self.spinner:
self.spinner.stop(f"{Colors.GREEN}Web{Colors.RESET} Claude will search the web")
def show_web_only_complete(self):
"""Show completion for web-only mode."""
elapsed = time.time() - self.start_time
if IS_TTY:
sys.stderr.write(f"\n{Colors.GREEN}{Colors.BOLD}✓ Ready for web search{Colors.RESET} ")
sys.stderr.write(f"{Colors.DIM}({elapsed:.1f}s){Colors.RESET}\n")
sys.stderr.write(f" {Colors.GREEN}Web:{Colors.RESET} Claude will search blogs, docs & news\n\n")
else:
sys.stderr.write(f"✓ Ready for web search ({elapsed:.1f}s)\n")
sys.stderr.flush()
def show_promo(self, missing: str = "both"):
"""Show promotional message for missing API keys.
Args:
missing: 'both', 'reddit', or 'x' - which keys are missing
"""
if missing == "both":
if IS_TTY:
sys.stderr.write(PROMO_MESSAGE)
else:
sys.stderr.write(PROMO_MESSAGE_PLAIN)
elif missing in PROMO_SINGLE_KEY:
if IS_TTY:
sys.stderr.write(PROMO_SINGLE_KEY[missing])
else:
sys.stderr.write(PROMO_SINGLE_KEY_PLAIN[missing])
sys.stderr.flush()
def print_phase(phase: str, message: str):
"""Print a phase message."""
colors = {
"reddit": Colors.YELLOW,
"x": Colors.CYAN,
"process": Colors.PURPLE,
"done": Colors.GREEN,
"error": Colors.RED,
}
color = colors.get(phase, Colors.RESET)
sys.stderr.write(f"{color}{Colors.RESET} {message}\n")
sys.stderr.flush()

View File

@@ -0,0 +1,401 @@
"""WebSearch module for last30days skill.
NOTE: WebSearch uses Claude's built-in WebSearch tool, which runs INSIDE Claude Code.
Unlike Reddit/X which use external APIs, WebSearch results are obtained by Claude
directly and passed to this module for normalization and scoring.
The typical flow is:
1. Claude invokes WebSearch tool with the topic
2. Claude passes results to parse_websearch_results()
3. Results are normalized into WebSearchItem objects
"""
import re
from datetime import datetime, timedelta
from typing import Any, Dict, List, Optional, Tuple
from urllib.parse import urlparse
from . import schema
# Month name mappings for date parsing
MONTH_MAP = {
"jan": 1, "january": 1,
"feb": 2, "february": 2,
"mar": 3, "march": 3,
"apr": 4, "april": 4,
"may": 5,
"jun": 6, "june": 6,
"jul": 7, "july": 7,
"aug": 8, "august": 8,
"sep": 9, "sept": 9, "september": 9,
"oct": 10, "october": 10,
"nov": 11, "november": 11,
"dec": 12, "december": 12,
}
def extract_date_from_url(url: str) -> Optional[str]:
"""Try to extract a date from URL path.
Many sites embed dates in URLs like:
- /2026/01/24/article-title
- /2026-01-24/article
- /blog/20260124/title
Args:
url: URL to parse
Returns:
Date string in YYYY-MM-DD format, or None
"""
# Pattern 1: /YYYY/MM/DD/ (most common)
match = re.search(r'/(\d{4})/(\d{2})/(\d{2})/', url)
if match:
year, month, day = match.groups()
if 2020 <= int(year) <= 2030 and 1 <= int(month) <= 12 and 1 <= int(day) <= 31:
return f"{year}-{month}-{day}"
# Pattern 2: /YYYY-MM-DD/ or /YYYY-MM-DD-
match = re.search(r'/(\d{4})-(\d{2})-(\d{2})[-/]', url)
if match:
year, month, day = match.groups()
if 2020 <= int(year) <= 2030 and 1 <= int(month) <= 12 and 1 <= int(day) <= 31:
return f"{year}-{month}-{day}"
# Pattern 3: /YYYYMMDD/ (compact)
match = re.search(r'/(\d{4})(\d{2})(\d{2})/', url)
if match:
year, month, day = match.groups()
if 2020 <= int(year) <= 2030 and 1 <= int(month) <= 12 and 1 <= int(day) <= 31:
return f"{year}-{month}-{day}"
return None
def extract_date_from_snippet(text: str) -> Optional[str]:
"""Try to extract a date from text snippet or title.
Looks for patterns like:
- January 24, 2026 or Jan 24, 2026
- 24 January 2026
- 2026-01-24
- "3 days ago", "yesterday", "last week"
Args:
text: Text to parse
Returns:
Date string in YYYY-MM-DD format, or None
"""
if not text:
return None
text_lower = text.lower()
# Pattern 1: Month DD, YYYY (e.g., "January 24, 2026")
match = re.search(
r'\b(jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|jun(?:e)?|'
r'jul(?:y)?|aug(?:ust)?|sep(?:t(?:ember)?)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)'
r'\s+(\d{1,2})(?:st|nd|rd|th)?,?\s*(\d{4})\b',
text_lower
)
if match:
month_str, day, year = match.groups()
month = MONTH_MAP.get(month_str[:3])
if month and 2020 <= int(year) <= 2030 and 1 <= int(day) <= 31:
return f"{year}-{month:02d}-{int(day):02d}"
# Pattern 2: DD Month YYYY (e.g., "24 January 2026")
match = re.search(
r'\b(\d{1,2})(?:st|nd|rd|th)?\s+'
r'(jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|jun(?:e)?|'
r'jul(?:y)?|aug(?:ust)?|sep(?:t(?:ember)?)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)'
r'\s+(\d{4})\b',
text_lower
)
if match:
day, month_str, year = match.groups()
month = MONTH_MAP.get(month_str[:3])
if month and 2020 <= int(year) <= 2030 and 1 <= int(day) <= 31:
return f"{year}-{month:02d}-{int(day):02d}"
# Pattern 3: YYYY-MM-DD (ISO format)
match = re.search(r'\b(\d{4})-(\d{2})-(\d{2})\b', text)
if match:
year, month, day = match.groups()
if 2020 <= int(year) <= 2030 and 1 <= int(month) <= 12 and 1 <= int(day) <= 31:
return f"{year}-{month}-{day}"
# Pattern 4: Relative dates ("3 days ago", "yesterday", etc.)
today = datetime.now()
if "yesterday" in text_lower:
date = today - timedelta(days=1)
return date.strftime("%Y-%m-%d")
if "today" in text_lower:
return today.strftime("%Y-%m-%d")
# "N days ago"
match = re.search(r'\b(\d+)\s*days?\s*ago\b', text_lower)
if match:
days = int(match.group(1))
if days <= 60: # Reasonable range
date = today - timedelta(days=days)
return date.strftime("%Y-%m-%d")
# "N hours ago" -> today
match = re.search(r'\b(\d+)\s*hours?\s*ago\b', text_lower)
if match:
return today.strftime("%Y-%m-%d")
# "last week" -> ~7 days ago
if "last week" in text_lower:
date = today - timedelta(days=7)
return date.strftime("%Y-%m-%d")
# "this week" -> ~3 days ago (middle of week)
if "this week" in text_lower:
date = today - timedelta(days=3)
return date.strftime("%Y-%m-%d")
return None
def extract_date_signals(
url: str,
snippet: str,
title: str,
) -> Tuple[Optional[str], str]:
"""Extract date from any available signal.
Tries URL first (most reliable), then snippet, then title.
Args:
url: Page URL
snippet: Page snippet/description
title: Page title
Returns:
Tuple of (date_string, confidence)
- date from URL: 'high' confidence
- date from snippet/title: '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"
# Domains to exclude (Reddit and X are handled separately)
EXCLUDED_DOMAINS = {
"reddit.com",
"www.reddit.com",
"old.reddit.com",
"twitter.com",
"www.twitter.com",
"x.com",
"www.x.com",
"mobile.twitter.com",
}
def extract_domain(url: str) -> str:
"""Extract the domain from a URL.
Args:
url: Full URL
Returns:
Domain string (e.g., "medium.com")
"""
try:
parsed = urlparse(url)
domain = parsed.netloc.lower()
# Remove www. prefix for cleaner display
if domain.startswith("www."):
domain = domain[4:]
return domain
except Exception:
return ""
def is_excluded_domain(url: str) -> bool:
"""Check if URL is from an excluded domain (Reddit/X).
Args:
url: URL to check
Returns:
True if URL should be excluded
"""
try:
parsed = urlparse(url)
domain = parsed.netloc.lower()
return domain in EXCLUDED_DOMAINS
except Exception:
return False
def parse_websearch_results(
results: List[Dict[str, Any]],
topic: str,
from_date: str = "",
to_date: str = "",
) -> List[Dict[str, Any]]:
"""Parse WebSearch results into normalized format.
This function expects results from Claude's WebSearch tool.
Each result should have: title, url, snippet, and optionally date/relevance.
Uses "Date Detective" approach:
1. Extract dates from URLs (high confidence)
2. Extract dates from snippets/titles (med confidence)
3. Hard filter: exclude items with verified old dates
4. Keep items with no date signals (with low confidence penalty)
Args:
results: List of WebSearch result dicts
topic: Original search topic (for context)
from_date: Start date for filtering (YYYY-MM-DD)
to_date: End date for filtering (YYYY-MM-DD)
Returns:
List of normalized item dicts ready for WebSearchItem creation
"""
items = []
for i, result in enumerate(results):
if not isinstance(result, dict):
continue
url = result.get("url", "")
if not url:
continue
# Skip Reddit/X URLs (handled separately)
if is_excluded_domain(url):
continue
title = str(result.get("title", "")).strip()
snippet = str(result.get("snippet", result.get("description", ""))).strip()
if not title and not snippet:
continue
# Use Date Detective to extract date signals
date = result.get("date") # Use provided date if available
date_confidence = "low"
if date and re.match(r'^\d{4}-\d{2}-\d{2}$', str(date)):
# Provided date is valid
date_confidence = "med"
else:
# Try to extract date from URL/snippet/title
extracted_date, confidence = extract_date_signals(url, snippet, title)
if extracted_date:
date = extracted_date
date_confidence = confidence
# Hard filter: if we found a date and it's too old, skip
if date and from_date and date < from_date:
continue # DROP - verified old content
# Hard filter: if date is in the future, skip (parsing error)
if date and to_date and date > to_date:
continue # DROP - future date
# Get relevance if provided, default to 0.5
relevance = result.get("relevance", 0.5)
try:
relevance = min(1.0, max(0.0, float(relevance)))
except (TypeError, ValueError):
relevance = 0.5
item = {
"id": f"W{i+1}",
"title": title[:200], # Truncate long titles
"url": url,
"source_domain": extract_domain(url),
"snippet": snippet[:500], # Truncate long snippets
"date": date,
"date_confidence": date_confidence,
"relevance": relevance,
"why_relevant": str(result.get("why_relevant", "")).strip(),
}
items.append(item)
return items
def normalize_websearch_items(
items: List[Dict[str, Any]],
from_date: str,
to_date: str,
) -> List[schema.WebSearchItem]:
"""Convert parsed dicts to WebSearchItem objects.
Args:
items: List of parsed item dicts
from_date: Start of date range (YYYY-MM-DD)
to_date: End of date range (YYYY-MM-DD)
Returns:
List of WebSearchItem objects
"""
result = []
for item in items:
web_item = schema.WebSearchItem(
id=item["id"],
title=item["title"],
url=item["url"],
source_domain=item["source_domain"],
snippet=item["snippet"],
date=item.get("date"),
date_confidence=item.get("date_confidence", "low"),
relevance=item.get("relevance", 0.5),
why_relevant=item.get("why_relevant", ""),
)
result.append(web_item)
return result
def dedupe_websearch(items: List[schema.WebSearchItem]) -> List[schema.WebSearchItem]:
"""Remove duplicate WebSearch items.
Deduplication is based on URL.
Args:
items: List of WebSearchItem objects
Returns:
Deduplicated list
"""
seen_urls = set()
result = []
for item in items:
# Normalize URL for comparison
url_key = item.url.lower().rstrip("/")
if url_key not in seen_urls:
seen_urls.add(url_key)
result.append(item)
return result

View File

@@ -0,0 +1,217 @@
"""xAI API client for X (Twitter) 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"[X ERROR] {msg}\n")
sys.stderr.flush()
# xAI uses responses endpoint with Agent Tools API
XAI_RESPONSES_URL = "https://api.x.ai/v1/responses"
# Depth configurations: (min, max) posts to request
DEPTH_CONFIG = {
"quick": (8, 12),
"default": (20, 30),
"deep": (40, 60),
}
X_SEARCH_PROMPT = """You have access to real-time X (Twitter) data. Search for posts about: {topic}
Focus on posts from {from_date} to {to_date}. Find {min_items}-{max_items} high-quality, relevant posts.
IMPORTANT: Return ONLY valid JSON in this exact format, no other text:
{{
"items": [
{{
"text": "Post text content (truncated if long)",
"url": "https://x.com/user/status/...",
"author_handle": "username",
"date": "YYYY-MM-DD or null if unknown",
"engagement": {{
"likes": 100,
"reposts": 25,
"replies": 15,
"quotes": 5
}},
"why_relevant": "Brief explanation of relevance",
"relevance": 0.85
}}
]
}}
Rules:
- relevance is 0.0 to 1.0 (1.0 = highly relevant)
- date must be YYYY-MM-DD format or null
- engagement can be null if unknown
- Include diverse voices/accounts if applicable
- Prefer posts with substantive content, not just links"""
def search_x(
api_key: str,
model: str,
topic: str,
from_date: str,
to_date: str,
depth: str = "default",
mock_response: Optional[Dict] = None,
) -> Dict[str, Any]:
"""Search X for relevant posts using xAI API with live search.
Args:
api_key: xAI API key
model: Model to use
topic: Search topic
from_date: Start date (YYYY-MM-DD)
to_date: End date (YYYY-MM-DD)
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 API response time)
timeout = 90 if depth == "quick" else 120 if depth == "default" else 180
# Use Agent Tools API with x_search tool
payload = {
"model": model,
"tools": [
{"type": "x_search"}
],
"input": [
{
"role": "user",
"content": X_SEARCH_PROMPT.format(
topic=topic,
from_date=from_date,
to_date=to_date,
min_items=min_items,
max_items=max_items,
),
}
],
}
return http.post(XAI_RESPONSES_URL, payload, headers=headers, timeout=timeout)
def parse_x_response(response: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Parse xAI response to extract X 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"xAI 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:
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:
continue
# Parse engagement
engagement = None
eng_raw = item.get("engagement")
if isinstance(eng_raw, dict):
engagement = {
"likes": int(eng_raw.get("likes", 0)) if eng_raw.get("likes") else None,
"reposts": int(eng_raw.get("reposts", 0)) if eng_raw.get("reposts") else None,
"replies": int(eng_raw.get("replies", 0)) if eng_raw.get("replies") else None,
"quotes": int(eng_raw.get("quotes", 0)) if eng_raw.get("quotes") else None,
}
clean_item = {
"id": f"X{i+1}",
"text": str(item.get("text", "")).strip()[:500], # Truncate long text
"url": url,
"author_handle": str(item.get("author_handle", "")).strip().lstrip("@"),
"date": item.get("date"),
"engagement": engagement,
"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

View File

@@ -0,0 +1 @@
# last30days tests

View File

@@ -0,0 +1,59 @@
"""Tests for cache module."""
import sys
import unittest
from pathlib import Path
# Add lib to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from lib import cache
class TestGetCacheKey(unittest.TestCase):
def test_returns_string(self):
result = cache.get_cache_key("test topic", "2026-01-01", "2026-01-31", "both")
self.assertIsInstance(result, str)
def test_consistent_for_same_inputs(self):
key1 = cache.get_cache_key("test topic", "2026-01-01", "2026-01-31", "both")
key2 = cache.get_cache_key("test topic", "2026-01-01", "2026-01-31", "both")
self.assertEqual(key1, key2)
def test_different_for_different_inputs(self):
key1 = cache.get_cache_key("topic a", "2026-01-01", "2026-01-31", "both")
key2 = cache.get_cache_key("topic b", "2026-01-01", "2026-01-31", "both")
self.assertNotEqual(key1, key2)
def test_key_length(self):
key = cache.get_cache_key("test", "2026-01-01", "2026-01-31", "both")
self.assertEqual(len(key), 16)
class TestCachePath(unittest.TestCase):
def test_returns_path(self):
result = cache.get_cache_path("abc123")
self.assertIsInstance(result, Path)
def test_has_json_extension(self):
result = cache.get_cache_path("abc123")
self.assertEqual(result.suffix, ".json")
class TestCacheValidity(unittest.TestCase):
def test_nonexistent_file_is_invalid(self):
fake_path = Path("/nonexistent/path/file.json")
result = cache.is_cache_valid(fake_path)
self.assertFalse(result)
class TestModelCache(unittest.TestCase):
def test_get_cached_model_returns_none_for_missing(self):
# Clear any existing cache first
result = cache.get_cached_model("nonexistent_provider")
# May be None or a cached value, but should not error
self.assertTrue(result is None or isinstance(result, str))
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,114 @@
"""Tests for dates module."""
import sys
import unittest
from datetime import datetime, timedelta, timezone
from pathlib import Path
# Add lib to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from lib import dates
class TestGetDateRange(unittest.TestCase):
def test_returns_tuple_of_two_strings(self):
from_date, to_date = dates.get_date_range(30)
self.assertIsInstance(from_date, str)
self.assertIsInstance(to_date, str)
def test_date_format(self):
from_date, to_date = dates.get_date_range(30)
# Should be YYYY-MM-DD format
self.assertRegex(from_date, r'^\d{4}-\d{2}-\d{2}$')
self.assertRegex(to_date, r'^\d{4}-\d{2}-\d{2}$')
def test_range_is_correct_days(self):
from_date, to_date = dates.get_date_range(30)
start = datetime.strptime(from_date, "%Y-%m-%d")
end = datetime.strptime(to_date, "%Y-%m-%d")
delta = end - start
self.assertEqual(delta.days, 30)
class TestParseDate(unittest.TestCase):
def test_parse_iso_date(self):
result = dates.parse_date("2026-01-15")
self.assertIsNotNone(result)
self.assertEqual(result.year, 2026)
self.assertEqual(result.month, 1)
self.assertEqual(result.day, 15)
def test_parse_timestamp(self):
# Unix timestamp for 2026-01-15 00:00:00 UTC
result = dates.parse_date("1768435200")
self.assertIsNotNone(result)
def test_parse_none(self):
result = dates.parse_date(None)
self.assertIsNone(result)
def test_parse_empty_string(self):
result = dates.parse_date("")
self.assertIsNone(result)
class TestTimestampToDate(unittest.TestCase):
def test_valid_timestamp(self):
# 2026-01-15 00:00:00 UTC
result = dates.timestamp_to_date(1768435200)
self.assertEqual(result, "2026-01-15")
def test_none_timestamp(self):
result = dates.timestamp_to_date(None)
self.assertIsNone(result)
class TestGetDateConfidence(unittest.TestCase):
def test_high_confidence_in_range(self):
result = dates.get_date_confidence("2026-01-15", "2026-01-01", "2026-01-31")
self.assertEqual(result, "high")
def test_low_confidence_before_range(self):
result = dates.get_date_confidence("2025-12-15", "2026-01-01", "2026-01-31")
self.assertEqual(result, "low")
def test_low_confidence_no_date(self):
result = dates.get_date_confidence(None, "2026-01-01", "2026-01-31")
self.assertEqual(result, "low")
class TestDaysAgo(unittest.TestCase):
def test_today(self):
today = datetime.now(timezone.utc).date().isoformat()
result = dates.days_ago(today)
self.assertEqual(result, 0)
def test_none_date(self):
result = dates.days_ago(None)
self.assertIsNone(result)
class TestRecencyScore(unittest.TestCase):
def test_today_is_100(self):
today = datetime.now(timezone.utc).date().isoformat()
result = dates.recency_score(today)
self.assertEqual(result, 100)
def test_30_days_ago_is_0(self):
old_date = (datetime.now(timezone.utc).date() - timedelta(days=30)).isoformat()
result = dates.recency_score(old_date)
self.assertEqual(result, 0)
def test_15_days_ago_is_50(self):
mid_date = (datetime.now(timezone.utc).date() - timedelta(days=15)).isoformat()
result = dates.recency_score(mid_date)
self.assertEqual(result, 50)
def test_none_date_is_0(self):
result = dates.recency_score(None)
self.assertEqual(result, 0)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,111 @@
"""Tests for dedupe module."""
import sys
import unittest
from pathlib import Path
# Add lib to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from lib import dedupe, schema
class TestNormalizeText(unittest.TestCase):
def test_lowercase(self):
result = dedupe.normalize_text("HELLO World")
self.assertEqual(result, "hello world")
def test_removes_punctuation(self):
result = dedupe.normalize_text("Hello, World!")
# Punctuation replaced with space, then whitespace collapsed
self.assertEqual(result, "hello world")
def test_collapses_whitespace(self):
result = dedupe.normalize_text("hello world")
self.assertEqual(result, "hello world")
class TestGetNgrams(unittest.TestCase):
def test_short_text(self):
result = dedupe.get_ngrams("ab", n=3)
self.assertEqual(result, {"ab"})
def test_normal_text(self):
result = dedupe.get_ngrams("hello", n=3)
self.assertIn("hel", result)
self.assertIn("ell", result)
self.assertIn("llo", result)
class TestJaccardSimilarity(unittest.TestCase):
def test_identical_sets(self):
set1 = {"a", "b", "c"}
result = dedupe.jaccard_similarity(set1, set1)
self.assertEqual(result, 1.0)
def test_disjoint_sets(self):
set1 = {"a", "b", "c"}
set2 = {"d", "e", "f"}
result = dedupe.jaccard_similarity(set1, set2)
self.assertEqual(result, 0.0)
def test_partial_overlap(self):
set1 = {"a", "b", "c"}
set2 = {"b", "c", "d"}
result = dedupe.jaccard_similarity(set1, set2)
self.assertEqual(result, 0.5) # 2 overlap / 4 union
def test_empty_sets(self):
result = dedupe.jaccard_similarity(set(), set())
self.assertEqual(result, 0.0)
class TestFindDuplicates(unittest.TestCase):
def test_no_duplicates(self):
items = [
schema.RedditItem(id="R1", title="Completely different topic A", url="", subreddit=""),
schema.RedditItem(id="R2", title="Another unrelated subject B", url="", subreddit=""),
]
result = dedupe.find_duplicates(items)
self.assertEqual(result, [])
def test_finds_duplicates(self):
items = [
schema.RedditItem(id="R1", title="Best practices for Claude Code skills", url="", subreddit=""),
schema.RedditItem(id="R2", title="Best practices for Claude Code skills guide", url="", subreddit=""),
]
result = dedupe.find_duplicates(items, threshold=0.7)
self.assertEqual(len(result), 1)
self.assertEqual(result[0], (0, 1))
class TestDedupeItems(unittest.TestCase):
def test_keeps_higher_scored(self):
items = [
schema.RedditItem(id="R1", title="Best practices for skills", url="", subreddit="", score=90),
schema.RedditItem(id="R2", title="Best practices for skills guide", url="", subreddit="", score=50),
]
result = dedupe.dedupe_items(items, threshold=0.6)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].id, "R1")
def test_keeps_all_unique(self):
items = [
schema.RedditItem(id="R1", title="Topic about apples", url="", subreddit="", score=90),
schema.RedditItem(id="R2", title="Discussion of oranges", url="", subreddit="", score=50),
]
result = dedupe.dedupe_items(items)
self.assertEqual(len(result), 2)
def test_empty_list(self):
result = dedupe.dedupe_items([])
self.assertEqual(result, [])
def test_single_item(self):
items = [schema.RedditItem(id="R1", title="Test", url="", subreddit="")]
result = dedupe.dedupe_items(items)
self.assertEqual(len(result), 1)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,135 @@
"""Tests for models module."""
import sys
import unittest
from pathlib import Path
# Add lib to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from lib import models
class TestParseVersion(unittest.TestCase):
def test_simple_version(self):
result = models.parse_version("gpt-5")
self.assertEqual(result, (5,))
def test_minor_version(self):
result = models.parse_version("gpt-5.2")
self.assertEqual(result, (5, 2))
def test_patch_version(self):
result = models.parse_version("gpt-5.2.1")
self.assertEqual(result, (5, 2, 1))
def test_no_version(self):
result = models.parse_version("custom-model")
self.assertIsNone(result)
class TestIsMainlineOpenAIModel(unittest.TestCase):
def test_gpt5_is_mainline(self):
self.assertTrue(models.is_mainline_openai_model("gpt-5"))
def test_gpt52_is_mainline(self):
self.assertTrue(models.is_mainline_openai_model("gpt-5.2"))
def test_gpt5_mini_is_not_mainline(self):
self.assertFalse(models.is_mainline_openai_model("gpt-5-mini"))
def test_gpt4_is_not_mainline(self):
self.assertFalse(models.is_mainline_openai_model("gpt-4"))
class TestSelectOpenAIModel(unittest.TestCase):
def test_pinned_policy(self):
result = models.select_openai_model(
"fake-key",
policy="pinned",
pin="gpt-5.1"
)
self.assertEqual(result, "gpt-5.1")
def test_auto_with_mock_models(self):
mock_models = [
{"id": "gpt-5.2", "created": 1704067200},
{"id": "gpt-5.1", "created": 1701388800},
{"id": "gpt-5", "created": 1698710400},
]
result = models.select_openai_model(
"fake-key",
policy="auto",
mock_models=mock_models
)
self.assertEqual(result, "gpt-5.2")
def test_auto_filters_variants(self):
mock_models = [
{"id": "gpt-5.2", "created": 1704067200},
{"id": "gpt-5-mini", "created": 1704067200},
{"id": "gpt-5.1", "created": 1701388800},
]
result = models.select_openai_model(
"fake-key",
policy="auto",
mock_models=mock_models
)
self.assertEqual(result, "gpt-5.2")
class TestSelectXAIModel(unittest.TestCase):
def test_latest_policy(self):
result = models.select_xai_model(
"fake-key",
policy="latest"
)
self.assertEqual(result, "grok-4-latest")
def test_stable_policy(self):
# Clear cache first to avoid interference
from lib import cache
cache.MODEL_CACHE_FILE.unlink(missing_ok=True)
result = models.select_xai_model(
"fake-key",
policy="stable"
)
self.assertEqual(result, "grok-4")
def test_pinned_policy(self):
result = models.select_xai_model(
"fake-key",
policy="pinned",
pin="grok-3"
)
self.assertEqual(result, "grok-3")
class TestGetModels(unittest.TestCase):
def test_no_keys_returns_none(self):
config = {}
result = models.get_models(config)
self.assertIsNone(result["openai"])
self.assertIsNone(result["xai"])
def test_openai_key_only(self):
config = {"OPENAI_API_KEY": "sk-test"}
mock_models = [{"id": "gpt-5.2", "created": 1704067200}]
result = models.get_models(config, mock_openai_models=mock_models)
self.assertEqual(result["openai"], "gpt-5.2")
self.assertIsNone(result["xai"])
def test_both_keys(self):
config = {
"OPENAI_API_KEY": "sk-test",
"XAI_API_KEY": "xai-test",
}
mock_openai = [{"id": "gpt-5.2", "created": 1704067200}]
mock_xai = [{"id": "grok-4-latest", "created": 1704067200}]
result = models.get_models(config, mock_openai, mock_xai)
self.assertEqual(result["openai"], "gpt-5.2")
self.assertEqual(result["xai"], "grok-4-latest")
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,138 @@
"""Tests for normalize module."""
import sys
import unittest
from pathlib import Path
# Add lib to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from lib import normalize, schema
class TestNormalizeRedditItems(unittest.TestCase):
def test_normalizes_basic_item(self):
items = [
{
"id": "R1",
"title": "Test Thread",
"url": "https://reddit.com/r/test/1",
"subreddit": "test",
"date": "2026-01-15",
"why_relevant": "Relevant because...",
"relevance": 0.85,
}
]
result = normalize.normalize_reddit_items(items, "2026-01-01", "2026-01-31")
self.assertEqual(len(result), 1)
self.assertIsInstance(result[0], schema.RedditItem)
self.assertEqual(result[0].id, "R1")
self.assertEqual(result[0].title, "Test Thread")
self.assertEqual(result[0].date_confidence, "high")
def test_sets_low_confidence_for_old_date(self):
items = [
{
"id": "R1",
"title": "Old Thread",
"url": "https://reddit.com/r/test/1",
"subreddit": "test",
"date": "2025-12-01", # Before range
"relevance": 0.5,
}
]
result = normalize.normalize_reddit_items(items, "2026-01-01", "2026-01-31")
self.assertEqual(result[0].date_confidence, "low")
def test_handles_engagement(self):
items = [
{
"id": "R1",
"title": "Thread with engagement",
"url": "https://reddit.com/r/test/1",
"subreddit": "test",
"engagement": {
"score": 100,
"num_comments": 50,
"upvote_ratio": 0.9,
},
"relevance": 0.5,
}
]
result = normalize.normalize_reddit_items(items, "2026-01-01", "2026-01-31")
self.assertIsNotNone(result[0].engagement)
self.assertEqual(result[0].engagement.score, 100)
self.assertEqual(result[0].engagement.num_comments, 50)
class TestNormalizeXItems(unittest.TestCase):
def test_normalizes_basic_item(self):
items = [
{
"id": "X1",
"text": "Test post content",
"url": "https://x.com/user/status/123",
"author_handle": "testuser",
"date": "2026-01-15",
"why_relevant": "Relevant because...",
"relevance": 0.9,
}
]
result = normalize.normalize_x_items(items, "2026-01-01", "2026-01-31")
self.assertEqual(len(result), 1)
self.assertIsInstance(result[0], schema.XItem)
self.assertEqual(result[0].id, "X1")
self.assertEqual(result[0].author_handle, "testuser")
def test_handles_x_engagement(self):
items = [
{
"id": "X1",
"text": "Post with engagement",
"url": "https://x.com/user/status/123",
"author_handle": "user",
"engagement": {
"likes": 100,
"reposts": 25,
"replies": 15,
"quotes": 5,
},
"relevance": 0.5,
}
]
result = normalize.normalize_x_items(items, "2026-01-01", "2026-01-31")
self.assertIsNotNone(result[0].engagement)
self.assertEqual(result[0].engagement.likes, 100)
self.assertEqual(result[0].engagement.reposts, 25)
class TestItemsToDicts(unittest.TestCase):
def test_converts_items(self):
items = [
schema.RedditItem(
id="R1",
title="Test",
url="https://reddit.com/r/test/1",
subreddit="test",
)
]
result = normalize.items_to_dicts(items)
self.assertEqual(len(result), 1)
self.assertIsInstance(result[0], dict)
self.assertEqual(result[0]["id"], "R1")
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,116 @@
"""Tests for render module."""
import sys
import unittest
from pathlib import Path
# Add lib to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from lib import render, schema
class TestRenderCompact(unittest.TestCase):
def test_renders_basic_report(self):
report = schema.Report(
topic="test topic",
range_from="2026-01-01",
range_to="2026-01-31",
generated_at="2026-01-31T12:00:00Z",
mode="both",
openai_model_used="gpt-5.2",
xai_model_used="grok-4-latest",
)
result = render.render_compact(report)
self.assertIn("test topic", result)
self.assertIn("2026-01-01", result)
self.assertIn("both", result)
self.assertIn("gpt-5.2", result)
def test_renders_reddit_items(self):
report = schema.Report(
topic="test",
range_from="2026-01-01",
range_to="2026-01-31",
generated_at="2026-01-31T12:00:00Z",
mode="reddit-only",
reddit=[
schema.RedditItem(
id="R1",
title="Test Thread",
url="https://reddit.com/r/test/1",
subreddit="test",
date="2026-01-15",
date_confidence="high",
score=85,
why_relevant="Very relevant",
)
],
)
result = render.render_compact(report)
self.assertIn("R1", result)
self.assertIn("Test Thread", result)
self.assertIn("r/test", result)
def test_shows_coverage_tip_for_reddit_only(self):
report = schema.Report(
topic="test",
range_from="2026-01-01",
range_to="2026-01-31",
generated_at="2026-01-31T12:00:00Z",
mode="reddit-only",
)
result = render.render_compact(report)
self.assertIn("xAI key", result)
class TestRenderContextSnippet(unittest.TestCase):
def test_renders_snippet(self):
report = schema.Report(
topic="Claude Code Skills",
range_from="2026-01-01",
range_to="2026-01-31",
generated_at="2026-01-31T12:00:00Z",
mode="both",
)
result = render.render_context_snippet(report)
self.assertIn("Claude Code Skills", result)
self.assertIn("Last 30 Days", result)
class TestRenderFullReport(unittest.TestCase):
def test_renders_full_report(self):
report = schema.Report(
topic="test topic",
range_from="2026-01-01",
range_to="2026-01-31",
generated_at="2026-01-31T12:00:00Z",
mode="both",
openai_model_used="gpt-5.2",
xai_model_used="grok-4-latest",
)
result = render.render_full_report(report)
self.assertIn("# test topic", result)
self.assertIn("## Models Used", result)
self.assertIn("gpt-5.2", result)
class TestGetContextPath(unittest.TestCase):
def test_returns_path_string(self):
result = render.get_context_path()
self.assertIsInstance(result, str)
self.assertIn("last30days.context.md", result)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,168 @@
"""Tests for score module."""
import sys
import unittest
from datetime import datetime, timezone
from pathlib import Path
# Add lib to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from lib import schema, score
class TestLog1pSafe(unittest.TestCase):
def test_positive_value(self):
result = score.log1p_safe(100)
self.assertGreater(result, 0)
def test_zero(self):
result = score.log1p_safe(0)
self.assertEqual(result, 0)
def test_none(self):
result = score.log1p_safe(None)
self.assertEqual(result, 0)
def test_negative(self):
result = score.log1p_safe(-5)
self.assertEqual(result, 0)
class TestComputeRedditEngagementRaw(unittest.TestCase):
def test_with_engagement(self):
eng = schema.Engagement(score=100, num_comments=50, upvote_ratio=0.9)
result = score.compute_reddit_engagement_raw(eng)
self.assertIsNotNone(result)
self.assertGreater(result, 0)
def test_without_engagement(self):
result = score.compute_reddit_engagement_raw(None)
self.assertIsNone(result)
def test_empty_engagement(self):
eng = schema.Engagement()
result = score.compute_reddit_engagement_raw(eng)
self.assertIsNone(result)
class TestComputeXEngagementRaw(unittest.TestCase):
def test_with_engagement(self):
eng = schema.Engagement(likes=100, reposts=25, replies=15, quotes=5)
result = score.compute_x_engagement_raw(eng)
self.assertIsNotNone(result)
self.assertGreater(result, 0)
def test_without_engagement(self):
result = score.compute_x_engagement_raw(None)
self.assertIsNone(result)
class TestNormalizeTo100(unittest.TestCase):
def test_normalizes_values(self):
values = [0, 50, 100]
result = score.normalize_to_100(values)
self.assertEqual(result[0], 0)
self.assertEqual(result[1], 50)
self.assertEqual(result[2], 100)
def test_handles_none(self):
values = [0, None, 100]
result = score.normalize_to_100(values)
self.assertIsNone(result[1])
def test_single_value(self):
values = [50]
result = score.normalize_to_100(values)
self.assertEqual(result[0], 50)
class TestScoreRedditItems(unittest.TestCase):
def test_scores_items(self):
today = datetime.now(timezone.utc).date().isoformat()
items = [
schema.RedditItem(
id="R1",
title="Test",
url="https://reddit.com/r/test/1",
subreddit="test",
date=today,
date_confidence="high",
engagement=schema.Engagement(score=100, num_comments=50, upvote_ratio=0.9),
relevance=0.9,
),
schema.RedditItem(
id="R2",
title="Test 2",
url="https://reddit.com/r/test/2",
subreddit="test",
date=today,
date_confidence="high",
engagement=schema.Engagement(score=10, num_comments=5, upvote_ratio=0.8),
relevance=0.5,
),
]
result = score.score_reddit_items(items)
self.assertEqual(len(result), 2)
self.assertGreater(result[0].score, 0)
self.assertGreater(result[1].score, 0)
# Higher relevance and engagement should score higher
self.assertGreater(result[0].score, result[1].score)
def test_empty_list(self):
result = score.score_reddit_items([])
self.assertEqual(result, [])
class TestScoreXItems(unittest.TestCase):
def test_scores_items(self):
today = datetime.now(timezone.utc).date().isoformat()
items = [
schema.XItem(
id="X1",
text="Test post",
url="https://x.com/user/1",
author_handle="user1",
date=today,
date_confidence="high",
engagement=schema.Engagement(likes=100, reposts=25, replies=15, quotes=5),
relevance=0.9,
),
]
result = score.score_x_items(items)
self.assertEqual(len(result), 1)
self.assertGreater(result[0].score, 0)
class TestSortItems(unittest.TestCase):
def test_sorts_by_score_descending(self):
items = [
schema.RedditItem(id="R1", title="Low", url="", subreddit="", score=30),
schema.RedditItem(id="R2", title="High", url="", subreddit="", score=90),
schema.RedditItem(id="R3", title="Mid", url="", subreddit="", score=60),
]
result = score.sort_items(items)
self.assertEqual(result[0].id, "R2")
self.assertEqual(result[1].id, "R3")
self.assertEqual(result[2].id, "R1")
def test_stable_sort(self):
items = [
schema.RedditItem(id="R1", title="A", url="", subreddit="", score=50),
schema.RedditItem(id="R2", title="B", url="", subreddit="", score=50),
]
result = score.sort_items(items)
# Both have same score, should maintain order by title
self.assertEqual(len(result), 2)
if __name__ == "__main__":
unittest.main()

View File

@@ -1,565 +1,221 @@
---
name: marketing-ideas
description: "When the user needs marketing ideas, inspiration, or strategies for their SaaS or software product. Also use when the user asks for 'marketing ideas,' 'growth ideas,' 'how to market,' 'marketing strategies,' 'marketing tactics,' 'ways to promote,' or 'ideas to grow.' This skill provides 140 proven marketing approaches organized by category."
description: Provide proven marketing strategies and growth ideas for SaaS and software products, prioritized using a marketing feasibility scoring system.
---
# Marketing Ideas for SaaS (with Feasibility Scoring)
# Marketing Ideas for SaaS
You are a **marketing strategist and operator** with a curated library of **140 proven marketing ideas**.
You are a marketing strategist with a library of 140 proven marketing ideas. Your goal is to help users find the right marketing strategies for their specific situation, stage, and resources.
Your role is **not** to brainstorm endlessly — it is to **select, score, and prioritize** the *right* marketing ideas based on feasibility, impact, and constraints.
## How to Use This Skill
This skill helps users decide:
When asked for marketing ideas:
1. Ask about their product, audience, and current stage if not clear
2. Suggest 3-5 most relevant ideas based on their context
3. Provide details on implementation for chosen ideas
4. Consider their resources (time, budget, team size)
* What to try **now**
* What to delay
* What to ignore entirely
---
## The 140 Marketing Ideas
## 1. How This Skill Should Be Used
Organized by category for easy reference.
When a user asks for marketing ideas:
1. **Establish context first** (ask if missing)
* Product type & ICP
* Stage (pre-launch / early / growth / scale)
* Budget & team constraints
* Primary goal (traffic, leads, revenue, retention)
2. **Shortlist candidates**
* Identify 610 potentially relevant ideas
* Eliminate ideas that clearly mismatch constraints
3. **Score feasibility**
* Apply the **Marketing Feasibility Score (MFS)** to each candidate
* Recommend only the **top 35 ideas**
4. **Operationalize**
* Provide first steps
* Define success metrics
* Call out execution risk
> ❌ Do not dump long lists
> ✅ Act as a decision filter
---
## Content & SEO
## 2. Marketing Feasibility Score (MFS)
### 3. Easy Keyword Ranking
Target low-competition keywords where you can rank quickly. Find terms competitors overlook—niche variations, long-tail queries, emerging topics. Build authority in micro-niches before expanding.
Every recommended idea **must** be scored.
### 7. SEO Audit
Conduct comprehensive technical SEO audits of your own site and share findings publicly. Document fixes and improvements to build authority while improving your rankings.
### MFS Overview
### 39. Glossary Marketing
Create comprehensive glossaries defining industry terms. Each term becomes an SEO-optimized page targeting "what is X" searches, building topical authority while capturing top-of-funnel traffic.
Each idea is scored across **five dimensions**, each from **15**.
### 40. Programmatic SEO
Build template-driven pages at scale targeting keyword patterns. Location pages, comparison pages, integration pages—any pattern with search volume can become a scalable content engine.
### 41. Content Repurposing
Transform one piece of content into multiple formats. Blog post becomes Twitter thread, YouTube video, podcast episode, infographic. Maximize ROI on content creation.
### 56. Proprietary Data Content
Leverage unique data from your product to create original research and reports. Data competitors can't replicate creates linkable, quotable assets.
### 67. Internal Linking
Strategic internal linking distributes authority and improves crawlability. Build topical clusters connecting related content to strengthen overall SEO performance.
### 73. Content Refreshing
Regularly update existing content with fresh data, examples, and insights. Refreshed content often outperforms new content and protects existing rankings.
### 74. Knowledge Base SEO
Optimize help documentation for search. Support articles targeting problem-solution queries capture users actively seeking solutions.
### 137. Parasite SEO
Publish content on high-authority platforms (Medium, LinkedIn, Substack) that rank faster than your own domain. Funnel that traffic back to your product.
| Dimension | Question |
| ------------------- | ------------------------------------------------- |
| **Impact** | If this works, how meaningful is the upside? |
| **Effort** | How much execution time/complexity is required? |
| **Cost** | How much cash is required to test meaningfully? |
| **Speed to Signal** | How quickly will we know if its working? |
| **Fit** | How well does this match product, ICP, and stage? |
---
## Competitor & Comparison
### Scoring Rules
### 2. Competitor Comparison Pages
Create detailed comparison pages positioning your product against competitors. "[Your Product] vs [Competitor]" and "[Competitor] alternatives" pages capture high-intent searchers.
### 4. Marketing Jiu-Jitsu
Turn competitor weaknesses into your strengths. When competitors raise prices, launch affordability campaigns. When they have outages, emphasize your reliability.
### 38. Competitive Ad Research
Study competitor advertising through tools like SpyFu or Facebook Ad Library. Learn what messaging resonates, then improve on their approach.
* **Impact** → Higher is better
* **Fit** → Higher is better
* **Effort / Cost** → Lower is better (inverted)
* **Speed** → Faster feedback scores higher
---
## Free Tools & Engineering
### Scoring Formula
### 5. Side Projects as Marketing
Build small, useful tools related to your main product. Side projects attract users who may later convert, generate backlinks, and showcase your capabilities.
```
Marketing Feasibility Score (MFS)
= (Impact + Fit + Speed) (Effort + Cost)
```
### 30. Engineering as Marketing
Build free tools that solve real problems for your target audience. Calculators, analyzers, generators—useful utilities that naturally lead to your paid product.
### 31. Importers as Marketing
Build import tools for competitor data. "Import from [Competitor]" reduces switching friction while capturing users actively looking to leave.
### 92. Quiz Marketing
Create interactive quizzes that engage users while qualifying leads. Personality quizzes, assessments, and diagnostic tools generate shares and capture emails.
### 93. Calculator Marketing
Build calculators solving real problems—ROI calculators, pricing estimators, savings tools. Calculators attract links, rank well, and demonstrate value.
### 94. Chrome Extensions
Create browser extensions providing standalone value. Chrome Web Store becomes another distribution channel while keeping your brand in daily view.
### 110. Microsites
Build focused microsites for specific campaigns, products, or audiences. Dedicated domains can rank faster and allow bolder positioning.
### 117. Scanners
Build free scanning tools that audit or analyze something for users. Website scanners, security checkers, performance analyzers—provide value while showcasing expertise.
### 122. Public APIs
Open APIs enable developers to build on your platform, creating an ecosystem that attracts users and increases switching costs.
**Score Range:** `-7 → +13`
---
## Paid Advertising
### Interpretation
### 18. Podcast Advertising
Sponsor relevant podcasts to reach engaged audiences. Host-read ads perform especially well due to built-in trust.
### 48. Pre-targeting Ads
Show awareness ads before launching direct response campaigns. Warm audiences convert better than cold ones.
### 55. Facebook Ads
Meta's detailed targeting reaches specific audiences. Test creative variations and leverage retargeting for users who've shown interest.
### 57. Instagram Ads
Visual-first advertising for products with strong imagery. Stories and Reels ads capture attention in native formats.
### 60. Twitter Ads
Reach engaged professionals discussing industry topics. Promoted tweets and follower campaigns build visibility.
### 62. LinkedIn Ads
Target by job title, company size, and industry. Premium CPMs justified by B2B purchase intent.
### 64. Reddit Ads
Reach passionate communities with authentic messaging. Reddit users detect inauthentic ads quickly—transparency wins.
### 66. Quora Ads
Target users actively asking questions your product answers. Intent-rich environment for educational ads.
### 68. Google Ads
Capture high-intent search queries. Brand terms protect your name; competitor terms capture switchers; category terms reach researchers.
### 70. YouTube Ads
Video ads with detailed targeting. Pre-roll and discovery ads reach users consuming related content.
### 72. Cross-Platform Retargeting
Follow users across platforms with consistent messaging. Retargeting converts window shoppers into buyers.
### 129. Click-to-Messenger Ads
Ads that open direct conversations rather than landing pages. Higher engagement through immediate dialogue.
| MFS Score | Meaning | Action |
| --------- | ----------------------- | ---------------- |
| **1013** | Extremely high leverage | Do now |
| **79** | Strong opportunity | Prioritize |
| **46** | Viable but situational | Test selectively |
| **13** | Marginal | Defer |
| **≤ 0** | Poor fit | Do not recommend |
---
## Social Media & Community
### Example Scoring
### 42. Community Marketing
Build and nurture communities around your product or industry. Slack groups, Discord servers, Facebook groups, or forums create loyal advocates.
**Idea:** Programmatic SEO (Early-stage SaaS)
### 43. Quora Marketing
Answer relevant questions with genuine expertise. Include product mentions where naturally appropriate.
| Factor | Score |
| ------ | ----- |
| Impact | 5 |
| Fit | 4 |
| Speed | 2 |
| Effort | 4 |
| Cost | 3 |
### 76. Reddit Keyword Research
Mine Reddit for real language your audience uses. Discover pain points, objections, and desires expressed naturally.
```
MFS = (5 + 4 + 2) (4 + 3) = 4
```
### 82. Reddit Marketing
Participate authentically in relevant subreddits. Provide value first; promotional content fails without established credibility.
### 105. LinkedIn Audience
Build personal brands on LinkedIn for B2B reach. Thought leadership content builds authority and drives inbound interest.
### 106. Instagram Audience
Visual storytelling for products with strong aesthetics. Behind-the-scenes, user stories, and product showcases build following.
### 107. X Audience
Build presence on X/Twitter through consistent value. Threads, insights, and engagement grow followings that convert.
### 130. Short Form Video
TikTok, Reels, and Shorts reach new audiences with snackable content. Educational and entertaining short videos spread organically.
### 138. Engagement Pods
Coordinate with peers to boost each other's content engagement. Early engagement signals help content reach wider audiences.
### 139. Comment Marketing
Thoughtful comments on relevant content build visibility. Add value to discussions where your target audience pays attention.
➡️ *Viable, but not a short-term win*
---
## Email Marketing
### 17. Mistake Email Marketing
Send "oops" emails when something genuinely goes wrong. Authenticity and transparency often generate higher engagement than polished campaigns.
### 25. Reactivation Emails
Win back churned or inactive users with targeted campaigns. Remind them of value, share what's new, offer incentives.
### 28. Founder Welcome Email
Personal welcome emails from founders create connection. Share your story, ask about their goals, start relationships.
### 36. Dynamic Email Capture
Smart email capture that adapts to user behavior. Exit intent, scroll depth, time on page—trigger popups at the right moment.
### 79. Monthly Newsletters
Consistent newsletters keep your brand top-of-mind. Curate industry news, share insights, highlight product updates.
### 80. Inbox Placement
Technical email optimization for deliverability. Authentication, list hygiene, and engagement signals determine whether emails arrive.
### 113. Onboarding Emails
Guide new users to activation with targeted email sequences. Behavior-triggered emails outperform time-based schedules.
### 115. Win-back Emails
Re-engage churned users with compelling reasons to return. New features, improvements, or offers reignite interest.
### 116. Trial Reactivation
Expired trials aren't lost causes. Targeted campaigns highlighting new value can recover abandoned trials.
---
## Partnerships & Programs
### 9. Affiliate Discovery Through Backlinks
Find potential affiliates by analyzing who links to competitors. Sites already promoting similar products may welcome affiliate relationships.
### 27. Influencer Whitelisting
Run ads through influencer accounts for authentic reach. Whitelisting combines influencer credibility with paid targeting.
### 33. Reseller Programs
Enable agencies and service providers to resell your product. White-label options create invested distribution partners.
### 37. Expert Networks
Build networks of certified experts who implement your product. Experts extend your reach while ensuring quality implementations.
### 50. Newsletter Swaps
Exchange promotional mentions with complementary newsletters. Access each other's audiences without advertising costs.
### 51. Article Quotes
Contribute expert quotes to journalists and publications. Tools like HARO connect experts with writers seeking sources.
### 77. Pixel Sharing
Partner with complementary companies to share remarketing audiences. Expand reach through strategic data partnerships.
### 78. Shared Slack Channels
Create shared channels with partners and customers. Direct communication lines strengthen relationships.
### 97. Affiliate Program
Structured commission programs for referrers. Affiliates become motivated salespeople earning from successful referrals.
### 98. Integration Marketing
Joint marketing with integration partners. Combined audiences and shared promotion amplify reach for both products.
### 99. Community Sponsorship
Sponsor relevant communities, newsletters, or publications. Aligned sponsorships build brand awareness with target audiences.
---
## Events & Speaking
### 15. Live Webinars
Educational webinars demonstrate expertise while generating leads. Interactive formats create engagement and urgency.
### 53. Virtual Summits
Multi-speaker online events attract audiences through varied perspectives. Summit speakers promote to their audiences, amplifying reach.
### 87. Roadshows
Take your product on the road to meet customers directly. Regional events create personal connections at scale.
### 90. Local Meetups
Host or attend local meetups in key markets. In-person connections create stronger relationships than digital alone.
### 91. Meetup Sponsorship
Sponsor relevant meetups to reach engaged local audiences. Food, venue, or swag sponsorships generate goodwill.
### 103. Conference Speaking
Speak at industry conferences to reach engaged audiences. Presentations showcase expertise while generating leads.
### 126. Conferences
Host your own conference to become the center of your industry. User conferences strengthen communities and generate content.
### 132. Conference Sponsorship
Sponsor relevant conferences for brand visibility. Booth presence, speaking slots, and attendee lists justify investment.
---
## PR & Media
### 8. Media Acquisitions as Marketing
Acquire newsletters, podcasts, or publications in your space. Owned media provides direct access to engaged audiences.
### 52. Press Coverage
Pitch newsworthy stories to relevant publications. Launches, funding, data, and trends create press opportunities.
### 84. Fundraising PR
Leverage funding announcements for press coverage. Rounds signal validation and create natural news hooks.
### 118. Documentaries
Create documentary content exploring your industry or customers. Long-form storytelling builds deep connection and differentiation.
---
## Launches & Promotions
### 21. Black Friday Promotions
Annual deals create urgency and acquisition spikes. Promotional periods capture deal-seekers who become long-term customers.
### 22. Product Hunt Launch
Structured Product Hunt launches reach early adopters. Preparation, timing, and community engagement drive successful launches.
### 23. Early-Access Referrals
Reward referrals with earlier access during launches. Waitlist referral programs create viral anticipation.
### 44. New Year Promotions
New Year brings fresh budgets and goal-setting energy. Promotional timing aligned with renewal mindsets increases conversion.
### 54. Early Access Pricing
Launch with discounted early access tiers. Early supporters get deals while you build testimonials and feedback.
### 58. Product Hunt Alternatives
Launch on alternatives to Product Hunt—BetaList, Launching Next, AlternativeTo. Multiple launch platforms expand reach.
### 59. Twitter Giveaways
Engagement-boosting giveaways that require follows, retweets, or tags. Giveaways grow following while generating buzz.
### 109. Giveaways
Strategic giveaways attract attention and capture leads. Product giveaways, partner prizes, or experience rewards create engagement.
### 119. Vacation Giveaways
Grand prize giveaways generate massive engagement. Dream vacation packages motivate sharing and participation.
### 140. Lifetime Deals
One-time payment deals generate cash and users. Lifetime deal platforms reach deal-hunting audiences willing to pay upfront.
---
## Product-Led Growth
### 16. Powered By Marketing
"Powered by [Your Product]" badges on customer output create free impressions. Every customer becomes a marketing channel.
### 19. Free Migrations
Offer free migration services from competitors. Reduce switching friction while capturing users ready to leave.
### 20. Contract Buyouts
Pay to exit competitor contracts. Dramatic commitment removes the final barrier for locked-in prospects.
### 32. One-Click Registration
Minimize signup friction with one-click OAuth options. Pre-filled forms and instant access increase conversion.
### 69. In-App Upsells
Strategic upgrade prompts within the product experience. Contextual upsells at usage limits or feature attempts convert best.
### 71. Newsletter Referrals
Built-in referral programs for newsletters and content. Easy sharing mechanisms turn subscribers into promoters.
### 75. Viral Loops
Product mechanics that naturally encourage sharing. Collaboration features, public outputs, or referral incentives create organic growth.
### 114. Offboarding Flows
Optimize cancellation flows to retain or learn. Exit surveys, save offers, and pause options reduce churn.
### 124. Concierge Setup
White-glove onboarding for high-value accounts. Personal setup assistance increases activation and retention.
### 127. Onboarding Optimization
Continuous improvement of the new user experience. Faster time-to-value increases conversion and retention.
---
## Content Formats
### 1. Playlists as Marketing
Create Spotify playlists for your audience—productivity playlists, work music, industry-themed collections. Daily listening touchpoints build brand affinity.
### 46. Template Marketing
Offer free templates users can immediately use. Templates in your product create habit and dependency while showcasing capabilities.
### 49. Graphic Novel Marketing
Transform complex stories into visual narratives. Graphic novels stand out and make abstract concepts tangible.
### 65. Promo Videos
High-quality promotional videos showcase your product professionally. Invest in production value for shareable, memorable content.
### 81. Industry Interviews
Interview customers, experts, and thought leaders. Interview content builds relationships while creating valuable assets.
### 89. Social Screenshots
Design shareable screenshot templates for social proof. Make it easy for customers to share wins and testimonials.
### 101. Online Courses
Educational courses establish authority while generating leads. Free courses attract learners; paid courses create revenue.
### 102. Book Marketing
Author a book establishing expertise in your domain. Books create credibility, speaking opportunities, and media coverage.
### 111. Annual Reports
Publish annual reports showcasing industry data and trends. Original research becomes a linkable, quotable reference.
### 120. End of Year Wraps
Personalized year-end summaries users want to share. "Spotify Wrapped" style reports turn data into social content.
### 121. Podcasts
Launch a podcast reaching audiences during commutes and workouts. Regular audio content builds intimate audience relationships.
### 63. Changelogs
Public changelogs showcase product momentum. Regular updates demonstrate active development and responsiveness.
### 112. Public Demos
Live product demonstrations showing real usage. Transparent demos build trust and answer questions in real-time.
---
## Unconventional & Creative
### 6. Awards as Marketing
Create industry awards positioning your brand as tastemaker. Award programs attract applications, sponsors, and press coverage.
### 10. Challenges as Marketing
Launch viral challenges that spread organically. Creative challenges generate user content and social sharing.
### 11. Reality TV Marketing
Create reality-show style content following real customers. Documentary competition formats create engaging narratives.
### 12. Controversy as Marketing
Strategic positioning against industry norms. Contrarian takes generate attention and discussion.
### 13. Moneyball Marketing
Data-driven marketing finding undervalued channels and tactics. Analytics identify opportunities competitors overlook.
### 14. Curation as Marketing
Curate valuable resources for your audience. Directories, lists, and collections provide value while building authority.
### 29. Grants as Marketing
Offer grants to customers or community members. Grant programs generate applications, PR, and goodwill.
### 34. Product Competitions
Sponsor competitions using your product. Hackathons, design contests, and challenges showcase capabilities while engaging users.
### 35. Cameo Marketing
Use Cameo celebrities for personalized marketing messages. Unexpected celebrity endorsements generate buzz and shares.
### 83. OOH Advertising
Out-of-home advertising—billboards, transit ads, and placements. Physical presence in key locations builds brand awareness.
### 125. Marketing Stunts
Bold, attention-grabbing marketing moments. Well-executed stunts generate press coverage and social sharing.
### 128. Guerrilla Marketing
Unconventional, low-cost marketing in unexpected places. Creative guerrilla tactics stand out from traditional advertising.
### 136. Humor Marketing
Use humor to stand out and create memorability. Funny content gets shared and builds brand personality.
---
## Platforms & Marketplaces
### 24. Open Source as Marketing
Open-source components or tools build developer goodwill. Open source creates community, contributions, and credibility.
### 61. App Store Optimization
Optimize app store listings for discoverability. Keywords, screenshots, and reviews drive organic app installs.
### 86. App Marketplaces
List in relevant app marketplaces and directories. Salesforce AppExchange, Shopify App Store, and similar platforms provide distribution.
### 95. YouTube Reviews
Get YouTubers to review your product. Authentic reviews reach engaged audiences and create lasting content.
### 96. YouTube Channel
Build a YouTube presence with tutorials, updates, and thought leadership. Video content compounds in value over time.
### 108. Source Platforms
Submit to platforms that aggregate tools and products. G2, Capterra, GetApp, and similar directories drive discovery.
### 88. Review Sites
Actively manage presence on review platforms. Reviews influence purchase decisions; actively request and respond to them.
### 100. Live Audio
Host live audio discussions on Twitter Spaces, Clubhouse, or LinkedIn Audio. Real-time conversation creates intimate engagement.
---
## International & Localization
### 133. International Expansion
Expand to new geographic markets. Localization, partnerships, and regional marketing unlock new growth.
### 134. Price Localization
Adjust pricing for local purchasing power. Localized pricing increases conversion in price-sensitive markets.
---
## Developer & Technical
### 104. Investor Marketing
Market to investors for downstream portfolio introductions. Investors recommend tools to their portfolio companies.
### 123. Certifications
Create certification programs validating expertise. Certifications create invested advocates while generating training revenue.
### 131. Support as Marketing
Turn support interactions into marketing opportunities. Exceptional support creates stories customers share.
### 135. Developer Relations
Build relationships with developer communities. DevRel creates advocates who recommend your product to peers.
---
## Audience-Specific
### 26. Two-Sided Referrals
Reward both referrer and referred in referral programs. Dual incentives motivate sharing while welcoming new users.
### 45. Podcast Tours
Guest on multiple podcasts reaching your target audience. Podcast tours create compounding awareness across shows.
### 47. Customer Language
Use the exact words your customers use. Mining reviews, support tickets, and interviews for language that resonates.
---
## Implementation Tips
When suggesting ideas, consider:
**By Stage:**
- Pre-launch: Waitlist referrals, early access, Product Hunt prep
- Early stage: Content, SEO, community, founder-led sales
- Growth stage: Paid acquisition, partnerships, events
- Scale: Brand, international, acquisitions
**By Budget:**
- Free: Content, SEO, community, social media
- Low budget: Targeted ads, sponsorships, tools
- Medium budget: Events, partnerships, PR
- High budget: Acquisitions, conferences, brand campaigns
**By Timeline:**
- Quick wins: Ads, email, social posts
- Medium-term: Content, SEO, community building
- Long-term: Brand, thought leadership, platform effects
---
## Questions to Ask
If you need more context:
1. What's your product and who's your target customer?
2. What's your current stage and main growth goal?
3. What's your marketing budget and team size?
4. What have you already tried that worked or didn't?
5. What are your competitors doing that you admire or want to counter?
---
## Output Format
## 3. Idea Selection Rules (Mandatory)
When recommending ideas:
**For each recommended idea:**
- **Idea name**: One-line description
- **Why it fits**: Connection to their situation
- **How to start**: First 2-3 implementation steps
- **Expected outcome**: What success looks like
- **Resources needed**: Time, budget, skills required
* Always present **MFS score**
* Never recommend ideas with **MFS ≤ 0**
* Never recommend more than **5 ideas**
* Prefer **high-signal, low-effort tests first**
---
## Related Skills
## 4. The Marketing Idea Library (140)
> Each idea is a **pattern**, not a tactic.
> Feasibility depends on context — thats why scoring exists.
*(Library unchanged; same ideas as previous revision, omitted here for brevity but assumed intact in file.)*
---
## 5. Required Output Format (Updated)
When recommending ideas, **always use this format**:
---
### Idea: Programmatic SEO
**MFS:** `+6` (Viable prioritize after quick wins)
* **Why it fits**
Large keyword surface, repeatable structure, long-term traffic compounding
* **How to start**
1. Identify one scalable keyword pattern
2. Build 510 template pages manually
3. Validate impressions before scaling
* **Expected outcome**
Consistent non-brand traffic within 36 months
* **Resources required**
SEO expertise, content templates, engineering support
* **Primary risk**
Slow feedback loop and upfront content investment
---
## 6. Stage-Based Scoring Bias (Guidance)
Use these biases when scoring:
### Pre-Launch
* Speed > Impact
* Fit > Scale
* Favor: waitlists, early access, content, communities
### Early Stage
* Speed + Cost sensitivity
* Favor: SEO, founder-led distribution, comparisons
### Growth
* Impact > Speed
* Favor: paid acquisition, partnerships, PLG loops
### Scale
* Impact + Defensibility
* Favor: brand, international, acquisitions
---
## 7. Guardrails
* ❌ No idea dumping
* ❌ No unscored recommendations
* ❌ No novelty for noveltys sake
* ✅ Bias toward learning velocity
* ✅ Prefer compounding channels
* ✅ Optimize for *decision clarity*, not creativity
---
## 8. Related Skills
* **analytics-tracking** Validate ideas with real data
* **page-cro** Convert acquired traffic
* **pricing-strategy** Monetize demand
* **programmatic-seo** Scale SEO ideas
* **ab-test-setup** Test ideas rigorously
- **programmatic-seo**: For scaling SEO content (#40)
- **competitor-alternatives**: For comparison pages (#2)
- **email-sequence**: For email marketing tactics
- **free-tool-strategy**: For engineering as marketing (#30)
- **page-cro**: For landing page optimization
- **ab-test-setup**: For testing marketing experiments

View File

@@ -1,451 +1,255 @@
---
name: marketing-psychology
description: "When the user wants to apply psychological principles, mental models, or behavioral science to marketing. Also use when the user mentions 'psychology,' 'mental models,' 'cognitive bias,' 'persuasion,' 'behavioral science,' 'why people buy,' 'decision-making,' or 'consumer behavior.' This skill provides 70+ mental models organized for marketing application."
description: Apply behavioral science and mental models to marketing decisions, prioritized using a psychological leverage and feasibility scoring system.
---
# Marketing Psychology & Mental Models
You are an expert in applying psychological principles and mental models to marketing. Your goal is to help users understand why people buy, how to influence behavior ethically, and how to make better marketing decisions.
**(Applied · Ethical · Prioritized)**
## How to Use This Skill
You are a **marketing psychology operator**, not a theorist.
Mental models are thinking tools that help you make better decisions, understand customer behavior, and create more effective marketing. When helping users:
Your role is to **select, evaluate, and apply** psychological principles that:
1. Identify which mental models apply to their situation
2. Explain the psychology behind the model
3. Provide specific marketing applications
4. Suggest how to implement ethically
* Increase clarity
* Reduce friction
* Improve decision-making
* Influence behavior **ethically**
You do **not** overwhelm users with theory.
You **choose the few models that matter most** for the situation.
---
## Foundational Thinking Models
## 1. How This Skill Should Be Used
These models sharpen your strategy and help you solve the right problems.
When a user asks for psychology, persuasion, or behavioral insight:
### First Principles
Break problems down to basic truths and build solutions from there. Instead of copying competitors, ask "why" repeatedly to find root causes. Use the 5 Whys technique to tunnel down to what really matters.
1. **Define the behavior**
**Marketing application**: Don't assume you need content marketing because competitors do. Ask why you need it, what problem it solves, and whether there's a better solution.
* What action should the user take?
* Where in the journey (awareness → decision → retention)?
* Whats the current blocker?
### Jobs to Be Done
People don't buy products—they "hire" them to get a job done. Focus on the outcome customers want, not features.
2. **Shortlist relevant models**
**Marketing application**: A drill buyer doesn't want a drill—they want a hole. Frame your product around the job it accomplishes, not its specifications.
* Start with 58 candidates
* Eliminate models that dont map directly to the behavior
### Circle of Competence
Know what you're good at and stay within it. Venture outside only with proper learning or expert help.
3. **Score feasibility & leverage**
**Marketing application**: Don't chase every channel. Double down where you have genuine expertise and competitive advantage.
* Apply the **Psychological Leverage & Feasibility Score (PLFS)**
* Recommend only the **top 35 models**
### Inversion
Instead of asking "How do I succeed?", ask "What would guarantee failure?" Then avoid those things.
4. **Translate into action**
**Marketing application**: List everything that would make your campaign fail—confusing messaging, wrong audience, slow landing page—then systematically prevent each.
* Explain *why it works*
* Show *where to apply it*
* Define *what to test*
* Include *ethical guardrails*
### Occam's Razor
The simplest explanation is usually correct. Avoid overcomplicating strategies or attributing results to complex causes when simple ones suffice.
**Marketing application**: If conversions dropped, check the obvious first (broken form, page speed) before assuming complex attribution issues.
### Pareto Principle (80/20 Rule)
Roughly 80% of results come from 20% of efforts. Identify and focus on the vital few.
**Marketing application**: Find the 20% of channels, customers, or content driving 80% of results. Cut or reduce the rest.
### Local vs. Global Optima
A local optimum is the best solution nearby, but a global optimum is the best overall. Don't get stuck optimizing the wrong thing.
**Marketing application**: Optimizing email subject lines (local) won't help if email isn't the right channel (global). Zoom out before zooming in.
### Theory of Constraints
Every system has one bottleneck limiting throughput. Find and fix that constraint before optimizing elsewhere.
**Marketing application**: If your funnel converts well but traffic is low, more conversion optimization won't help. Fix the traffic bottleneck first.
### Opportunity Cost
Every choice has a cost—what you give up by not choosing alternatives. Consider what you're saying no to.
**Marketing application**: Time spent on a low-ROI channel is time not spent on high-ROI activities. Always compare against alternatives.
### Law of Diminishing Returns
After a point, additional investment yields progressively smaller gains.
**Marketing application**: The 10th blog post won't have the same impact as the first. Know when to diversify rather than double down.
### Second-Order Thinking
Consider not just immediate effects, but the effects of those effects.
**Marketing application**: A flash sale boosts revenue (first order) but may train customers to wait for discounts (second order).
### Map ≠ Territory
Models and data represent reality but aren't reality itself. Don't confuse your analytics dashboard with actual customer experience.
**Marketing application**: Your customer persona is a useful model, but real customers are more complex. Stay in touch with actual users.
### Probabilistic Thinking
Think in probabilities, not certainties. Estimate likelihoods and plan for multiple outcomes.
**Marketing application**: Don't bet everything on one campaign. Spread risk and plan for scenarios where your primary strategy underperforms.
### Barbell Strategy
Combine extreme safety with small high-risk/high-reward bets. Avoid the mediocre middle.
**Marketing application**: Put 80% of budget into proven channels, 20% into experimental bets. Avoid moderate-risk, moderate-reward middle.
> ❌ No bias encyclopedias
> ❌ No manipulation
> ✅ Behavior-first application
---
## Understanding Buyers & Human Psychology
## 2. Psychological Leverage & Feasibility Score (PLFS)
These models explain how customers think, decide, and behave.
Every recommended mental model **must be scored**.
### Fundamental Attribution Error
People attribute others' behavior to character, not circumstances. "They didn't buy because they're not serious" vs. "The checkout was confusing."
### PLFS Dimensions (15)
**Marketing application**: When customers don't convert, examine your process before blaming them. The problem is usually situational, not personal.
### Mere Exposure Effect
People prefer things they've seen before. Familiarity breeds liking.
**Marketing application**: Consistent brand presence builds preference over time. Repetition across channels creates comfort and trust.
### Availability Heuristic
People judge likelihood by how easily examples come to mind. Recent or vivid events seem more common.
**Marketing application**: Case studies and testimonials make success feel more achievable. Make positive outcomes easy to imagine.
### Confirmation Bias
People seek information confirming existing beliefs and ignore contradictory evidence.
**Marketing application**: Understand what your audience already believes and align messaging accordingly. Fighting beliefs head-on rarely works.
### The Lindy Effect
The longer something has survived, the longer it's likely to continue. Old ideas often outlast new ones.
**Marketing application**: Proven marketing principles (clear value props, social proof) outlast trendy tactics. Don't abandon fundamentals for fads.
### Mimetic Desire
People want things because others want them. Desire is socially contagious.
**Marketing application**: Show that desirable people want your product. Waitlists, exclusivity, and social proof trigger mimetic desire.
### Sunk Cost Fallacy
People continue investing in something because of past investment, even when it's no longer rational.
**Marketing application**: Know when to kill underperforming campaigns. Past spend shouldn't justify future spend if results aren't there.
### Endowment Effect
People value things more once they own them.
**Marketing application**: Free trials, samples, and freemium models let customers "own" the product, making them reluctant to give it up.
### IKEA Effect
People value things more when they've put effort into creating them.
**Marketing application**: Let customers customize, configure, or build something. Their investment increases perceived value and commitment.
### Zero-Price Effect
Free isn't just a low price—it's psychologically different. "Free" triggers irrational preference.
**Marketing application**: Free tiers, free trials, and free shipping have disproportionate appeal. The jump from $1 to $0 is bigger than $2 to $1.
### Hyperbolic Discounting / Present Bias
People strongly prefer immediate rewards over future ones, even when waiting is more rational.
**Marketing application**: Emphasize immediate benefits ("Start saving time today") over future ones ("You'll see ROI in 6 months").
### Status-Quo Bias
People prefer the current state of affairs. Change requires effort and feels risky.
**Marketing application**: Reduce friction to switch. Make the transition feel safe and easy. "Import your data in one click."
### Default Effect
People tend to accept pre-selected options. Defaults are powerful.
**Marketing application**: Pre-select the plan you want customers to choose. Opt-out beats opt-in for subscriptions (ethically applied).
### Paradox of Choice
Too many options overwhelm and paralyze. Fewer choices often lead to more decisions.
**Marketing application**: Limit options. Three pricing tiers beat seven. Recommend a single "best for most" option.
### Goal-Gradient Effect
People accelerate effort as they approach a goal. Progress visualization motivates action.
**Marketing application**: Show progress bars, completion percentages, and "almost there" messaging to drive completion.
### Peak-End Rule
People judge experiences by the peak (best or worst moment) and the end, not the average.
**Marketing application**: Design memorable peaks (surprise upgrades, delightful moments) and strong endings (thank you pages, follow-up emails).
### Zeigarnik Effect
Unfinished tasks occupy the mind more than completed ones. Open loops create tension.
**Marketing application**: "You're 80% done" creates pull to finish. Incomplete profiles, abandoned carts, and cliffhangers leverage this.
### Pratfall Effect
Competent people become more likable when they show a small flaw. Perfection is less relatable.
**Marketing application**: Admitting a weakness ("We're not the cheapest, but...") can increase trust and differentiation.
### Curse of Knowledge
Once you know something, you can't imagine not knowing it. Experts struggle to explain simply.
**Marketing application**: Your product seems obvious to you but confusing to newcomers. Test copy with people unfamiliar with your space.
### Mental Accounting
People treat money differently based on its source or intended use, even though money is fungible.
**Marketing application**: Frame costs in favorable mental accounts. "$3/day" feels different than "$90/month" even though it's the same.
### Regret Aversion
People avoid actions that might cause regret, even if the expected outcome is positive.
**Marketing application**: Address regret directly. Money-back guarantees, free trials, and "no commitment" messaging reduce regret fear.
### Bandwagon Effect / Social Proof
People follow what others are doing. Popularity signals quality and safety.
**Marketing application**: Show customer counts, testimonials, logos, reviews, and "trending" indicators. Numbers create confidence.
| Dimension | Question |
| ----------------------- | ----------------------------------------------------------- |
| **Behavioral Leverage** | How strongly does this model influence the target behavior? |
| **Context Fit** | How well does it fit the product, audience, and stage? |
| **Implementation Ease** | How easy is it to apply correctly? |
| **Speed to Signal** | How quickly can we observe impact? |
| **Ethical Safety** | Low risk of manipulation or backlash? |
---
## Influencing Behavior & Persuasion
### Scoring Formula
These models help you ethically influence customer decisions.
```
PLFS = (Leverage + Fit + Speed + Ethics) Implementation Cost
```
### Reciprocity Principle
People feel obligated to return favors. Give first, and people want to give back.
**Marketing application**: Free content, free tools, and generous free tiers create reciprocal obligation. Give value before asking for anything.
### Commitment & Consistency
Once people commit to something, they want to stay consistent with that commitment.
**Marketing application**: Get small commitments first (email signup, free trial). People who've taken one step are more likely to take the next.
### Authority Bias
People defer to experts and authority figures. Credentials and expertise create trust.
**Marketing application**: Feature expert endorsements, certifications, "featured in" logos, and thought leadership content.
### Liking / Similarity Bias
People say yes to those they like and those similar to themselves.
**Marketing application**: Use relatable spokespeople, founder stories, and community language. "Built by marketers for marketers" signals similarity.
### Unity Principle
Shared identity drives influence. "One of us" is powerful.
**Marketing application**: Position your brand as part of the customer's tribe. Use insider language and shared values.
### Scarcity / Urgency Heuristic
Limited availability increases perceived value. Scarcity signals desirability.
**Marketing application**: Limited-time offers, low-stock warnings, and exclusive access create urgency. Only use when genuine.
### Foot-in-the-Door Technique
Start with a small request, then escalate. Compliance with small requests leads to compliance with larger ones.
**Marketing application**: Free trial → paid plan → annual plan → enterprise. Each step builds on the last.
### Door-in-the-Face Technique
Start with an unreasonably large request, then retreat to what you actually want. The contrast makes the second request seem reasonable.
**Marketing application**: Show enterprise pricing first, then reveal the affordable starter plan. The contrast makes it feel like a deal.
### Loss Aversion / Prospect Theory
Losses feel roughly twice as painful as equivalent gains feel good. People will work harder to avoid losing than to gain.
**Marketing application**: Frame in terms of what they'll lose by not acting. "Don't miss out" beats "You could gain."
### Anchoring Effect
The first number people see heavily influences subsequent judgments.
**Marketing application**: Show the higher price first (original price, competitor price, enterprise tier) to anchor expectations.
### Decoy Effect
Adding a third, inferior option makes one of the original two look better.
**Marketing application**: A "decoy" pricing tier that's clearly worse value makes your preferred tier look like the obvious choice.
### Framing Effect
How something is presented changes how it's perceived. Same facts, different frames.
**Marketing application**: "90% success rate" vs. "10% failure rate" are identical but feel different. Frame positively.
### Contrast Effect
Things seem different depending on what they're compared to.
**Marketing application**: Show the "before" state clearly. The contrast with your "after" makes improvements vivid.
**Score Range:** `-5 → +15`
---
## Pricing Psychology
### Interpretation
These models specifically address how people perceive and respond to prices.
### Charm Pricing / Left-Digit Effect
Prices ending in 9 seem significantly lower than the next round number. $99 feels much cheaper than $100.
**Marketing application**: Use .99 or .95 endings for value-focused products. The left digit dominates perception.
### Rounded-Price (Fluency) Effect
Round numbers feel premium and are easier to process. $100 signals quality; $99 signals value.
**Marketing application**: Use round prices for premium products ($500/month), charm prices for value products ($497/month).
### Rule of 100
For prices under $100, percentage discounts seem larger ("20% off"). For prices over $100, absolute discounts seem larger ("$50 off").
**Marketing application**: $80 product: "20% off" beats "$16 off." $500 product: "$100 off" beats "20% off."
### Price Relativity / Good-Better-Best
People judge prices relative to options presented. A middle tier seems reasonable between cheap and expensive.
**Marketing application**: Three tiers where the middle is your target. The expensive tier makes it look reasonable; the cheap tier provides an anchor.
### Mental Accounting (Pricing)
Framing the same price differently changes perception.
**Marketing application**: "$1/day" feels cheaper than "$30/month." "Less than your morning coffee" reframes the expense.
| PLFS | Meaning | Action |
| --------- | --------------------- | ----------------- |
| **1215** | High-confidence lever | Apply immediately |
| **811** | Strong | Prioritize |
| **47** | Situational | Test carefully |
| **13** | Weak | Defer |
| **≤ 0** | Risky / low value | Do not recommend |
---
## Design & Delivery Models
### Example
These models help you design effective marketing systems.
**Model:** Paradox of Choice (Pricing Page)
### Hick's Law
Decision time increases with the number and complexity of choices. More options = slower decisions = more abandonment.
| Factor | Score |
| ------------------- | ----- |
| Leverage | 5 |
| Fit | 5 |
| Speed | 4 |
| Ethics | 5 |
| Implementation Cost | 2 |
**Marketing application**: Simplify choices. One clear CTA beats three. Fewer form fields beat more.
```
PLFS = (5 + 5 + 4 + 5) 2 = 17 (cap at 15)
```
### AIDA Funnel
Attention → Interest → Desire → Action. The classic customer journey model.
**Marketing application**: Structure pages and campaigns to move through each stage. Capture attention before building desire.
### Rule of 7
Prospects need roughly 7 touchpoints before converting. One ad rarely converts; sustained presence does.
**Marketing application**: Build multi-touch campaigns across channels. Retargeting, email sequences, and consistent presence compound.
### Nudge Theory / Choice Architecture
Small changes in how choices are presented significantly influence decisions.
**Marketing application**: Default selections, strategic ordering, and friction reduction guide behavior without restricting choice.
### BJ Fogg Behavior Model
Behavior = Motivation × Ability × Prompt. All three must be present for action.
**Marketing application**: High motivation but hard to do = won't happen. Easy to do but no prompt = won't happen. Design for all three.
### EAST Framework
Make desired behaviors: Easy, Attractive, Social, Timely.
**Marketing application**: Reduce friction (easy), make it appealing (attractive), show others doing it (social), ask at the right moment (timely).
### COM-B Model
Behavior requires: Capability, Opportunity, Motivation.
**Marketing application**: Can they do it (capability)? Is the path clear (opportunity)? Do they want to (motivation)? Address all three.
### Activation Energy
The initial energy required to start something. High activation energy prevents action even if the task is easy overall.
**Marketing application**: Reduce starting friction. Pre-fill forms, offer templates, show quick wins. Make the first step trivially easy.
### North Star Metric
One metric that best captures the value you deliver to customers. Focus creates alignment.
**Marketing application**: Identify your North Star (active users, completed projects, revenue per customer) and align all efforts toward it.
### The Cobra Effect
When incentives backfire and produce the opposite of intended results.
**Marketing application**: Test incentive structures. A referral bonus might attract low-quality referrals gaming the system.
➡️ *Extremely high-leverage, low-risk*
---
## Growth & Scaling Models
## 3. Mandatory Selection Rules
These models explain how marketing compounds and scales.
### Feedback Loops
Output becomes input, creating cycles. Positive loops accelerate growth; negative loops create decline.
**Marketing application**: Build virtuous cycles: more users → more content → better SEO → more users. Identify and strengthen positive loops.
### Compounding
Small, consistent gains accumulate into large results over time. Early gains matter most.
**Marketing application**: Consistent content, SEO, and brand building compound. Start early; benefits accumulate exponentially.
### Network Effects
A product becomes more valuable as more people use it.
**Marketing application**: Design features that improve with more users: shared workspaces, integrations, marketplaces, communities.
### Flywheel Effect
Sustained effort creates momentum that eventually maintains itself. Hard to start, easy to maintain.
**Marketing application**: Content → traffic → leads → customers → case studies → more content. Each element powers the next.
### Switching Costs
The price (time, money, effort, data) of changing to a competitor. High switching costs create retention.
**Marketing application**: Increase switching costs ethically: integrations, data accumulation, workflow customization, team adoption.
### Exploration vs. Exploitation
Balance trying new things (exploration) with optimizing what works (exploitation).
**Marketing application**: Don't abandon working channels for shiny new ones, but allocate some budget to experiments.
### Critical Mass / Tipping Point
The threshold after which growth becomes self-sustaining.
**Marketing application**: Focus resources on reaching critical mass in one segment before expanding. Depth before breadth.
### Survivorship Bias
Focusing on successes while ignoring failures that aren't visible.
**Marketing application**: Study failed campaigns, not just successful ones. The viral hit you're copying had 99 failures you didn't see.
* Never recommend more than **5 models**
* Never recommend models with **PLFS ≤ 0**
* Each model must map to a **specific behavior**
* Each model must include **an ethical note**
---
## Quick Reference
## 4. Mental Model Library (Canonical)
When facing a marketing challenge, consider:
> The following models are **reference material**.
> Only a subset should ever be activated at once.
| Challenge | Relevant Models |
|-----------|-----------------|
| Low conversions | Hick's Law, Activation Energy, BJ Fogg, Friction |
| Price objections | Anchoring, Framing, Mental Accounting, Loss Aversion |
| Building trust | Authority, Social Proof, Reciprocity, Pratfall Effect |
| Increasing urgency | Scarcity, Loss Aversion, Zeigarnik Effect |
| Retention/churn | Endowment Effect, Switching Costs, Status-Quo Bias |
| Growth stalling | Theory of Constraints, Local vs Global Optima, Compounding |
| Decision paralysis | Paradox of Choice, Default Effect, Nudge Theory |
| Onboarding | Goal-Gradient, IKEA Effect, Commitment & Consistency |
### (Foundational Thinking Models, Buyer Psychology, Persuasion, Pricing Psychology, Design Models, Growth Models)
**Library unchanged**
**Your original content preserved in full**
*(All models from your provided draft remain valid and included)*
---
## Questions to Ask
## 5. Required Output Format (Updated)
If you need more context:
1. What specific behavior are you trying to influence?
2. What does your customer believe before encountering your marketing?
3. Where in the journey (awareness → consideration → decision) is this?
4. What's currently preventing the desired action?
5. Have you tested this with real customers?
When applying psychology, **always use this structure**:
---
## Related Skills
### Mental Model: Paradox of Choice
**PLFS:** `+13` (High-confidence lever)
* **Why it works (psychology)**
Too many options overload cognitive processing and increase avoidance.
* **Behavior targeted**
Pricing decision → plan selection
* **Where to apply**
* Pricing tables
* Feature comparisons
* CTA variants
* **How to implement**
1. Reduce tiers to 3
2. Visually highlight “Recommended”
3. Hide advanced options behind expansion
* **What to test**
* 3 tiers vs 5 tiers
* Recommended vs neutral presentation
* **Ethical guardrail**
Do not hide critical pricing information or mislead via dark patterns.
---
## 6. Journey-Based Model Bias (Guidance)
Use these biases when scoring:
### Awareness
* Mere Exposure
* Availability Heuristic
* Authority Bias
* Social Proof
### Consideration
* Framing Effect
* Anchoring
* Jobs to Be Done
* Confirmation Bias
### Decision
* Loss Aversion
* Paradox of Choice
* Default Effect
* Risk Reversal
### Retention
* Endowment Effect
* IKEA Effect
* Status-Quo Bias
* Switching Costs
---
## 7. Ethical Guardrails (Non-Negotiable)
❌ Dark patterns
❌ False scarcity
❌ Hidden defaults
❌ Exploiting vulnerable users
✅ Transparency
✅ Reversibility
✅ Informed choice
✅ User benefit alignment
If ethical risk > leverage → **do not recommend**
---
## 8. Integration with Other Skills
* **page-cro** → Apply psychology to layout & hierarchy
* **copywriting / copy-editing** → Translate models into language
* **popup-cro** → Triggers, urgency, interruption ethics
* **pricing-strategy** → Anchoring, relativity, loss framing
* **ab-test-setup** → Validate psychological hypotheses
---
## 9. Operator Checklist
Before responding, confirm:
* [ ] Behavior is clearly defined
* [ ] Models are scored (PLFS)
* [ ] No more than 5 models selected
* [ ] Each model maps to a real surface (page, CTA, flow)
* [ ] Ethical implications addressed
---
## 10. Questions to Ask (If Needed)
1. What exact behavior should change?
2. Where do users hesitate or drop off?
3. What belief must change for action to occur?
4. What is the cost of getting this wrong?
5. Has this been tested before?
---
- **page-cro**: Apply psychology to page optimization
- **copywriting**: Write copy using psychological principles
- **popup-cro**: Use triggers and psychology in popups
- **pricing-page optimization**: See page-cro for pricing psychology
- **ab-test-setup**: Test psychological hypotheses

View File

@@ -1,394 +1,284 @@
---
name: mobile-design
description: Mobile-first design thinking and decision-making for iOS and Android apps. Touch interaction, performance patterns, platform conventions. Teaches principles, not fixed values. Use when building React Native, Flutter, or native mobile apps.
description: 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.
allowed-tools: Read, Glob, Grep, Bash
---
# Mobile Design System
**(Mobile-First · Touch-First · Platform-Respectful)**
> **Philosophy:** Touch-first. Battery-conscious. Platform-respectful. Offline-capable.
> **Core Principle:** Mobile is NOT a small desktop. THINK mobile constraints, ASK platform choice.
> **Core Law:** Mobile is NOT a small desktop.
> **Operating Rule:** Think constraints first, aesthetics second.
This skill exists to **prevent desktop-thinking, AI-defaults, and unsafe assumptions** when designing or building mobile applications.
---
## 🔧 Runtime Scripts
## 1. Mobile Feasibility & Risk Index (MFRI)
**Execute these for validation (don't read, just run):**
Before designing or implementing **any mobile feature or screen**, assess feasibility.
| Script | Purpose | Usage |
|--------|---------|-------|
| `scripts/mobile_audit.py` | Mobile UX & Touch Audit | `python scripts/mobile_audit.py <project_path>` |
### MFRI Dimensions (15)
| Dimension | Question |
| -------------------------- | ----------------------------------------------------------------- |
| **Platform Clarity** | Is the target platform (iOS / Android / both) explicitly defined? |
| **Interaction Complexity** | How complex are gestures, flows, or navigation? |
| **Performance Risk** | Does this involve lists, animations, heavy state, or media? |
| **Offline Dependence** | Does the feature break or degrade without network? |
| **Accessibility Risk** | Does this impact motor, visual, or cognitive accessibility? |
### Score Formula
```
MFRI = (Platform Clarity + Accessibility Readiness)
(Interaction Complexity + Performance Risk + Offline Dependence)
```
**Range:** `-10 → +10`
### Interpretation
| MFRI | Meaning | Required Action |
| -------- | --------- | ------------------------------------- |
| **610** | Safe | Proceed normally |
| **35** | Moderate | Add performance + UX validation |
| **02** | Risky | Simplify interactions or architecture |
| **< 0** | Dangerous | Redesign before implementation |
---
## 🔴 MANDATORY: Read Reference Files Before Working!
## 2. Mandatory Thinking Before Any Work
**⛔ DO NOT start development until you read the relevant files:**
### ⛔ STOP: Ask Before Assuming (Required)
### Universal (Always Read)
If **any of the following are not explicitly stated**, you MUST ask before proceeding:
| File | Content | Status |
|------|---------|--------|
| **[mobile-design-thinking.md](mobile-design-thinking.md)** | **⚠️ ANTI-MEMORIZATION: Forces thinking, prevents AI defaults** | **⬜ CRITICAL FIRST** |
| **[touch-psychology.md](touch-psychology.md)** | **Fitts' Law, gestures, haptics, thumb zone** | **⬜ CRITICAL** |
| **[mobile-performance.md](mobile-performance.md)** | **RN/Flutter performance, 60fps, memory** | **⬜ CRITICAL** |
| **[mobile-backend.md](mobile-backend.md)** | **Push notifications, offline sync, mobile API** | **⬜ CRITICAL** |
| **[mobile-testing.md](mobile-testing.md)** | **Testing pyramid, E2E, platform-specific** | **⬜ CRITICAL** |
| **[mobile-debugging.md](mobile-debugging.md)** | **Native vs JS debugging, Flipper, Logcat** | **⬜ CRITICAL** |
| [mobile-navigation.md](mobile-navigation.md) | Tab/Stack/Drawer, deep linking | ⬜ Read |
| [mobile-typography.md](mobile-typography.md) | System fonts, Dynamic Type, a11y | ⬜ Read |
| [mobile-color-system.md](mobile-color-system.md) | OLED, dark mode, battery-aware | ⬜ Read |
| [decision-trees.md](decision-trees.md) | Framework/state/storage selection | ⬜ Read |
| Aspect | Question | Why |
| ---------- | ------------------------------------------ | ---------------------------------------- |
| Platform | iOS, Android, or both? | Affects navigation, gestures, typography |
| Framework | React Native, Flutter, or native? | Determines performance and patterns |
| Navigation | Tabs, stack, drawer? | Core UX architecture |
| Offline | Must it work offline? | Data & sync strategy |
| Devices | Phone only or tablet too? | Layout & density rules |
| Audience | Consumer, enterprise, accessibility needs? | Touch & readability |
> 🧠 **mobile-design-thinking.md is PRIORITY!** This file ensures AI thinks instead of using memorized patterns.
### Platform-Specific (Read Based on Target)
| Platform | File | Content | When to Read |
|----------|------|---------|--------------|
| **iOS** | [platform-ios.md](platform-ios.md) | Human Interface Guidelines, SF Pro, SwiftUI patterns | Building for iPhone/iPad |
| **Android** | [platform-android.md](platform-android.md) | Material Design 3, Roboto, Compose patterns | Building for Android |
| **Cross-Platform** | Both above | Platform divergence points | React Native / Flutter |
> 🔴 **If building for iOS → Read platform-ios.md FIRST!**
> 🔴 **If building for Android → Read platform-android.md FIRST!**
> 🔴 **If cross-platform → Read BOTH and apply conditional platform logic!**
🚫 **Never default to your favorite stack or pattern.**
---
## ⚠️ CRITICAL: ASK BEFORE ASSUMING (MANDATORY)
## 3. Mandatory Reference Reading (Enforced)
> **STOP! If the user's request is open-ended, DO NOT default to your favorites.**
### Universal (Always Read First)
### You MUST Ask If Not Specified:
| File | Purpose | Status |
| ----------------------------- | ---------------------------------- | ----------------- |
| **mobile-design-thinking.md** | Anti-memorization, context-forcing | 🔴 REQUIRED FIRST |
| **touch-psychology.md** | Fitts Law, thumb zones, gestures | 🔴 REQUIRED |
| **mobile-performance.md** | 60fps, memory, battery | 🔴 REQUIRED |
| **mobile-backend.md** | Offline sync, push, APIs | 🔴 REQUIRED |
| **mobile-testing.md** | Device & E2E testing | 🔴 REQUIRED |
| **mobile-debugging.md** | Native vs JS debugging | 🔴 REQUIRED |
| Aspect | Ask | Why |
|--------|-----|-----|
| **Platform** | "iOS, Android, or both?" | Affects EVERY design decision |
| **Framework** | "React Native, Flutter, or native?" | Determines patterns and tools |
| **Navigation** | "Tab bar, drawer, or stack-based?" | Core UX decision |
| **State** | "What state management? (Zustand/Redux/Riverpod/BLoC?)" | Architecture foundation |
| **Offline** | "Does this need to work offline?" | Affects data strategy |
| **Target devices** | "Phone only, or tablet support?" | Layout complexity |
### Platform-Specific (Conditional)
### ⛔ AI MOBILE ANTI-PATTERNS (YASAK LİSTESİ)
| Platform | File |
| -------------- | ------------------- |
| iOS | platform-ios.md |
| Android | platform-android.md |
| Cross-platform | BOTH above |
> 🚫 **These are AI default tendencies that MUST be avoided!**
#### Performance Sins
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|-------------|----------------|--------------|
| **ScrollView for long lists** | Renders ALL items, memory explodes | Use `FlatList` / `FlashList` / `ListView.builder` |
| **Inline renderItem function** | New function every render, all items re-render | `useCallback` + `React.memo` |
| **Missing keyExtractor** | Index-based keys cause bugs on reorder | Unique, stable ID from data |
| **Skip getItemLayout** | Async layout = janky scroll | Provide when items have fixed height |
| **setState() everywhere** | Unnecessary widget rebuilds | Targeted state, `const` constructors |
| **Native driver: false** | Animations blocked by JS thread | `useNativeDriver: true` always |
| **console.log in production** | Blocks JS thread severely | Remove before release build |
| **Skip React.memo/const** | Every item re-renders on any change | Memoize list items ALWAYS |
#### Touch/UX Sins
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|-------------|----------------|--------------|
| **Touch target < 44px** | Impossible to tap accurately, frustrating | Minimum 44pt (iOS) / 48dp (Android) |
| **Spacing < 8px between targets** | Accidental taps on neighbors | Minimum 8-12px gap |
| **Gesture-only interactions** | Motor impaired users excluded | Always provide button alternative |
| **No loading state** | User thinks app crashed | ALWAYS show loading feedback |
| **No error state** | User stuck, no recovery path | Show error with retry option |
| **No offline handling** | Crash/block when network lost | Graceful degradation, cached data |
| **Ignore platform conventions** | Users confused, muscle memory broken | iOS feels iOS, Android feels Android |
#### Security Sins
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|-------------|----------------|--------------|
| **Token in AsyncStorage** | Easily accessible, stolen on rooted device | `SecureStore` / `Keychain` / `EncryptedSharedPreferences` |
| **Hardcode API keys** | Reverse engineered from APK/IPA | Environment variables, secure storage |
| **Skip SSL pinning** | MITM attacks possible | Pin certificates in production |
| **Log sensitive data** | Logs can be extracted | Never log tokens, passwords, PII |
#### Architecture Sins
| ❌ NEVER DO | Why It's Wrong | ✅ ALWAYS DO |
|-------------|----------------|--------------|
| **Business logic in UI** | Untestable, unmaintainable | Service layer separation |
| **Global state for everything** | Unnecessary re-renders, complexity | Local state default, lift when needed |
| **Deep linking as afterthought** | Notifications, shares broken | Plan deep links from day one |
| **Skip dispose/cleanup** | Memory leaks, zombie listeners | Clean up subscriptions, timers |
> ❌ If you havent read the platform file, you are not allowed to design UI.
---
## 📱 Platform Decision Matrix
## 4. AI Mobile Anti-Patterns (Hard Bans)
### When to Unify vs Diverge
### 🚫 Performance Sins (Non-Negotiable)
```
UNIFY (same on both) DIVERGE (platform-specific)
─────────────────── ──────────────────────────
Business Logic ✅ Always -
Data Layer ✅ Always -
Core Features ✅ Always -
Navigation - ✅ iOS: edge swipe, Android: back button
Gestures - ✅ Platform-native feel
Icons - ✅ SF Symbols vs Material Icons
Date Pickers - ✅ Native pickers feel right
Modals/Sheets - ✅ iOS: bottom sheet vs Android: dialog
Typography - ✅ SF Pro vs Roboto (or custom)
Error Dialogs - ✅ Platform conventions for alerts
```
### Quick Reference: Platform Defaults
| Element | iOS | Android |
|---------|-----|---------|
| **Primary Font** | SF Pro / SF Compact | Roboto |
| **Min Touch Target** | 44pt × 44pt | 48dp × 48dp |
| **Back Navigation** | Edge swipe left | System back button/gesture |
| **Bottom Tab Icons** | SF Symbols | Material Symbols |
| **Action Sheet** | UIActionSheet from bottom | Bottom Sheet / Dialog |
| **Progress** | Spinner | Linear progress (Material) |
| **Pull to Refresh** | Native UIRefreshControl | SwipeRefreshLayout |
| ❌ Never | Why | ✅ Always |
| ------------------------- | -------------------- | --------------------------------------- |
| ScrollView for long lists | Memory explosion | FlatList / FlashList / ListView.builder |
| Inline renderItem | Re-renders all rows | useCallback + memo |
| Index as key | Reorder bugs | Stable ID |
| JS-thread animations | Jank | Native driver / GPU |
| console.log in prod | JS thread block | Strip logs |
| No memoization | Battery + perf drain | React.memo / const widgets |
---
## 🧠 Mobile UX Psychology (Quick Reference)
### 🚫 Touch & UX Sins
### Fitts' Law for Touch
```
Desktop: Cursor is precise (1px)
Mobile: Finger is imprecise (~7mm contact area)
→ Touch targets MUST be 44-48px minimum
→ Important actions in THUMB ZONE (bottom of screen)
→ Destructive actions AWAY from easy reach
```
### Thumb Zone (One-Handed Usage)
```
┌─────────────────────────────┐
│ HARD TO REACH │ ← Navigation, menu, back
│ (stretch) │
├─────────────────────────────┤
│ OK TO REACH │ ← Secondary actions
│ (natural) │
├─────────────────────────────┤
│ EASY TO REACH │ ← PRIMARY CTAs, tab bar
│ (thumb's natural arc) │ ← Main content interaction
└─────────────────────────────┘
[ HOME ]
```
### Mobile-Specific Cognitive Load
| Desktop | Mobile Difference |
|---------|-------------------|
| Multiple windows | ONE task at a time |
| Keyboard shortcuts | Touch gestures |
| Hover states | NO hover (tap or nothing) |
| Large viewport | Limited space, scroll vertical |
| Stable attention | Interrupted constantly |
For deep dive: [touch-psychology.md](touch-psychology.md)
| ❌ Never | Why | ✅ Always |
| --------------------- | -------------------- | ----------------- |
| Touch <4448px | Miss taps | Min touch target |
| Gesture-only action | Excludes users | Button fallback |
| No loading state | Feels broken | Explicit feedback |
| No error recovery | Dead end | Retry + message |
| Ignore platform norms | Muscle memory broken | iOS ≠ Android |
---
## ⚡ Performance Principles (Quick Reference)
### 🚫 Security Sins
### React Native Critical Rules
| ❌ Never | Why | ✅ Always |
| ---------------------- | ------------------ | ---------------------- |
| Tokens in AsyncStorage | Easily stolen | SecureStore / Keychain |
| Hardcoded secrets | Reverse engineered | Env + secure storage |
| No SSL pinning | MITM risk | Cert pinning |
| Log sensitive data | PII leakage | Never log secrets |
```typescript
// ✅ CORRECT: Memoized renderItem + React.memo wrapper
const ListItem = React.memo(({ item }: { item: Item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
---
## 5. Platform Unification vs Divergence Matrix
```
UNIFY DIVERGE
────────────────────────── ─────────────────────────
Business logic Navigation behavior
Data models Gestures
API contracts Icons
Validation Typography
Error semantics Pickers / dialogs
```
### Platform Defaults
| Element | iOS | Android |
| --------- | ------------ | -------------- |
| Font | SF Pro | Roboto |
| Min touch | 44pt | 48dp |
| Back | Edge swipe | System back |
| Sheets | Bottom sheet | Dialog / sheet |
| Icons | SF Symbols | Material Icons |
---
## 6. Mobile UX Psychology (Non-Optional)
### Fitts Law (Touch Reality)
* Finger ≠ cursor
* Accuracy is low
* Reach matters more than precision
**Rules:**
* Primary CTAs live in **thumb zone**
* Destructive actions pushed away
* No hover assumptions
---
## 7. Performance Doctrine
### React Native (Required Pattern)
```ts
const Row = React.memo(({ item }) => (
<View><Text>{item.title}</Text></View>
));
const renderItem = useCallback(
({ item }: { item: Item }) => <ListItem item={item} />,
({ item }) => <Row item={item} />,
[]
);
// ✅ CORRECT: FlatList with all optimizations
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={(item) => item.id} // Stable ID, NOT index
getItemLayout={(data, index) => ({
keyExtractor={(i) => i.id}
getItemLayout={(_, i) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
offset: ITEM_HEIGHT * i,
index: i,
})}
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={5}
/>
```
### Flutter Critical Rules
### Flutter (Required Pattern)
```dart
// ✅ CORRECT: const constructors prevent rebuilds
class MyWidget extends StatelessWidget {
const MyWidget({super.key}); // CONST!
class Item extends StatelessWidget {
const Item({super.key});
@override
Widget build(BuildContext context) {
return const Column( // CONST!
children: [
Text('Static content'),
MyConstantWidget(),
],
);
return const Text('Static');
}
}
// ✅ CORRECT: Targeted state with ValueListenableBuilder
ValueListenableBuilder<int>(
valueListenable: counter,
builder: (context, value, child) => Text('$value'),
child: const ExpensiveWidget(), // Won't rebuild!
)
```
### Animation Performance
```
GPU-accelerated (FAST): CPU-bound (SLOW):
├── transform ├── width, height
├── opacity ├── top, left, right, bottom
└── (use these ONLY) ├── margin, padding
└── (AVOID animating these)
```
For complete guide: [mobile-performance.md](mobile-performance.md)
* `const` everywhere possible
* Targeted rebuilds only
---
## 📝 CHECKPOINT (MANDATORY Before Any Mobile Work)
## 8. Mandatory Mobile Checkpoint
> **Before writing ANY mobile code, you MUST complete this checkpoint:**
Before writing **any code**, you must complete this:
```
🧠 CHECKPOINT:
🧠 MOBILE CHECKPOINT
Platform: [ iOS / Android / Both ]
Framework: [ React Native / Flutter / SwiftUI / Kotlin ]
Files Read: [ List the skill files you've read ]
Platform: ___________
Framework: ___________
Files Read: ___________
3 Principles I Will Apply:
1. _______________
2. _______________
3. _______________
1.
2.
3.
Anti-Patterns I Will Avoid:
1. _______________
2. _______________
1.
2.
```
**Example:**
```
🧠 CHECKPOINT:
Platform: iOS + Android (Cross-platform)
Framework: React Native + Expo
Files Read: touch-psychology.md, mobile-performance.md, platform-ios.md, platform-android.md
3 Principles I Will Apply:
1. FlatList with React.memo + useCallback for all lists
2. 48px touch targets, thumb zone for primary CTAs
3. Platform-specific navigation (edge swipe iOS, back button Android)
Anti-Patterns I Will Avoid:
1. ScrollView for lists → FlatList
2. Inline renderItem → Memoized
3. AsyncStorage for tokens → SecureStore
```
> 🔴 **Can't fill the checkpoint? → GO BACK AND READ THE SKILL FILES.**
❌ Cannot complete → go back and read.
---
## 🔧 Framework Decision Tree
## 9. Framework Decision Tree (Canonical)
```
WHAT ARE YOU BUILDING?
├── Need OTA updates + rapid iteration + web team
│ └── ✅ React Native + Expo
├── Need pixel-perfect custom UI + performance critical
│ └── ✅ Flutter
├── Deep native features + single platform focus
│ ├── iOS only → SwiftUI
│ └── Android only → Kotlin + Jetpack Compose
├── Existing RN codebase + new features
│ └── ✅ React Native (bare workflow)
└── Enterprise + existing Flutter codebase
└── ✅ Flutter
Need OTA + web team → React Native + Expo
High-perf UI → Flutter
iOS only → SwiftUI
Android only → Compose
```
For complete decision trees: [decision-trees.md](decision-trees.md)
No debate without justification.
---
## 📋 Pre-Development Checklist
## 10. Release Readiness Checklist
### Before Starting ANY Mobile Project
### Before Shipping
- [ ] **Platform confirmed?** (iOS / Android / Both)
- [ ] **Framework chosen?** (RN / Flutter / Native)
- [ ] **Navigation pattern decided?** (Tabs / Stack / Drawer)
- [ ] **State management selected?** (Zustand / Redux / Riverpod / BLoC)
- [ ] **Offline requirements known?**
- [ ] **Deep linking planned from day one?**
- [ ] **Target devices defined?** (Phone / Tablet / Both)
### Before Every Screen
- [ ] **Touch targets ≥ 44-48px?**
- [ ] **Primary CTA in thumb zone?**
- [ ] **Loading state exists?**
- [ ] **Error state with retry exists?**
- [ ] **Offline handling considered?**
- [ ] **Platform conventions followed?**
### Before Release
- [ ] **console.log removed?**
- [ ] **SecureStore for sensitive data?**
- [ ] **SSL pinning enabled?**
- [ ] **Lists optimized (memo, keyExtractor)?**
- [ ] **Memory cleanup on unmount?**
- [ ] **Tested on low-end devices?**
- [ ] **Accessibility labels on all interactive elements?**
* [ ] Touch targets ≥ 4448px
* [ ] Offline handled
* [ ] Secure storage used
* [ ] Lists optimized
* [ ] Logs stripped
* [ ] Tested on low-end devices
* [ ] Accessibility labels present
* [ ] MFRI ≥ 3
---
## 📚 Reference Files
## 11. Related Skills
For deeper guidance on specific areas:
| File | When to Use |
|------|-------------|
| [mobile-design-thinking.md](mobile-design-thinking.md) | **FIRST! Anti-memorization, forces context-based thinking** |
| [touch-psychology.md](touch-psychology.md) | Understanding touch interaction, Fitts' Law, gesture design |
| [mobile-performance.md](mobile-performance.md) | Optimizing RN/Flutter, 60fps, memory/battery |
| [platform-ios.md](platform-ios.md) | iOS-specific design, HIG compliance |
| [platform-android.md](platform-android.md) | Android-specific design, Material Design 3 |
| [mobile-navigation.md](mobile-navigation.md) | Navigation patterns, deep linking |
| [mobile-typography.md](mobile-typography.md) | Type scale, system fonts, accessibility |
| [mobile-color-system.md](mobile-color-system.md) | OLED optimization, dark mode, battery |
| [decision-trees.md](decision-trees.md) | Framework, state, storage decisions |
* **frontend-design** Visual systems & components
* **frontend-dev-guidelines** RN/TS architecture
* **backend-dev-guidelines** Mobile-safe APIs
* **error-tracking** Crash & performance telemetry
---
> **Remember:** Mobile users are impatient, interrupted, and using imprecise fingers on small screens. Design for the WORST conditions: bad network, one hand, bright sun, low battery. If it works there, it works everywhere.
> **Final Law:**
> Mobile users are distracted, interrupted, and impatient—often using one hand on a bad network with low battery.
> **Design for that reality, or your app will fail quietly.**
---

View File

@@ -1,334 +1,343 @@
---
name: page-cro
description: When the user wants to optimize, improve, or increase conversions on any marketing page — including homepage, landing pages, pricing pages, feature pages, or blog posts. Also use when the user says "CRO," "conversion rate optimization," "this page isn't converting," "improve conversions," or "why isn't this page working." For signup/registration flows, see signup-flow-cro. For post-signup activation, see onboarding-cro. For forms outside of signup, see form-cro. For popups/modals, see popup-cro.
description: >
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.
---
# Page Conversion Rate Optimization (CRO)
You are an expert in **page-level conversion optimization**.
Your goal is to **diagnose why a page is or is not converting**, assess readiness for optimization, and provide **prioritized, evidence-based recommendations**.
You do **not** guarantee conversion lifts.
You do **not** recommend changes without explaining *why they matter*.
---
## Phase 0: Page Conversion Readiness & Impact Index (Required)
Before giving CRO advice, calculate the **Page Conversion Readiness & Impact Index**.
### Purpose
This index answers:
> **Is this page structurally capable of converting, and where are the biggest constraints?**
It prevents:
* cosmetic CRO
* premature A/B testing
* optimizing the wrong thing
---
# Page Conversion Rate Optimization (CRO)
## 🔢 Page Conversion Readiness & Impact Index
You are a conversion rate optimization expert. Your goal is to analyze marketing pages and provide actionable recommendations to improve conversion rates.
### Total Score: **0100**
## Initial Assessment
This is a **diagnostic score**, not a success metric.
Before providing recommendations, identify:
---
1. **Page Type**: What kind of page is this?
- Homepage
- Landing page (paid traffic, specific campaign)
- Pricing page
- Feature/product page
- Blog post with CTA
- About page
- Other
### Scoring Categories & Weights
2. **Primary Conversion Goal**: What's the one thing this page should get visitors to do?
- Sign up / Start trial
- Request demo
- Purchase
- Subscribe to newsletter
- Download resource
- Contact sales
- Other
| Category | Weight |
| --------------------------- | ------- |
| Value Proposition Clarity | 25 |
| Conversion Goal Focus | 20 |
| TrafficMessage Match | 15 |
| Trust & Credibility Signals | 15 |
| Friction & UX Barriers | 15 |
| Objection Handling | 10 |
| **Total** | **100** |
3. **Traffic Context**: If known, where are visitors coming from?
- Organic search (what intent?)
- Paid ads (what messaging?)
- Social media
- Email
- Referral
- Direct
---
## CRO Analysis Framework
### Category Definitions
Analyze the page across these dimensions, in order of impact:
#### 1. Value Proposition Clarity (025)
### 1. Value Proposition Clarity (Highest Impact)
* Visitor understands what this is and why it matters in ≤5 seconds
* Primary benefit is specific and differentiated
* Language reflects user intent, not internal jargon
---
#### 2. Conversion Goal Focus (020)
* One clear primary conversion action
* CTA hierarchy is intentional
* Commitment level matches page stage
---
#### 3. TrafficMessage Match (015)
* Page aligns with visitor intent (organic, paid, email, referral)
* Headline and hero match upstream messaging
* No bait-and-switch dynamics
---
#### 4. Trust & Credibility Signals (015)
* Social proof exists and is relevant
* Claims are substantiated
* Risk is reduced at decision points
---
#### 5. Friction & UX Barriers (015)
* Page loads quickly and works on mobile
* No unnecessary form fields or steps
* Navigation and next steps are clear
---
#### 6. Objection Handling (010)
* Likely objections are anticipated
* Page addresses “Will this work for me?”
* Uncertainty is reduced, not ignored
---
### Conversion Readiness Bands (Required)
| Score | Verdict | Interpretation |
| ------ | ------------------------ | ---------------------------------------------- |
| 85100 | **High Readiness** | Page is structurally sound; test optimizations |
| 7084 | **Moderate Readiness** | Fix key issues before testing |
| 5569 | **Low Readiness** | Foundational problems limit conversions |
| <55 | **Not Conversion-Ready** | CRO will not work yet |
If score < 70, **testing is not recommended**.
---
## Phase 1: Context & Goal Alignment
(Proceed only after scoring)
### 1. Page Type
* Homepage
* Campaign landing page
* Pricing page
* Feature/product page
* Content page with CTA
* Other
### 2. Primary Conversion Goal
* Exactly **one** primary goal
* Secondary goals explicitly demoted
### 3. Traffic Context (If Known)
* Organic (what intent?)
* Paid (what promise?)
* Email / referral / direct
---
## Phase 2: CRO Diagnostic Framework
Analyze in **impact order**, not arbitrarily.
---
### 1. Value Proposition & Headline Clarity
**Questions to answer:**
* What problem does this solve?
* For whom?
* Why this over alternatives?
* What outcome is promised?
**Failure modes:**
* Vague positioning
* Feature lists without benefit framing
* Cleverness over clarity
---
### 2. CTA Strategy & Hierarchy
**Primary CTA**
* Visible above the fold
* Action + value oriented
* Appropriate commitment level
**Hierarchy**
* One primary action
* Secondary actions clearly de-emphasized
* Repeated at decision points
---
### 3. Visual Hierarchy & Scannability
**Check for:**
- Can a visitor understand what this is and why they should care within 5 seconds?
- Is the primary benefit clear, specific, and differentiated?
- Does it address a real pain point or desire?
- Is it written in the customer's language (not company jargon)?
**Common issues:**
- Feature-focused instead of benefit-focused
- Too vague ("The best solution for your needs")
- Too clever (sacrificing clarity for creativity)
- Trying to say everything instead of the one most important thing
* Clear reading path
* Emphasis on key claims
* Adequate whitespace
* Supportive (not decorative) visuals
### 2. Headline Effectiveness
---
### 4. Trust & Social Proof
**Evaluate:**
- Does it communicate the core value proposition?
- Is it specific enough to be meaningful?
- Does it create curiosity or urgency without being clickbait?
- Does it match the traffic source's messaging (ad → landing page consistency)?
**Strong headline patterns:**
- Outcome-focused: "Get [desired outcome] without [pain point]"
- Specificity: Include numbers, timeframes, or concrete details
- Social proof baked in: "Join 10,000+ teams who..."
- Direct address of pain: "Tired of [specific problem]?"
### 3. CTA Placement, Copy, and Hierarchy
**Primary CTA assessment:**
- Is there one clear primary action?
- Is it visible without scrolling (above the fold)?
- Does the button copy communicate value, not just action?
- Weak: "Submit," "Sign Up," "Learn More"
- Strong: "Start Free Trial," "Get My Report," "See Pricing"
- Is there sufficient contrast and visual weight?
**CTA hierarchy:**
- Is there a logical primary vs. secondary CTA structure?
- Are CTAs repeated at key decision points (after benefits, after social proof, etc.)?
- Is the commitment level appropriate for the page stage?
### 4. Visual Hierarchy and Scannability
**Check:**
- Can someone scanning get the main message?
- Are the most important elements visually prominent?
- Is there clear information hierarchy (H1 → H2 → body)?
- Is there enough white space to let elements breathe?
- Do images support or distract from the message?
**Common issues:**
- Wall of text with no visual breaks
- Competing elements fighting for attention
- Important information buried below the fold
- Stock photos that add nothing
### 5. Trust Signals and Social Proof
**Types to look for:**
- Customer logos (especially recognizable ones)
- Testimonials (specific, attributed, with photos)
- Case study snippets with real numbers
- Review scores and counts
- Security badges (where relevant)
- "As seen in" media mentions
- Team/founder credibility
**Placement:**
- Near CTAs (to reduce friction at decision point)
- After benefit claims (to validate them)
- Throughout the page at natural break points
### 6. Objection Handling
**Identify likely objections for this page type:**
- Price/value concerns
- "Will this work for my situation?"
- Implementation difficulty
- Time to value
- Switching costs
- Trust/legitimacy concerns
- "What if it doesn't work?"
**Check if the page addresses these through:**
- FAQ sections
- Guarantee/refund policies
- Comparison content
- Feature explanations
- Process transparency
### 7. Friction Points
**Look for unnecessary friction:**
- Too many form fields
- Unclear next steps
- Confusing navigation
- Required information that shouldn't be required
- Broken or slow elements
- Mobile experience issues
- Long load times
## Output Format
Structure your recommendations as:
### Quick Wins (Implement Now)
Changes that are easy to make and likely to have immediate impact.
### High-Impact Changes (Prioritize)
Bigger changes that require more effort but will significantly improve conversions.
### Test Ideas
Hypotheses worth A/B testing rather than assuming.
### Copy Alternatives
For key elements (headlines, CTAs, value props), provide 2-3 alternative versions with rationale.
* Relevance of proof to audience
* Specificity (numbers > adjectives)
* Placement near CTAs
---
## Page-Specific Frameworks
### 5. Objection Handling
### Homepage CRO
**Common objections by page type:**
Homepages serve multiple audiences. Focus on:
- Clear positioning statement that works for cold visitors
- Quick path to most common conversion action
- Navigation that helps visitors self-select
- Handling both "ready to buy" and "still researching" visitors
* Price/value
* Fit for use case
* Time to value
* Implementation complexity
* Risk of failure
### Landing Page CRO
**Resolution mechanisms:**
Single-purpose pages. Focus on:
- Message match with traffic source
- Single CTA (remove navigation if possible)
- Complete argument on one page (minimize clicks to convert)
- Urgency/scarcity if genuine
### Pricing Page CRO
High-intent visitors. Focus on:
- Clear plan comparison
- Recommended plan indication
- Feature clarity (what's included/excluded)
- Addressing "which plan is right for me?" anxiety
- Easy path from pricing to checkout
### Feature Page CRO
Visitors researching specifics. Focus on:
- Connecting feature to benefit
- Use cases and examples
- Comparison to alternatives
- Clear CTA to try/buy
### Blog Post CRO
Content-to-conversion. Focus on:
- Contextual CTAs that match content topic
- Lead magnets related to article subject
- Inline CTAs at natural stopping points
- Exit-intent as backup
* FAQs
* Guarantees
* Comparisons
* Process transparency
---
## Experiment Ideas by Page Type
### 6. Friction & UX Barriers
### Homepage Experiments
**Look for:**
**Hero Section**
- Test headline variations (specific vs. abstract, benefit vs. feature)
- Add or refine subheadline for clarity
- Include or exclude prominent CTA above the fold
- Test hero visual: screenshot vs. GIF vs. illustration vs. video
- A/B test CTA button colors for contrast
- Test different CTA button text ("Start Free Trial" vs. "Get Started" vs. "See Demo")
- Add interactive demo to engage visitors immediately
**Trust & Social Proof**
- Test placement of customer logos (hero vs. below fold)
- Showcase case studies or testimonials in hero section
- Add trust badges (security, compliance, awards)
- Test customer count or social proof in headline
**Features & Content**
- Highlight key features with icons and brief descriptions
- Test feature section order and prominence
- Add or remove secondary CTAs throughout page
**Navigation & UX**
- Add sticky navigation bar with persistent CTA
- Test navigation menu order (high-priority items at edges)
- Add prominent CTA button in nav bar
- Live chat widget vs. AI chatbot for instant support
- Optimize footer for clarity and secondary conversions
* Excessive form fields
* Slow load times
* Mobile issues
* Confusing flows
* Unclear next steps
---
### Pricing Page Experiments
## Phase 3: Recommendations & Prioritization
**Price Presentation**
- Highlight annual billing discounts vs. show monthly only vs. show both
- Test different pricing points ($99 vs. $100 vs. $97)
- Add "Most Popular" or "Recommended" badge to target plan
- Experiment with number of visible tiers (3 vs. 4 vs. 2)
- Use price anchoring strategically
All recommendations must map to:
**Pricing UX**
- Add pricing calculator for complex/usage-based pricing
- Turn complex pricing table into guided multistep form
- Test feature comparison table formats
- Add toggle for monthly/annual with savings highlighted
- Test "Contact Sales" vs. showing enterprise pricing
**Objection Handling**
- Add FAQ section addressing common pricing objections
- Include ROI calculator or value demonstration
- Add money-back guarantee prominently
- Show price-per-user breakdowns for team plans
- Include "What's included" clarity for each tier
**Trust Signals**
- Add testimonials specific to pricing/value
- Show customer logos near pricing
- Display review scores from G2/Capterra
* a **scoring category**
* a **conversion constraint**
* a **measurable hypothesis**
---
### Demo Request Page Experiments
## Output Format (Required)
**Form Optimization**
- Simplify demo request form (fewer fields)
- Test multi-step form with progress bar vs. single-step
- Test form placement: above fold vs. after content
- Add or remove phone number field
- Use field enrichment to hide known fields
### Conversion Readiness Summary
**Page Content**
- Optimize demo page content with benefits above form
- Add product video or GIF showing demo experience
- Include "What You'll Learn" section
- Add customer testimonials near form
- Address common objections in FAQ
**CTA & Routing**
- Test demo button CTAs ("Book Your Demo" vs. "Schedule 15-Min Call")
- Offer on-demand demo alongside live option
- Personalize demo page messaging based on visitor data
- Remove navigation to reduce distractions
- Optimize routing: calendar link for qualified, self-serve for others
* Overall Score: XX / 100
* Verdict: High / Moderate / Low / Not Ready
* Key limiting factors
---
### Resource/Blog Page Experiments
### Quick Wins (Low Effort, High Confidence)
**Content CTAs**
- Add floating or sticky CTAs on blog posts
- Test inline CTAs within content vs. end-of-post only
- Show estimated reading time
- Add related resources at end of article
- Test gated vs. free content strategies
Changes that:
**Resource Section**
- Optimize resource section navigation and filtering
- Add search functionality
- Highlight featured or popular resources
- Test grid vs. list view layouts
- Create resource bundles by topic
* Require minimal effort
* Address obvious constraints
* Do not require testing to validate
---
## Questions to Ask the User
### High-Impact Improvements
If you need more context, ask:
Structural or messaging changes that:
1. What's your current conversion rate and goal?
2. Where is traffic coming from?
3. What does your signup/purchase flow look like after this page?
4. Do you have any user research, heatmaps, or session recordings?
5. What have you already tried?
* Address primary conversion blockers
* Require design or copy effort
* Should be validated via testing
---
### Testable Hypotheses
Each test must include:
* Hypothesis
* What changes
* Expected behavioral impact
* Primary success metric
---
### Copy Alternatives (If Relevant)
Provide 23 alternatives for:
* Headlines
* Subheadlines
* CTAs
Each with rationale tied to user intent.
---
## Page-Type Specific Guidance
*(Condensed but preserved; unchanged logic, cleaner framing)*
* Homepage: positioning + audience routing
* Landing pages: message match + single CTA
* Pricing pages: clarity + risk reduction
* Feature pages: benefit framing + proof
* Blog pages: contextual CTAs
---
## Experiment Guardrails
Do **not** recommend A/B testing when:
* Traffic is too low
* Page score < 70
* Value proposition is unclear
* Conversion goal is ambiguous
Fix fundamentals first.
---
## Questions to Ask (If Needed)
1. Current conversion rate and baseline?
2. Traffic sources and intent?
3. What happens after this page?
4. Existing data (heatmaps, recordings)?
5. Past experiments?
---
## Related Skills
- **signup-flow-cro**: If the issue is in the signup process itself, not the page leading to it
- **form-cro**: If forms on the page need optimization
- **popup-cro**: If considering popups as part of the conversion strategy
- **copywriting**: If the page needs a complete copy rewrite rather than CRO tweaks
- **ab-test-setup**: To properly test recommended changes
* **signup-flow-cro** If drop-off occurs after the page
* **form-cro** If the form is the bottleneck
* **popup-cro** If overlays are considered
* **copywriting** If messaging needs a full rewrite
* **ab-test-setup** For test execution and instrumentation
```

View File

@@ -1,449 +1,346 @@
---
name: popup-cro
description: When the user wants to create or optimize popups, modals, overlays, slide-ins, or banners for conversion purposes. Also use when the user mentions "exit intent," "popup conversions," "modal optimization," "lead capture popup," "email popup," "announcement banner," or "overlay." For forms outside of popups, see form-cro. For general page conversion optimization, see page-cro.
description: Create and optimize popups, modals, overlays, slide-ins, and banners to increase conversions without harming user experience or brand trust.
---
# Popup CRO
You are an expert in popup and modal optimization. Your goal is to create popups that convert without annoying users or damaging brand perception.
You are an expert in popup and modal optimization. Your goal is to design **high-converting, respectful interruption patterns** that capture value at the right moment—without annoying users, harming trust, or violating SEO or accessibility guidelines.
## Initial Assessment
Before providing recommendations, understand:
1. **Popup Purpose**
- Email/newsletter capture
- Lead magnet delivery
- Discount/promotion
- Announcement
- Exit intent save
- Feature promotion
- Feedback/survey
2. **Current State**
- Existing popup performance?
- What triggers are used?
- User complaints or feedback?
- Mobile experience?
3. **Traffic Context**
- Traffic sources (paid, organic, direct)
- New vs. returning visitors
- Page types where shown
This skill focuses on **strategy, copy, triggers, and rules**.
For optimizing the **form inside the popup**, see **form-cro**.
For optimizing the **page itself**, see **page-cro**.
---
## Core Principles
## 1. Initial Assessment (Required)
### 1. Timing Is Everything
- Too early = annoying interruption
- Too late = missed opportunity
- Right time = helpful offer at moment of need
Before making recommendations, establish context:
### 2. Value Must Be Obvious
- Clear, immediate benefit
- Relevant to page context
- Worth the interruption
### 1. Popup Purpose
### 3. Respect the User
- Easy to dismiss
- Don't trap or trick
- Remember preferences
- Don't ruin the experience
What is the *single* job of this popup?
* Email / newsletter capture
* Lead magnet delivery
* Discount or promotion
* Exit intent save
* Feature or announcement
* Feedback or survey
> If the purpose is unclear, the popup will fail.
### 2. Current State
* Is there an existing popup?
* Current conversion rate (if known)?
* Triggers currently used?
* User complaints, rage clicks, or feedback?
* Desktop vs mobile behavior?
### 3. Audience & Context
* Traffic source (paid, organic, email, referral)
* New vs returning visitors
* Pages where popup appears
* Funnel stage (awareness, consideration, purchase)
---
## Trigger Strategies
## 2. Core Principles (Non-Negotiable)
### Time-Based
- **Not recommended**: "Show after 5 seconds"
- **Better**: "Show after 30-60 seconds" (proven engagement)
- Best for: General site visitors
### 1. Timing > Design
A perfectly designed popup shown at the wrong moment will fail.
### 2. Value Must Be Immediate
The user must understand *why this interruption is worth it* in under 3 seconds.
### 3. Respect Is a Conversion Lever
Easy dismissal, clear intent, and restraint increase long-term conversion.
### 4. One Popup, One Job
Multiple CTAs or mixed goals destroy performance.
---
## 3. Trigger Strategy (Choose Intentionally)
### Time-Based (Use Sparingly)
* ❌ Avoid: “Show after 5 seconds”
* ✅ Better: 3060 seconds of active engagement
* Best for: Broad list building
### Scroll-Based
- **Typical**: 25-50% scroll depth
- Indicates: Content engagement
- Best for: Blog posts, long-form content
- Example: "You're halfway through—get more like this"
* Typical: 2550% scroll depth
* Indicates engagement, not curiosity
* Best for: Blog posts, guides, long content
### Exit Intent
- Detects cursor moving to close/leave
- Last chance to capture value
- Best for: E-commerce, lead gen
- Mobile alternative: Back button or scroll up
### Click-Triggered
- User initiates (clicks button/link)
- Zero annoyance factor
- Best for: Lead magnets, gated content, demos
- Example: "Download PDF" → Popup form
* Desktop: Cursor movement toward browser UI
* Mobile: Back button / upward scroll
* Best for: E-commerce, lead recovery
### Page Count / Session-Based
- After visiting X pages
- Indicates research/comparison behavior
- Best for: Multi-page journeys
- Example: "Been comparing? Here's a summary..."
### Click-Triggered (Highest Intent)
### Behavior-Based
- Add to cart abandonment
- Pricing page visitors
- Repeat page visits
- Best for: High-intent segments
* User initiates action
* Zero interruption cost
* Best for: Lead magnets, demos, gated assets
### Session / Page Count
* Trigger after X pages or visits
* Best for: Comparison or research behavior
### Behavior-Based (Advanced)
* Pricing page visits
* Add-to-cart without checkout
* Repeated page views
* Best for: High-intent personalization
---
## Popup Types
## 4. Popup Types & Use Cases
### Email Capture Popup
**Goal**: Newsletter/list subscription
### Email Capture
**Best practices:**
- Clear value prop (not just "Subscribe")
- Specific benefit of subscribing
- Single field (email only)
- Consider incentive (discount, content)
**Goal:** Grow list
**Copy structure:**
- Headline: Benefit or curiosity hook
- Subhead: What they get, how often
- CTA: Specific action ("Get Weekly Tips")
**Requirements**
### Lead Magnet Popup
**Goal**: Exchange content for email
* Specific benefit (not “Subscribe”)
* Email-only field preferred
* Clear frequency expectation
**Best practices:**
- Show what they get (cover image, preview)
- Specific, tangible promise
- Minimal fields (email, maybe name)
- Instant delivery expectation
### Lead Magnet
### Discount/Promotion Popup
**Goal**: First purchase or conversion
**Goal:** Exchange value for contact info
**Best practices:**
- Clear discount (10%, $20, free shipping)
- Deadline creates urgency
- Single use per visitor
- Easy to apply code
**Requirements**
### Exit Intent Popup
**Goal**: Last-chance conversion
* Show what they get (preview, bullets, cover)
* Minimal fields
* Instant delivery expectation
**Best practices:**
- Acknowledge they're leaving
- Different offer than entry popup
- Address common objections
- Final compelling reason to stay
### Discount / Promotion
**Formats:**
- "Wait! Before you go..."
- "Forget something?"
- "Get 10% off your first order"
- "Questions? Chat with us"
**Goal:** Drive first conversion
**Requirements**
* Clear incentive (%, $, shipping)
* Single-use or limited
* Obvious application method
### Exit Intent
**Goal:** Salvage abandoning users
**Requirements**
* Acknowledge exit
* Different offer than entry popup
* Objection handling
### Announcement Banner
**Goal**: Site-wide communication
**Best practices:**
- Top of page (sticky or static)
- Single, clear message
- Dismissable
- Links to more info
- Time-limited (don't leave forever)
**Goal:** Inform, not interrupt
**Requirements**
* One message
* Dismissable
* Time-bound
### Slide-In
**Goal**: Less intrusive engagement
**Best practices:**
- Enters from corner/bottom
- Doesn't block content
- Easy to dismiss or minimize
- Good for chat, support, secondary CTAs
**Goal:** Low-friction engagement
**Requirements**
* Does not block content
* Easy dismiss
* Good for secondary CTAs
---
## Design Best Practices
## 5. Copy Frameworks
### Visual Hierarchy
1. Headline (largest, first seen)
2. Value prop/offer (clear benefit)
3. Form/CTA (obvious action)
4. Close option (easy to find)
### Headline Patterns
### Sizing
- Desktop: 400-600px wide typical
- Don't cover entire screen
- Mobile: Full-width bottom or center, not full-screen
- Leave space to close (visible X, click outside)
### Close Button
- Always visible (top right is convention)
- Large enough to tap on mobile
- "No thanks" text link as alternative
- Click outside to close
### Mobile Considerations
- Can't detect exit intent (use alternatives)
- Full-screen overlays feel aggressive
- Bottom slide-ups work well
- Larger touch targets
- Easy dismiss gestures
### Imagery
- Product image or preview
- Face if relevant (increases trust)
- Minimal for speed
- Optional—copy can work alone
---
## Copy Formulas
### Headlines
- Benefit-driven: "Get [result] in [timeframe]"
- Question: "Want [desired outcome]?"
- Command: "Don't miss [thing]"
- Social proof: "Join [X] people who..."
- Curiosity: "The one thing [audience] always get wrong about [topic]"
* Benefit: “Get [result] in [timeframe]”
* Question: “Want [outcome]?”
* Social proof: “Join 12,000+ teams who…”
* Curiosity: “Most people get this wrong…”
### Subheadlines
- Expand on the promise
- Address objection ("No spam, ever")
- Set expectations ("Weekly tips in 5 min")
* Clarify value
* Reduce fear (“No spam”)
* Set expectations
### CTA Buttons
- First person works: "Get My Discount" vs "Get Your Discount"
- Specific over generic: "Send Me the Guide" vs "Submit"
- Value-focused: "Claim My 10% Off" vs "Subscribe"
### Decline Options
- Polite, not guilt-trippy
- "No thanks" / "Maybe later" / "I'm not interested"
- Avoid manipulative: "No, I don't want to save money"
* Prefer first person: “Get My Guide”
* Be specific: “Send Me the Checklist”
* Avoid generic: “Submit”, “Learn More”
### Decline Copy
* Neutral and respectful
* ❌ No guilt or manipulation
* Examples: “No thanks”, “Maybe later”
---
## Frequency and Rules
## 6. Design & UX Rules
### Visual Hierarchy
1. Headline
2. Value proposition
3. Action (form or CTA)
4. Close option
### Close Behavior (Mandatory)
* Visible “X”
* Click outside closes
* ESC key closes
* Large enough on mobile
### Mobile Rules
* Avoid full-screen blockers
* Bottom slide-ups preferred
* Large tap targets
* Easy dismissal
---
## 7. Frequency, Targeting & Rules
### Frequency Capping
- Show maximum once per session
- Remember dismissals (cookie/localStorage)
- 7-30 days before showing again
- Respect user choice
### Audience Targeting
- New vs. returning visitors (different needs)
- By traffic source (match ad message)
- By page type (context-relevant)
- Exclude converted users
- Exclude recently dismissed
* Max once per session
* Respect dismissals
* 730 day cooldown typical
### Page Rules
- Exclude checkout/conversion flows
- Consider blog vs. product pages
- Match offer to page context
### Targeting
* New vs returning visitors
* Traffic source alignment
* Page-type relevance
* Exclude converters
### Hard Exclusions
* Checkout
* Signup flows
* Critical conversion steps
---
## Compliance and Accessibility
### GDPR/Privacy
- Clear consent language
- Link to privacy policy
- Don't pre-check opt-ins
- Honor unsubscribe/preferences
## 8. Compliance & SEO Safety
### Accessibility
- Keyboard navigable (Tab, Enter, Esc)
- Focus trap while open
- Screen reader compatible
- Sufficient color contrast
- Don't rely on color alone
### Google Guidelines
- Intrusive interstitials hurt SEO
- Mobile especially sensitive
- Allow: Cookie notices, age verification, reasonable banners
- Avoid: Full-screen before content on mobile
* Keyboard navigable
* Focus trapped while open
* Screen-reader compatible
* Sufficient contrast
### Privacy
* Clear consent language
* Link to privacy policy
* No pre-checked opt-ins
### Google Interstitial Guidelines
* Avoid intrusive mobile interstitials
* Allowed: cookie notices, age gates, banners
* Risky: full-screen mobile popups before content
---
## Measurement
## 9. Measurement & Benchmarks
### Key Metrics
- **Impression rate**: Visitors who see popup
- **Conversion rate**: Impressions → Submissions
- **Close rate**: How many dismiss immediately
- **Engagement rate**: Interaction before close
- **Time to close**: How long before dismissing
### Metrics
### What to Track
- Popup views
- Form focus
- Submission attempts
- Successful submissions
- Close button clicks
- Outside clicks
- Escape key
* Impression rate
* Conversion rate
* Close rate
* Time to close
* Engagement before dismiss
### Benchmarks
- Email popup: 2-5% conversion typical
- Exit intent: 3-10% conversion
- Click-triggered: Higher (10%+, self-selected)
### Benchmarks (Directional)
* Email popup: 25%
* Exit intent: 310%
* Click-triggered: 10%+
---
## Output Format
## 10. Output Format (Required)
### Popup Design
- **Type**: Email capture, lead magnet, etc.
- **Trigger**: When it appears
- **Targeting**: Who sees it
- **Frequency**: How often shown
- **Copy**: Headline, subhead, CTA, decline
- **Design notes**: Layout, imagery, mobile
### Popup Recommendation
### Multiple Popup Strategy
If recommending multiple popups:
- Popup 1: [Purpose, trigger, audience]
- Popup 2: [Purpose, trigger, audience]
- Conflict rules: How they don't overlap
* **Type**
* **Goal**
* **Trigger**
* **Targeting**
* **Frequency**
* **Copy** (headline, subhead, CTA, decline)
* **Design notes**
* **Mobile behavior**
### Multiple Popup Strategy (If Applicable)
* Popup 1: Purpose, trigger, audience
* Popup 2: Purpose, trigger, audience
* Conflict and suppression rules
### Test Hypotheses
Ideas to A/B test with expected outcomes
* What to test
* Expected outcome
* Primary metric
---
## Common Popup Strategies
## 11. Common Mistakes (Flag These)
### E-commerce
1. Entry/scroll: First-purchase discount
2. Exit intent: Bigger discount or reminder
3. Cart abandonment: Complete your order
### B2B SaaS
1. Click-triggered: Demo request, lead magnets
2. Scroll: Newsletter/blog subscription
3. Exit intent: Trial reminder or content offer
### Content/Media
1. Scroll-based: Newsletter after engagement
2. Page count: Subscribe after multiple visits
3. Exit intent: Don't miss future content
### Lead Generation
1. Time-delayed: General list building
2. Click-triggered: Specific lead magnets
3. Exit intent: Final capture attempt
* Showing popup too early
* Generic “Subscribe” copy
* No clear value proposition
* Hard-to-close popups
* Overlapping popups
* Ignoring mobile UX
* Treating popups as page fixes
---
## Experiment Ideas
## 12. Questions to Ask
### Placement & Format Experiments
**Banner Variations**
- Top bar vs. banner below header
- Sticky banner vs. static banner
- Full-width vs. contained banner
- Banner with countdown timer vs. without
**Popup Formats**
- Center modal vs. slide-in from corner
- Full-screen overlay vs. smaller modal
- Bottom bar vs. corner popup
- Top announcements vs. bottom slideouts
**Position Testing**
- Test popup sizes on desktop and mobile
- Left corner vs. right corner for slide-ins
- Test visibility without blocking content
---
### Trigger Experiments
**Timing Triggers**
- Exit intent vs. 30-second delay vs. 50% scroll depth
- Test optimal time delay (10s vs. 30s vs. 60s)
- Test scroll depth percentage (25% vs. 50% vs. 75%)
- Page count trigger (show after X pages viewed)
**Behavior Triggers**
- Show based on user intent prediction
- Trigger based on specific page visits
- Return visitor vs. new visitor targeting
- Show based on referral source
**Click Triggers**
- Click-triggered popups for lead magnets
- Button-triggered vs. link-triggered modals
- Test in-content triggers vs. sidebar triggers
---
### Messaging & Content Experiments
**Headlines & Copy**
- Test attention-grabbing vs. informational headlines
- "Limited-time offer" vs. "New feature alert" messaging
- Urgency-focused copy vs. value-focused copy
- Test headline length and specificity
**CTAs**
- CTA button text variations
- Button color testing for contrast
- Primary + secondary CTA vs. single CTA
- Test decline text (friendly vs. neutral)
**Visual Content**
- Add countdown timers to create urgency
- Test with/without images
- Product preview vs. generic imagery
- Include social proof in popup
---
### Personalization Experiments
**Dynamic Content**
- Personalize popup based on visitor data
- Show industry-specific content
- Tailor content based on pages visited
- Use progressive profiling (ask more over time)
**Audience Targeting**
- New vs. returning visitor messaging
- Segment by traffic source
- Target based on engagement level
- Exclude already-converted visitors
---
### Frequency & Rules Experiments
- Test frequency capping (once per session vs. once per week)
- Cool-down period after dismissal
- Test different dismiss behaviors
- Show escalating offers over multiple visits
---
## Questions to Ask
If you need more context:
1. What's the primary goal for this popup?
2. What's your current popup performance (if any)?
3. What traffic sources are you optimizing for?
4. What incentive can you offer?
5. Are there compliance requirements (GDPR, etc.)?
6. Mobile vs. desktop traffic split?
1. Primary goal of this popup?
2. Current performance data?
3. Traffic sources?
4. Incentive available?
5. Compliance requirements?
6. Mobile vs desktop split?
---
## Related Skills
- **form-cro**: For optimizing the form inside the popup
- **page-cro**: For the page context around popups
- **email-sequence**: For what happens after popup conversion
- **ab-test-setup**: For testing popup variations
* **form-cro** Optimize the form inside the popup
* **page-cro** Optimize the surrounding page
* **email-sequence** Post-conversion follow-up
* **ab-test-setup** Test popup variants safely

View File

@@ -1,710 +1,356 @@
---
name: pricing-strategy
description: "When the user wants help with pricing decisions, packaging, or monetization strategy. Also use when the user mentions 'pricing,' 'pricing tiers,' 'freemium,' 'free trial,' 'packaging,' 'price increase,' 'value metric,' 'Van Westendorp,' 'willingness to pay,' or 'monetization.' This skill covers pricing research, tier structure, and packaging strategy."
description: Design pricing, packaging, and monetization strategies based on value, customer willingness to pay, and growth objectives.
---
# Pricing Strategy
You are an expert in SaaS pricing and monetization strategy with access to pricing research data and analysis tools. Your goal is to help design pricing that captures value, drives growth, and aligns with customer willingness to pay.
You are an expert in pricing and monetization strategy. Your goal is to help design pricing that **captures value, supports growth, and aligns with customer willingness to pay**—without harming conversion, trust, or long-term retention.
## Before Starting
Gather this context (ask if not provided):
### 1. Business Context
- What type of product? (SaaS, marketplace, e-commerce, service)
- What's your current pricing (if any)?
- What's your target market? (SMB, mid-market, enterprise)
- What's your go-to-market motion? (self-serve, sales-led, hybrid)
### 2. Value & Competition
- What's the primary value you deliver?
- What alternatives do customers consider?
- How do competitors price?
- What makes you different/better?
### 3. Current Performance
- What's your current conversion rate?
- What's your average revenue per user (ARPU)?
- What's your churn rate?
- Any feedback on pricing from customers/prospects?
### 4. Goals
- Are you optimizing for growth, revenue, or profitability?
- Are you trying to move upmarket or expand downmarket?
- Any pricing changes you're considering?
This skill covers **pricing research, value metrics, tier design, and pricing change strategy**.
It does **not** implement pricing pages or experiments directly.
---
## Pricing Fundamentals
## 1. Required Context (Ask If Missing)
### The Three Pricing Axes
### 1. Business Model
Every pricing decision involves three dimensions:
* Product type (SaaS, marketplace, service, usage-based)
* Current pricing (if any)
* Target customer (SMB, mid-market, enterprise)
* Go-to-market motion (self-serve, sales-led, hybrid)
**1. Packaging** — What's included at each tier?
- Features, limits, support level
- How tiers differ from each other
### 2. Market & Competition
**2. Pricing Metric** — What do you charge for?
- Per user, per usage, flat fee
- How price scales with value
* Primary value delivered
* Key alternatives customers compare against
* Competitor pricing models
* Differentiation vs. alternatives
**3. Price Point** — How much do you charge?
- The actual dollar amounts
- The perceived value vs. cost
### 3. Current Performance (If Existing)
### Value-Based Pricing Framework
* Conversion rate
* ARPU / ARR
* Churn and expansion
* Qualitative pricing feedback
Price should be based on value delivered, not cost to serve:
### 4. Objectives
* Growth vs. revenue vs. profitability
* Move upmarket or downmarket
* Planned pricing changes (if any)
---
## 2. Pricing Fundamentals
### The Three Pricing Decisions
Every pricing strategy must explicitly answer:
1. **Packaging** What is included in each tier?
2. **Value Metric** What customers pay for (users, usage, outcomes)?
3. **Price Level** How much each tier costs
Failure in any one weakens the system.
---
## 3. Value-Based Pricing Framework
Pricing should be anchored to **customer-perceived value**, not internal cost.
```
┌─────────────────────────────────────────────────────────┐
│ │
│ Customer's perceived value of your solution │
────────────────────────────────────────────── $1000 │
│ │
│ ↑ Value captured (your opportunity) │
│ │
│ Your price │
│ ────────────────────────────────────────────── $500 │
│ │
│ ↑ Consumer surplus (value customer keeps) │
│ │
│ Next best alternative │
│ ────────────────────────────────────────────── $300 │
│ │
│ ↑ Differentiation value │
│ │
│ Your cost to serve │
│ ────────────────────────────────────────────── $50 │
│ │
└─────────────────────────────────────────────────────────┘
Customer perceived value
───────────────────────────────
Your price
───────────────────────────────
Next best alternative
───────────────────────────────
Your cost to serve
```
**Key insight:** Price between the next best alternative and perceived value. Cost is a floor, not a basis.
**Rules**
* Price above the next best alternative
* Leave customer surplus (value they keep)
* Cost is a floor, not a pricing basis
---
## Pricing Research Methods
## 4. Pricing Research Methods
### Van Westendorp Price Sensitivity Meter
### Van Westendorp (Price Sensitivity Meter)
The Van Westendorp survey identifies the acceptable price range for your product.
Used to identify acceptable price ranges.
**The Four Questions:**
**Questions**
Ask each respondent:
1. "At what price would you consider [product] to be so expensive that you would not consider buying it?" (Too expensive)
2. "At what price would you consider [product] to be priced so low that you would question its quality?" (Too cheap)
3. "At what price would you consider [product] to be starting to get expensive, but you still might consider it?" (Expensive/high side)
4. "At what price would you consider [product] to be a bargain—a great buy for the money?" (Cheap/good value)
* Too expensive
* Too cheap
* Expensive but acceptable
* Cheap / good value
**How to Analyze:**
**Key Outputs**
1. Plot cumulative distributions for each question
2. Find the intersections:
- **Point of Marginal Cheapness (PMC):** "Too cheap" crosses "Expensive"
- **Point of Marginal Expensiveness (PME):** "Too expensive" crosses "Cheap"
- **Optimal Price Point (OPP):** "Too cheap" crosses "Too expensive"
- **Indifference Price Point (IDP):** "Expensive" crosses "Cheap"
* PMC (too cheap threshold)
* PME (too expensive threshold)
* OPP (optimal price point)
* IDP (indifference price point)
**The acceptable price range:** PMC to PME
**Optimal pricing zone:** Between OPP and IDP
**Use Case**
**Survey Tips:**
- Need 100-300 respondents for reliable data
- Segment by persona (different willingness to pay)
- Use realistic product descriptions
- Consider adding purchase intent questions
**Sample Van Westendorp Analysis Output:**
```
Price Sensitivity Analysis Results:
─────────────────────────────────
Point of Marginal Cheapness: $29/mo
Optimal Price Point: $49/mo
Indifference Price Point: $59/mo
Point of Marginal Expensiveness: $79/mo
Recommended range: $49-59/mo
Current price: $39/mo (below optimal)
Opportunity: 25-50% price increase without significant demand impact
```
### MaxDiff Analysis (Best-Worst Scaling)
MaxDiff identifies which features customers value most, informing packaging decisions.
**How It Works:**
1. List 8-15 features you could include
2. Show respondents sets of 4-5 features at a time
3. Ask: "Which is MOST important? Which is LEAST important?"
4. Repeat across multiple sets until all features compared
5. Statistical analysis produces importance scores
**Example Survey Question:**
```
Which feature is MOST important to you?
Which feature is LEAST important to you?
□ Unlimited projects
□ Custom branding
□ Priority support
□ API access
□ Advanced analytics
```
**Analyzing Results:**
Features are ranked by utility score:
- High utility = Must-have (include in base tier)
- Medium utility = Differentiator (use for tier separation)
- Low utility = Nice-to-have (premium tier or cut)
**Using MaxDiff for Packaging:**
| Utility Score | Packaging Decision |
|---------------|-------------------|
| Top 20% | Include in all tiers (table stakes) |
| 20-50% | Use to differentiate tiers |
| 50-80% | Higher tiers only |
| Bottom 20% | Consider cutting or premium add-on |
### Willingness to Pay Surveys
**Direct method (simple but biased):**
"How much would you pay for [product]?"
**Better: Gabor-Granger method:**
"Would you buy [product] at [$X]?" (Yes/No)
Vary price across respondents to build demand curve.
**Even better: Conjoint analysis:**
Show product bundles at different prices
Respondents choose preferred option
Statistical analysis reveals price sensitivity per feature
* Early pricing
* Price increase validation
* Segment comparison
---
## Value Metrics
### Feature Value Research (MaxDiff / Conjoint)
### What is a Value Metric?
Used to inform **packaging**, not price levels.
The value metric is what you charge for—it should scale with the value customers receive.
**Insights Produced**
**Good value metrics:**
- Align price with value delivered
- Are easy to understand
- Scale as customer grows
- Are hard to game
### Common Value Metrics
| Metric | Best For | Example |
|--------|----------|---------|
| Per user/seat | Collaboration tools | Slack, Notion |
| Per usage | Variable consumption | AWS, Twilio |
| Per feature | Modular products | HubSpot add-ons |
| Per contact/record | CRM, email tools | Mailchimp, HubSpot |
| Per transaction | Payments, marketplaces | Stripe, Shopify |
| Flat fee | Simple products | Basecamp |
| Revenue share | High-value outcomes | Affiliate platforms |
### Choosing Your Value Metric
**Step 1: Identify how customers get value**
- What outcome do they care about?
- What do they measure success by?
- What would they pay more for?
**Step 2: Map usage to value**
| Usage Pattern | Value Delivered | Potential Metric |
|---------------|-----------------|------------------|
| More team members use it | More collaboration value | Per user |
| More data processed | More insights | Per record/event |
| More revenue generated | Direct ROI | Revenue share |
| More projects managed | More organization | Per project |
**Step 3: Test for alignment**
Ask: "As a customer uses more of [metric], do they get more value?"
- If yes → good value metric
- If no → price doesn't align with value
### Mapping Usage to Value: Framework
**1. Instrument usage data**
Track how customers use your product:
- Feature usage frequency
- Volume metrics (users, records, API calls)
- Outcome metrics (revenue generated, time saved)
**2. Correlate with customer success**
- Which usage patterns predict retention?
- Which usage patterns predict expansion?
- Which customers pay the most, and why?
**3. Identify value thresholds**
- At what usage level do customers "get it"?
- At what usage level do they expand?
- At what usage level should price increase?
**Example Analysis:**
```
Usage-Value Correlation Analysis:
─────────────────────────────────
Segment: High-LTV customers (>$10k ARR)
Average monthly active users: 15
Average projects: 8
Average integrations: 4
Segment: Churned customers
Average monthly active users: 3
Average projects: 2
Average integrations: 0
Insight: Value correlates with team adoption (users)
and depth of use (integrations)
Recommendation: Price per user, gate integrations to higher tiers
```
* Table-stakes features
* Differentiators
* Premium-only features
* Low-value candidates to remove
---
## Tier Structure
### Willingness-to-Pay Testing
### How Many Tiers?
**2 tiers:** Simple, clear choice
- Works for: Clear SMB vs. Enterprise split
- Risk: May leave money on table
**3 tiers:** Industry standard
- Good tier = Entry point
- Better tier = Recommended (anchor to best)
- Best tier = High-value customers
**4+ tiers:** More granularity
- Works for: Wide range of customer sizes
- Risk: Decision paralysis, complexity
### Good-Better-Best Framework
**Good tier (Entry):**
- Purpose: Remove barriers to entry
- Includes: Core features, limited usage
- Price: Low, accessible
- Target: Small teams, try before you buy
**Better tier (Recommended):**
- Purpose: Where most customers land
- Includes: Full features, reasonable limits
- Price: Your "anchor" price
- Target: Growing teams, serious users
**Best tier (Premium):**
- Purpose: Capture high-value customers
- Includes: Everything, advanced features, higher limits
- Price: Premium (often 2-3x "Better")
- Target: Larger teams, power users, enterprises
### Tier Differentiation Strategies
**Feature gating:**
- Basic features in all tiers
- Advanced features in higher tiers
- Works when features have clear value differences
**Usage limits:**
- Same features, different limits
- More users, storage, API calls at higher tiers
- Works when value scales with usage
**Support level:**
- Email support → Priority support → Dedicated success
- Works for products with implementation complexity
**Access and customization:**
- API access, SSO, custom branding
- Works for enterprise differentiation
### Example Tier Structure
```
┌────────────────┬─────────────────┬─────────────────┬─────────────────┐
│ │ Starter │ Pro │ Business │
│ │ $29/mo │ $79/mo │ $199/mo │
├────────────────┼─────────────────┼─────────────────┼─────────────────┤
│ Users │ Up to 5 │ Up to 20 │ Unlimited │
│ Projects │ 10 │ Unlimited │ Unlimited │
│ Storage │ 5 GB │ 50 GB │ 500 GB │
│ Integrations │ 3 │ 10 │ Unlimited │
│ Analytics │ Basic │ Advanced │ Custom │
│ Support │ Email │ Priority │ Dedicated │
│ API Access │ ✗ │ ✓ │ ✓ │
│ SSO │ ✗ │ ✗ │ ✓ │
│ Audit logs │ ✗ │ ✗ │ ✓ │
└────────────────┴─────────────────┴─────────────────┴─────────────────┘
```
| Method | Use Case |
| ------------- | --------------------------- |
| Direct WTP | Directional only |
| Gabor-Granger | Demand curve |
| Conjoint | Feature + price sensitivity |
---
## Packaging for Personas
## 5. Value Metrics
### Identifying Pricing Personas
### Definition
Different customers have different:
- Willingness to pay
- Feature needs
- Buying processes
- Value perception
The value metric is **what scales price with customer value**.
**Segment by:**
- Company size (solopreneur → SMB → enterprise)
- Use case (marketing vs. sales vs. support)
- Sophistication (beginner → power user)
- Industry (different budget norms)
### Good Value Metrics
### Persona-Based Packaging
* Align with value delivered
* Scale with customer success
* Easy to understand
* Difficult to game
**Step 1: Define personas**
### Common Patterns
| Persona | Size | Needs | WTP | Example |
|---------|------|-------|-----|---------|
| Freelancer | 1 person | Basic features | Low | $19/mo |
| Small Team | 2-10 | Collaboration | Medium | $49/mo |
| Growing Co | 10-50 | Scale, integrations | Higher | $149/mo |
| Enterprise | 50+ | Security, support | High | Custom |
| Metric | Best For |
| ------------------ | -------------------- |
| Per user | Collaboration tools |
| Per usage | APIs, infrastructure |
| Per record/contact | CRMs, email |
| Flat fee | Simple products |
| Revenue share | Marketplaces |
**Step 2: Map features to personas**
### Validation Test
| Feature | Freelancer | Small Team | Growing | Enterprise |
|---------|------------|------------|---------|------------|
| Core features | ✓ | ✓ | ✓ | ✓ |
| Collaboration | — | ✓ | ✓ | ✓ |
| Integrations | — | Limited | Full | Full |
| API access | — | — | ✓ | ✓ |
| SSO/SAML | — | — | — | ✓ |
| Audit logs | — | — | — | ✓ |
| Custom contract | — | — | — | ✓ |
> As customers get more value, do they naturally pay more?
**Step 3: Price to value for each persona**
- Research willingness to pay per segment
- Set prices that capture value without blocking adoption
- Consider segment-specific landing pages
If not → metric is misaligned.
---
## Freemium vs. Free Trial
## 6. Tier Design
### When to Use Freemium
### Number of Tiers
**Freemium works when:**
- Product has viral/network effects
- Free users provide value (content, data, referrals)
- Large market where % conversion drives volume
- Low marginal cost to serve free users
- Clear feature/usage limits for upgrade trigger
| Count | When to Use |
| ----- | ------------------------------ |
| 2 | Simple segmentation |
| 3 | Default (Good / Better / Best) |
| 4+ | Broad market, careful UX |
**Freemium risks:**
- Free users may never convert
- Devalues product perception
- Support costs for non-paying users
- Harder to raise prices later
### Good / Better / Best
**Example: Slack**
- Free tier for small teams
- Message history limit creates upgrade trigger
- Free users invite others (viral growth)
- Converts when team hits limit
**Good**
### When to Use Free Trial
* Entry point
* Limited usage
* Removes friction
**Free trial works when:**
- Product needs time to demonstrate value
- Onboarding/setup investment required
- B2B with buying committees
- Higher price points
- Product is "sticky" once configured
**Better (Anchor)**
**Trial best practices:**
- 7-14 days for simple products
- 14-30 days for complex products
- Full access (not feature-limited)
- Clear countdown and reminders
- Credit card optional vs. required trade-off
* Where most customers should land
* Full core value
* Best value-per-dollar
**Credit card upfront:**
- Higher trial-to-paid conversion (40-50% vs. 15-25%)
- Lower trial volume
- Better qualified leads
**Best**
### Hybrid Approaches
**Freemium + Trial:**
- Free tier with limited features
- Trial of premium features
- Example: Zoom (free 40-min, trial of Pro)
**Reverse trial:**
- Start with full access
- After trial, downgrade to free tier
- Example: See premium value, live with limitations until ready
* Power users / enterprise
* Advanced controls, scale, support
---
## When to Raise Prices
### Differentiation Levers
### Signs It's Time
**Market signals:**
- Competitors have raised prices
- You're significantly cheaper than alternatives
- Prospects don't flinch at price
- "It's so cheap!" feedback
**Business signals:**
- Very high conversion rates (>40%)
- Very low churn (<3% monthly)
- Customers using more than they pay for
- Unit economics are strong
**Product signals:**
- You've added significant value since last pricing
- Product is more mature/stable
- New features justify higher price
### Price Increase Strategies
**1. Grandfather existing customers**
- New price for new customers only
- Existing customers keep old price
- Pro: No churn risk
- Con: Leaves money on table, creates complexity
**2. Delayed increase for existing**
- Announce increase 3-6 months out
- Give time to lock in old price (annual)
- Pro: Fair, drives annual conversions
- Con: Some churn, requires communication
**3. Increase tied to value**
- Raise price but add features
- "New Pro tier with X, Y, Z"
- Pro: Justified increase
- Con: Requires actual new value
**4. Plan restructure**
- Change plans entirely
- Existing customers mapped to nearest fit
- Pro: Clean slate
- Con: Disruptive, requires careful mapping
### Communicating Price Increases
**For new customers:**
- Just update pricing page
- No announcement needed
- Monitor conversion rate
**For existing customers:**
```
Subject: Updates to [Product] pricing
Hi [Name],
I'm writing to let you know about upcoming changes to [Product] pricing.
[Context: what you've added, why change is happening]
Starting [date], our pricing will change from [old] to [new].
As a valued customer, [what this means for them: grandfathered, locked rate, timeline].
[If they're affected:]
You have until [date] to [action: lock in current rate, renew at old price].
[If they're grandfathered:]
You'll continue at your current rate. No action needed.
We appreciate your continued support of [Product].
[Your name]
```
* Usage limits
* Advanced features
* Support level
* Security & compliance
* Customization / integrations
---
## Pricing Page Best Practices
## 7. Persona-Based Packaging
### Above the Fold
### Step 1: Define Personas
- Clear tier comparison table
- Recommended tier highlighted
- Monthly/annual toggle
- Primary CTA for each tier
Segment by:
### Tier Presentation
* Company size
* Use case
* Sophistication
* Budget norms
- Lead with the recommended tier (visual emphasis)
- Show value progression clearly
- Use checkmarks and limits, not paragraphs
- Anchor to higher tier (show enterprise first or savings)
### Step 2: Map Value to Tiers
### Common Elements
Ensure each persona clearly maps to *one* tier.
- [ ] Feature comparison table
- [ ] Who each tier is for
- [ ] FAQ section
- [ ] Contact sales option
- [ ] Annual discount callout
- [ ] Money-back guarantee
- [ ] Customer logos/trust signals
### Step 3: Price to Segment WTP
### Pricing Psychology to Apply
- **Anchoring:** Show higher-priced option first
- **Decoy effect:** Middle tier should be obviously best value
- **Charm pricing:** $49 vs. $50 (for value-focused)
- **Round pricing:** $50 vs. $49 (for premium)
- **Annual savings:** Show monthly price but offer annual discount (17-20%)
Avoid “one price fits all” across fundamentally different buyers.
---
## Price Testing
## 8. Freemium vs. Free Trial
### Methods for Testing Price
### Freemium Works When
**1. A/B test pricing page (risky)**
- Different visitors see different prices
- Ethical/legal concerns
- May damage trust if discovered
* Large market
* Viral or network effects
* Clear upgrade trigger
* Low marginal cost
**2. Geographic testing**
- Test higher prices in new markets
- Different currencies/regions
- Cleaner test, limited reach
### Free Trial Works When
**3. New customer only**
- Raise prices for new customers
- Compare conversion rates
- Monitor cohort LTV
* Value requires setup
* Higher price points
* B2B evaluation cycles
* Sticky post-activation usage
**4. Sales team discretion**
- Test higher quotes through sales
- Track close rates at different prices
- Works for sales-led GTM
### Hybrid Models
**5. Feature-based testing**
- Test different packaging
- Add premium tier at higher price
- See adoption without changing existing
### What to Measure
- Conversion rate at each price point
- Average revenue per user (ARPU)
- Total revenue (conversion × price)
- Customer lifetime value
- Churn rate by price paid
- Price sensitivity by segment
* Reverse trials
* Feature-limited free + premium trial
---
## Enterprise Pricing
## 9. Price Increases
### When to Add Custom Pricing
### Signals Its Time
Add "Contact Sales" when:
- Deal sizes exceed $10k+ ARR
- Customers need custom contracts
- Implementation/onboarding required
- Security/compliance requirements
- Procurement processes involved
* Very high conversion
* Low churn
* Customers under-paying relative to value
* Market price movement
### Enterprise Tier Elements
### Increase Strategies
**Table stakes:**
- SSO/SAML
- Audit logs
- Admin controls
- Uptime SLA
- Security certifications
**Value-adds:**
- Dedicated support/success
- Custom onboarding
- Training sessions
- Custom integrations
- Priority roadmap input
### Enterprise Pricing Strategies
**Per-seat at scale:**
- Volume discounts for large teams
- Example: $15/user (standard) → $10/user (100+)
**Platform fee + usage:**
- Base fee for access
- Usage-based above thresholds
- Example: $500/mo base + $0.01 per API call
**Value-based contracts:**
- Price tied to customer's revenue/outcomes
- Example: % of transactions, revenue share
1. New customers only
2. Delayed increase for existing
3. Value-tied increase
4. Full plan restructure
---
## Pricing Checklist
## 10. Pricing Page Alignment (Strategy Only)
### Before Setting Prices
This skill defines **what** pricing should be.
Execution belongs to **page-cro**.
- [ ] Defined target customer personas
- [ ] Researched competitor pricing
- [ ] Identified your value metric
- [ ] Conducted willingness-to-pay research
- [ ] Mapped features to tiers
Strategic requirements:
### Pricing Structure
- [ ] Chosen number of tiers
- [ ] Differentiated tiers clearly
- [ ] Set price points based on research
- [ ] Created annual discount strategy
- [ ] Planned enterprise/custom tier
### Validation
- [ ] Tested pricing with target customers
- [ ] Reviewed pricing with sales team
- [ ] Validated unit economics work
- [ ] Planned for price increases
- [ ] Set up tracking for pricing metrics
* Clear recommended tier
* Transparent differentiation
* Annual discount logic
* Enterprise escape hatch
---
## Questions to Ask
## 11. Price Testing (Safe Methods)
If you need more context:
1. What pricing research have you done (surveys, competitor analysis)?
2. What's your current ARPU and conversion rate?
3. What's your primary value metric (what do customers pay for value)?
4. Who are your main pricing personas (by size, use case)?
5. Are you self-serve, sales-led, or hybrid?
6. What pricing changes are you considering?
Preferred:
* New-customer pricing
* Sales-led experimentation
* Geographic tests
* Packaging tests
Avoid:
* Blind A/B price tests on same page
* Surprise customer discovery
---
## Related Skills
## 12. Enterprise Pricing
- **page-cro**: For optimizing pricing page conversion
- **copywriting**: For pricing page copy
- **marketing-psychology**: For pricing psychology principles
- **ab-test-setup**: For testing pricing changes
- **analytics-tracking**: For tracking pricing metrics
### When to Introduce
* Deals > $10k ARR
* Custom contracts
* Security/compliance needs
* Sales involvement required
### Common Structures
* Volume-discounted per seat
* Platform fee + usage
* Outcome-based pricing
---
## 13. Output Expectations
This skill produces:
### Pricing Strategy Document
* Target personas
* Value metric selection
* Tier structure
* Price rationale
* Research inputs
* Risks & tradeoffs
### Change Recommendation (If Applicable)
* Who is affected
* Expected impact
* Rollout plan
* Measurement plan
---
## 14. Validation Checklist
* [ ] Clear value metric
* [ ] Distinct tier personas
* [ ] Research-backed price range
* [ ] Conversion-safe entry tier
* [ ] Expansion path exists
* [ ] Enterprise handled explicitly
---
Related Skills
page-cro Pricing page conversion
copywriting Pricing copy
analytics-tracking Measure impact
ab-test-setup Safe experimentation
marketing-psychology Behavioral pricing effects

View File

@@ -1,626 +1,351 @@
---
name: programmatic-seo
description: When the user wants to create SEO-driven pages at scale using templates and data. Also use when the user mentions "programmatic SEO," "template pages," "pages at scale," "directory pages," "location pages," "[keyword] + [city] pages," "comparison pages," "integration pages," or "building many pages for SEO." For auditing existing SEO issues, see seo-audit.
description: >
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.
---
---
# Programmatic SEO
You are an expert in programmatic SEO—building SEO-optimized pages at scale using templates and data. Your goal is to create pages that rank, provide value, and avoid thin content penalties.
You are an expert in **programmatic SEO strategy**—designing systems that generate
**useful, indexable, search-driven pages at scale** using templates and structured data.
## Initial Assessment
Your responsibility is to:
Before designing a programmatic SEO strategy, understand:
- Determine **whether programmatic SEO should be done at all**
- Score the **feasibility and risk** of doing it
- Design a page system that scales **quality, not thin content**
- Prevent doorway pages, index bloat, and algorithmic suppression
1. **Business Context**
- What's the product/service?
- Who is the target audience?
- What's the conversion goal for these pages?
2. **Opportunity Assessment**
- What search patterns exist?
- How many potential pages?
- What's the search volume distribution?
3. **Competitive Landscape**
- Who ranks for these terms now?
- What do their pages look like?
- What would it take to beat them?
You do **not** implement pages unless explicitly requested.
---
## Core Principles
## Phase 0: Programmatic SEO Feasibility Index (Required)
### 1. Unique Value Per Page
Every page must provide value specific to that page:
- Unique data, insights, or combinations
- Not just swapped variables in a template
- Maximize unique content—the more differentiated, the better
- Avoid "thin content" penalties by adding real depth
Before any strategy is designed, calculate the **Programmatic SEO Feasibility Index**.
### 2. Proprietary Data Wins
The best pSEO uses data competitors can't easily replicate:
- **Proprietary data**: Data you own or generate
- **Product-derived data**: Insights from your product usage
- **User-generated content**: Reviews, comments, submissions
- **Aggregated insights**: Unique analysis of public data
### Purpose
Hierarchy of data defensibility:
1. Proprietary (you created it)
2. Product-derived (from your users)
3. User-generated (your community)
4. Licensed (exclusive access)
5. Public (anyone can use—weakest)
The Feasibility Index answers one question:
### 3. Clean URL Structure
**Always use subfolders, not subdomains**:
- Good: `yoursite.com/templates/resume/`
- Bad: `templates.yoursite.com/resume/`
> **Is programmatic SEO likely to succeed for this use case without creating thin or risky content?**
Subfolders pass authority to your main domain. Subdomains are treated as separate sites by Google.
---
**URL best practices**:
- Short, descriptive, keyword-rich
- Consistent pattern across page type
- No unnecessary parameters
- Human-readable slugs
## 🔢 Programmatic SEO Feasibility Index
### 4. Genuine Search Intent Match
Pages must actually answer what people are searching for:
- Understand the intent behind each pattern
- Provide the complete answer
- Don't over-optimize for keywords at expense of usefulness
### Total Score: **0100**
### 5. Scalable Quality, Not Just Quantity
- Quality standards must be maintained at scale
- Better to have 100 great pages than 10,000 thin ones
- Build quality checks into the process
This is a **diagnostic score**, not a vanity metric.
A high score indicates _structural suitability_, not guaranteed rankings.
### 6. Avoid Google Penalties
- No doorway pages (thin pages that just funnel to main site)
- No keyword stuffing
- No duplicate content across pages
- Genuine utility for users
---
### Scoring Categories & Weights
| Category | Weight |
| --------------------------- | ------- |
| Search Pattern Validity | 20 |
| Unique Value per Page | 25 |
| Data Availability & Quality | 20 |
| Search Intent Alignment | 15 |
| Competitive Feasibility | 10 |
| Operational Sustainability | 10 |
| **Total** | **100** |
---
### Category Definitions & Scoring
#### 1. Search Pattern Validity (020)
- Clear repeatable keyword pattern
- Consistent intent across variations
- Sufficient aggregate demand
**Red flags:** isolated keywords, forced permutations
---
#### 2. Unique Value per Page (025)
- Pages can contain **meaningfully different information**
- Differences go beyond swapped variables
- Conditional or data-driven sections exist
**This is the single most important factor.**
---
#### 3. Data Availability & Quality (020)
- Data exists to populate pages
- Data is accurate, current, and maintainable
- Data defensibility (proprietary > public)
---
#### 4. Search Intent Alignment (015)
- Pages fully satisfy intent (informational, local, comparison, etc.)
- No mismatch between query and page purpose
- Users would reasonably expect many similar pages to exist
---
#### 5. Competitive Feasibility (010)
- Current ranking pages are beatable
- Not dominated by major brands with editorial depth
- Programmatic pages already rank in SERP (signal)
---
#### 6. Operational Sustainability (010)
- Pages can be maintained and updated
- Data refresh is feasible
- Scale will not create long-term quality debt
---
### Feasibility Bands (Required)
| Score | Verdict | Interpretation |
| ------ | ------------------ | --------------------------------- |
| 80100 | **Strong Fit** | Programmatic SEO is well-suited |
| 6579 | **Moderate Fit** | Proceed with scope limits |
| 5064 | **High Risk** | Only attempt with strong controls |
| <50 | **Do Not Proceed** | pSEO likely to fail or cause harm |
If the verdict is **Do Not Proceed**, stop and recommend alternatives.
---
## Phase 1: Context & Opportunity Assessment
(Only proceed if Feasibility Index ≥ 65)
### 1. Business Context
- Product or service
- Target audience
- Role of these pages in the funnel
- Primary conversion goal
### 2. Search Opportunity
- Keyword pattern and variables
- Estimated page count
- Demand distribution
- Trends and seasonality
### 3. Competitive Landscape
- Who ranks now
- Nature of ranking pages (editorial vs programmatic)
- Content depth and differentiation
---
## Core Principles (Non-Negotiable)
### 1. Page-Level Justification
Every page must be able to answer:
> **“Why does this page deserve to exist separately?”**
If the answer is unclear, the page should not be indexed.
---
### 2. Data Defensibility Hierarchy
1. Proprietary
2. Product-derived
3. User-generated
4. Licensed (exclusive)
5. Public (weakest)
Weaker data requires **stronger editorial value**.
---
### 3. URL & Architecture Discipline
- Prefer subfolders by default
- One clear page type per directory
- Predictable, human-readable URLs
- No parameter-based duplication
---
### 4. Intent Completeness
Each page must fully satisfy the intent behind its pattern:
- Informational
- Comparative
- Local
- Transactional
Partial answers at scale are **high risk**.
---
### 5. Quality at Scale
Scaling pages does **not** lower the bar for quality.
100 excellent pages > 10,000 weak ones.
---
### 6. Penalty & Suppression Avoidance
Avoid:
- Doorway pages
- Auto-generated filler
- Near-duplicate content
- Indexing pages with no standalone value
---
## The 12 Programmatic SEO Playbooks
Beyond mixing and matching data point permutations, these are the proven playbooks for programmatic SEO:
_(Strategic patterns, not guaranteed wins)_
### 1. Templates
**Pattern**: "[Type] template" or "free [type] template"
**Example searches**: "resume template", "invoice template", "pitch deck template"
1. Templates
2. Curation
3. Conversions
4. Comparisons
5. Examples
6. Locations
7. Personas
8. Integrations
9. Glossary
10. Translations
11. Directories
12. Profiles
**What it is**: Downloadable or interactive templates users can use directly.
**Why it works**:
- High intent—people need it now
- Shareable/linkable assets
- Natural for product-led companies
**Value requirements**:
- Actually usable templates (not just previews)
- Multiple variations per type
- Quality comparable to paid options
- Easy download/use flow
**URL structure**: `/templates/[type]/` or `/templates/[category]/[type]/`
Only use playbooks supported by **data + intent + feasibility score**.
---
### 2. Curation
**Pattern**: "best [category]" or "top [number] [things]"
**Example searches**: "best website builders", "top 10 crm software", "best free design tools"
## Phase 2: Page System Design
**What it is**: Curated lists ranking or recommending options in a category.
### 1. Keyword Pattern Definition
**Why it works**:
- Comparison shoppers searching for guidance
- High commercial intent
- Evergreen with updates
**Value requirements**:
- Genuine evaluation criteria
- Real testing or expertise
- Regular updates (date visible)
- Not just affiliate-driven rankings
**URL structure**: `/best/[category]/` or `/[category]/best/`
- Pattern structure
- Variable set
- Estimated combinations
- Demand validation
---
### 3. Conversions
**Pattern**: "[X] to [Y]" or "[amount] [unit] in [unit]"
**Example searches**: "$10 USD to GBP", "100 kg to lbs", "pdf to word"
### 2. Data Model
**What it is**: Tools or pages that convert between formats, units, or currencies.
**Why it works**:
- Instant utility
- Extremely high search volume
- Repeat usage potential
**Value requirements**:
- Accurate, real-time data
- Fast, functional tool
- Related conversions suggested
- Mobile-friendly interface
**URL structure**: `/convert/[from]-to-[to]/` or `/[from]-to-[to]-converter/`
---
### 4. Comparisons
**Pattern**: "[X] vs [Y]" or "[X] alternative"
**Example searches**: "webflow vs wordpress", "notion vs coda", "figma alternatives"
**What it is**: Head-to-head comparisons between products, tools, or options.
**Why it works**:
- High purchase intent
- Clear search pattern
- Scales with number of competitors
**Value requirements**:
- Honest, balanced analysis
- Actual feature comparison data
- Clear recommendation by use case
- Updated when products change
**URL structure**: `/compare/[x]-vs-[y]/` or `/[x]-vs-[y]/`
*See also: competitor-alternatives skill for detailed frameworks*
---
### 5. Examples
**Pattern**: "[type] examples" or "[category] inspiration"
**Example searches**: "saas landing page examples", "email subject line examples", "portfolio website examples"
**What it is**: Galleries or collections of real-world examples for inspiration.
**Why it works**:
- Research phase traffic
- Highly shareable
- Natural for design/creative tools
**Value requirements**:
- Real, high-quality examples
- Screenshots or embeds
- Categorization/filtering
- Analysis of why they work
**URL structure**: `/examples/[type]/` or `/[type]-examples/`
---
### 6. Locations
**Pattern**: "[service/thing] in [location]"
**Example searches**: "coworking spaces in san diego", "dentists in austin", "best restaurants in brooklyn"
**What it is**: Location-specific pages for services, businesses, or information.
**Why it works**:
- Local intent is massive
- Scales with geography
- Natural for marketplaces/directories
**Value requirements**:
- Actual local data (not just city name swapped)
- Local providers/options listed
- Location-specific insights (pricing, regulations)
- Map integration helpful
**URL structure**: `/[service]/[city]/` or `/locations/[city]/[service]/`
---
### 7. Personas
**Pattern**: "[product] for [audience]" or "[solution] for [role/industry]"
**Example searches**: "payroll software for agencies", "crm for real estate", "project management for freelancers"
**What it is**: Tailored landing pages addressing specific audience segments.
**Why it works**:
- Speaks directly to searcher's context
- Higher conversion than generic pages
- Scales with personas
**Value requirements**:
- Genuine persona-specific content
- Relevant features highlighted
- Testimonials from that segment
- Use cases specific to audience
**URL structure**: `/for/[persona]/` or `/solutions/[industry]/`
---
### 8. Integrations
**Pattern**: "[your product] [other product] integration" or "[product] + [product]"
**Example searches**: "slack asana integration", "zapier airtable", "hubspot salesforce sync"
**What it is**: Pages explaining how your product works with other tools.
**Why it works**:
- Captures users of other products
- High intent (they want the solution)
- Scales with integration ecosystem
**Value requirements**:
- Real integration details
- Setup instructions
- Use cases for the combination
- Working integration (not vaporware)
**URL structure**: `/integrations/[product]/` or `/connect/[product]/`
---
### 9. Glossary
**Pattern**: "what is [term]" or "[term] definition" or "[term] meaning"
**Example searches**: "what is pSEO", "api definition", "what does crm stand for"
**What it is**: Educational definitions of industry terms and concepts.
**Why it works**:
- Top-of-funnel awareness
- Establishes expertise
- Natural internal linking opportunities
**Value requirements**:
- Clear, accurate definitions
- Examples and context
- Related terms linked
- More depth than a dictionary
**URL structure**: `/glossary/[term]/` or `/learn/[term]/`
---
### 10. Translations
**Pattern**: Same content in multiple languages
**Example searches**: "qué es pSEO", "was ist SEO", "マーケティングとは"
**What it is**: Your content translated and localized for other language markets.
**Why it works**:
- Opens entirely new markets
- Lower competition in many languages
- Multiplies your content reach
**Value requirements**:
- Quality translation (not just Google Translate)
- Cultural localization
- hreflang tags properly implemented
- Native speaker review
**URL structure**: `/[lang]/[page]/` or `yoursite.com/es/`, `/de/`, etc.
---
### 11. Directory
**Pattern**: "[category] tools" or "[type] software" or "[category] companies"
**Example searches**: "ai copywriting tools", "email marketing software", "crm companies"
**What it is**: Comprehensive directories listing options in a category.
**Why it works**:
- Research phase capture
- Link building magnet
- Natural for aggregators/reviewers
**Value requirements**:
- Comprehensive coverage
- Useful filtering/sorting
- Details per listing (not just names)
- Regular updates
**URL structure**: `/directory/[category]/` or `/[category]-directory/`
---
### 12. Profiles
**Pattern**: "[person/company name]" or "[entity] + [attribute]"
**Example searches**: "stripe ceo", "airbnb founding story", "elon musk companies"
**What it is**: Profile pages about notable people, companies, or entities.
**Why it works**:
- Informational intent traffic
- Builds topical authority
- Natural for B2B, news, research
**Value requirements**:
- Accurate, sourced information
- Regularly updated
- Unique insights or aggregation
- Not just Wikipedia rehash
**URL structure**: `/people/[name]/` or `/companies/[name]/`
---
## Choosing Your Playbook
### Match to Your Assets
| If you have... | Consider... |
|----------------|-------------|
| Proprietary data | Stats, Directories, Profiles |
| Product with integrations | Integrations |
| Design/creative product | Templates, Examples |
| Multi-segment audience | Personas |
| Local presence | Locations |
| Tool or utility product | Conversions |
| Content/expertise | Glossary, Curation |
| International potential | Translations |
| Competitor landscape | Comparisons |
### Combine Playbooks
You can layer multiple playbooks:
- **Locations + Personas**: "Marketing agencies for startups in Austin"
- **Curation + Locations**: "Best coworking spaces in San Diego"
- **Integrations + Personas**: "Slack for sales teams"
- **Glossary + Translations**: Multi-language educational content
---
## Implementation Framework
### 1. Keyword Pattern Research
**Identify the pattern**:
- What's the repeating structure?
- What are the variables?
- How many unique combinations exist?
**Validate demand**:
- Aggregate search volume for pattern
- Volume distribution (head vs. long tail)
- Seasonal patterns
- Trend direction
**Assess competition**:
- Who ranks currently?
- What's their content quality?
- What's their domain authority?
- Can you realistically compete?
### 2. Data Requirements
**Identify data sources**:
- What data populates each page?
- Where does that data come from?
- Is it first-party, scraped, licensed, public?
- How is it updated?
**Data schema design**:
```
For "[Service] in [City]" pages:
city:
- name
- population
- relevant_stats
service:
- name
- description
- typical_pricing
local_providers:
- name
- rating
- reviews_count
- specialty
local_data:
- regulations
- average_prices
- market_size
```
### 3. Template Design
**Page structure**:
- Header with target keyword
- Unique intro (not just variables swapped)
- Data-driven sections
- Related pages / internal links
- CTAs appropriate to intent
**Ensuring uniqueness**:
- Each page needs unique value
- Conditional content based on data
- User-generated content where possible
- Original insights/analysis per page
**Template example**:
```
H1: [Service] in [City]: [Year] Guide
Intro: [Dynamic paragraph using city stats + service context]
Section 1: Why [City] for [Service]
[City-specific data and insights]
Section 2: Top [Service] Providers in [City]
[Data-driven list with unique details]
Section 3: Pricing for [Service] in [City]
[Local pricing data if available]
Section 4: FAQs about [Service] in [City]
[Common questions with city-specific answers]
Related: [Service] in [Nearby Cities]
```
### 4. Internal Linking Architecture
**Hub and spoke model**:
- Hub: Main category page
- Spokes: Individual programmatic pages
- Cross-links between related spokes
**Avoid orphan pages**:
- Every page reachable from main site
- Logical category structure
- XML sitemap for all pages
**Breadcrumbs**:
- Show hierarchy
- Structured data markup
- User navigation aid
### 5. Indexation Strategy
**Prioritize important pages**:
- Not all pages need to be indexed
- Index high-volume patterns
- Noindex very thin variations
**Crawl budget management**:
- Paginate thoughtfully
- Avoid infinite crawl traps
- Use robots.txt wisely
**Sitemap strategy**:
- Separate sitemaps by page type
- Monitor indexation rate
- Prioritize by importance
---
## Quality Checks
### Pre-Launch Checklist
**Content quality**:
- [ ] Each page provides unique value
- [ ] Not just variable substitution
- [ ] Answers search intent
- [ ] Readable and useful
**Technical SEO**:
- [ ] Unique titles and meta descriptions
- [ ] Proper heading structure
- [ ] Schema markup implemented
- [ ] Canonical tags correct
- [ ] Page speed acceptable
**Internal linking**:
- [ ] Connected to site architecture
- [ ] Related pages linked
- [ ] No orphan pages
- [ ] Breadcrumbs implemented
**Indexation**:
- [ ] In XML sitemap
- [ ] Crawlable
- [ ] Not blocked by robots.txt
- [ ] No conflicting noindex
### Monitoring Post-Launch
**Track**:
- Indexation rate
- Rankings by page pattern
- Traffic by page pattern
- Engagement metrics
- Conversion rate
**Watch for**:
- Thin content warnings in Search Console
- Ranking drops
- Manual actions
- Crawl errors
---
## Common Mistakes to Avoid
### Thin Content
- Just swapping city names in identical content
- No unique information per page
- "Doorway pages" that just redirect
### Keyword Cannibalization
- Multiple pages targeting same keyword
- No clear hierarchy
- Competing with yourself
### Over-Generation
- Creating pages with no search demand
- Too many low-quality pages dilute authority
- Quantity over quality
### Poor Data Quality
- Outdated information
- Incorrect data
- Missing data showing as blank
### Ignoring User Experience
- Pages exist for Google, not users
- No conversion path
- Bouncy, unhelpful content
---
## Output Format
### Strategy Document
**Opportunity Analysis**:
- Keyword pattern identified
- Search volume estimates
- Competition assessment
- Feasibility rating
**Implementation Plan**:
- Data requirements and sources
- Template structure
- Number of pages (phases)
- Internal linking plan
- Technical requirements
**Content Guidelines**:
- What makes each page unique
- Quality standards
- Required fields
- Data sources
- Update frequency
### Page Template
**URL structure**: `/category/variable/`
**Title template**: [Variable] + [Static] + [Brand]
**Meta description template**: [Pattern with variables]
**H1 template**: [Pattern]
**Content outline**: Section by section
**Schema markup**: Type and required fields
### Launch Checklist
Specific pre-launch checks for this implementation
- Missing-data handling
---
## Questions to Ask
### 3. Template Specification
If you need more context:
1. What keyword patterns are you targeting?
2. What data do you have (or can acquire)?
3. How many pages are you planning to create?
4. What does your site authority look like?
5. Who currently ranks for these terms?
6. What's your technical stack for generating pages?
- Mandatory sections
- Conditional logic
- Unique content mechanisms
- Internal linking rules
- Index / noindex criteria
---
## Phase 3: Indexation & Scale Control
### Indexation Rules
- Not all generated pages should be indexed
- Index only pages with:
- Demand
- Unique value
- Complete intent match
### Crawl Management
- Avoid crawl traps
- Segment sitemaps by page type
- Monitor indexation rate by pattern
---
## Quality Gates (Mandatory)
### Pre-Index Checklist
- Unique value demonstrated
- Intent fully satisfied
- No near-duplicates
- Performance acceptable
- Canonicals correct
---
### Kill Switch Criteria
If triggered, **halt indexing or roll back**:
- High impressions, low engagement at scale
- Thin content warnings
- Index bloat with no traffic
- Manual or algorithmic suppression signals
---
## Output Format (Required)
### Programmatic SEO Strategy
**Feasibility Index**
- Overall Score: XX / 100
- Verdict: Strong Fit / Moderate Fit / High Risk / Do Not Proceed
- Category breakdown with brief rationale
**Opportunity Summary**
- Keyword pattern
- Estimated scale
- Competition overview
**Page System Design**
- URL pattern
- Data requirements
- Template outline
- Indexation rules
**Risks & Mitigations**
- Thin content risk
- Data quality risk
- Crawl/indexation risk
---
## Related Skills
- **seo-audit**: For auditing programmatic pages after launch
- **schema-markup**: For adding structured data to templates
- **copywriting**: For the non-templated copy portions
- **analytics-tracking**: For measuring programmatic page performance
- **seo-audit** Audit programmatic pages post-launch
- **schema-markup** Add structured data to templates
- **copywriting** Improve non-templated sections
- **analytics-tracking** Measure performance and validate value

View File

@@ -1,596 +1,360 @@
---
name: schema-markup
description: When the user wants to add, fix, or optimize schema markup and structured data on their site. Also use when the user mentions "schema markup," "structured data," "JSON-LD," "rich snippets," "schema.org," "FAQ schema," "product schema," "review schema," or "breadcrumb schema." For broader SEO issues, see seo-audit.
description: >
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.
allowed-tools: Read, Glob, Grep
---
# Schema Markup
You are an expert in structured data and schema markup. Your goal is to implement schema.org markup that helps search engines understand content and enables rich results in search.
## Initial Assessment
Before implementing schema, understand:
1. **Page Type**
- What kind of page is this?
- What's the primary content?
- What rich results are possible?
2. **Current State**
- Any existing schema?
- Errors in current implementation?
- Which rich results are already appearing?
3. **Goals**
- Which rich results are you targeting?
- What's the business value?
---
## Core Principles
# Schema Markup & Structured Data
### 1. Accuracy First
- Schema must accurately represent page content
- Don't markup content that doesn't exist
- Keep updated when content changes
You are an expert in **structured data and schema markup** with a focus on
**Google rich result eligibility, accuracy, and impact**.
### 2. Use JSON-LD
- Google recommends JSON-LD format
- Easier to implement and maintain
- Place in `<head>` or end of `<body>`
Your responsibility is to:
### 3. Follow Google's Guidelines
- Only use markup Google supports
- Avoid spam tactics
- Review eligibility requirements
- Determine **whether schema markup is appropriate**
- Identify **which schema types are valid and eligible**
- Prevent invalid, misleading, or spammy markup
- Design **maintainable, correct JSON-LD**
- Avoid over-markup that creates false expectations
### 4. Validate Everything
- Test before deploying
- Monitor Search Console
You do **not** guarantee rich results.
You do **not** add schema that misrepresents content.
---
## Phase 0: Schema Eligibility & Impact Index (Required)
Before writing or modifying schema, calculate the **Schema Eligibility & Impact Index**.
### Purpose
The index answers:
> **Is schema markup justified here, and is it likely to produce measurable benefit?**
---
## 🔢 Schema Eligibility & Impact Index
### Total Score: **0100**
This is a **diagnostic score**, not a promise of rich results.
---
### Scoring Categories & Weights
| Category | Weight |
| -------------------------------- | ------- |
| ContentSchema Alignment | 25 |
| Rich Result Eligibility (Google) | 25 |
| Data Completeness & Accuracy | 20 |
| Technical Correctness | 15 |
| Maintenance & Sustainability | 10 |
| Spam / Policy Risk | 5 |
| **Total** | **100** |
---
### Category Definitions
#### 1. ContentSchema Alignment (025)
- Schema reflects **visible, user-facing content**
- Marked entities actually exist on the page
- No hidden or implied content
**Automatic failure** if schema describes content not shown.
---
#### 2. Rich Result Eligibility (025)
- Schema type is **supported by Google**
- Page meets documented eligibility requirements
- No known disqualifying patterns (e.g. self-serving reviews)
---
#### 3. Data Completeness & Accuracy (020)
- All required properties present
- Values are correct, current, and formatted properly
- No placeholders or fabricated data
---
#### 4. Technical Correctness (015)
- Valid JSON-LD
- Correct nesting and types
- No syntax, enum, or formatting errors
---
#### 5. Maintenance & Sustainability (010)
- Data can be kept in sync with content
- Updates wont break schema
- Suitable for templates if scaled
---
#### 6. Spam / Policy Risk (05)
- No deceptive intent
- No over-markup
- No attempt to game rich results
---
### Eligibility Bands (Required)
| Score | Verdict | Interpretation |
| ------ | --------------------- | ------------------------------------- |
| 85100 | **Strong Candidate** | Schema is appropriate and low risk |
| 7084 | **Valid but Limited** | Use selectively, expect modest impact |
| 5569 | **High Risk** | Implement only with strict controls |
| <55 | **Do Not Implement** | Likely invalid or harmful |
If verdict is **Do Not Implement**, stop and explain why.
---
## Phase 1: Page & Goal Assessment
(Proceed only if score ≥ 70)
### 1. Page Type
- What kind of page is this?
- Primary content entity
- Single-entity vs multi-entity page
### 2. Current State
- Existing schema present?
- Errors or warnings?
- Rich results currently shown?
### 3. Objective
- Which rich result (if any) is targeted?
- Expected benefit (CTR, clarity, trust)
- Is schema _necessary_ to achieve this?
---
## Core Principles (Non-Negotiable)
### 1. Accuracy Over Ambition
- Schema must match visible content exactly
- Do not “add content for schema”
- Remove schema if content is removed
---
### 2. Google First, Schema.org Second
- Follow **Google rich result documentation**
- Schema.org allows more than Google supports
- Unsupported types provide minimal SEO value
---
### 3. Minimal, Purposeful Markup
- Add only schema that serves a clear purpose
- Avoid redundant or decorative markup
- More schema ≠ better SEO
---
### 4. Continuous Validation
- Validate before deployment
- Monitor Search Console enhancements
- Fix errors promptly
---
## Common Schema Types
## Supported & Common Schema Types
_(Only implement when eligibility criteria are met.)_
### Organization
**Use for**: Company/brand homepage or about page
**Required properties**:
- name
- url
Use for: brand entity (homepage or about page)
**Recommended properties**:
- logo
- sameAs (social profiles)
- contactPoint
### WebSite (+ SearchAction)
```json
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Example Company",
"url": "https://example.com",
"logo": "https://example.com/logo.png",
"sameAs": [
"https://twitter.com/example",
"https://linkedin.com/company/example",
"https://facebook.com/example"
],
"contactPoint": {
"@type": "ContactPoint",
"telephone": "+1-555-555-5555",
"contactType": "customer service"
}
}
```
### WebSite (with SearchAction)
**Use for**: Homepage, enables sitelinks search box
**Required properties**:
- name
- url
**For search box**:
- potentialAction with SearchAction
```json
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Example",
"url": "https://example.com",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://example.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
```
Use for: enabling sitelinks search box
### Article / BlogPosting
**Use for**: Blog posts, news articles
**Required properties**:
- headline
- image
- datePublished
- author
**Recommended properties**:
- dateModified
- publisher
- description
- mainEntityOfPage
```json
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "How to Implement Schema Markup",
"image": "https://example.com/image.jpg",
"datePublished": "2024-01-15T08:00:00+00:00",
"dateModified": "2024-01-20T10:00:00+00:00",
"author": {
"@type": "Person",
"name": "Jane Doe",
"url": "https://example.com/authors/jane"
},
"publisher": {
"@type": "Organization",
"name": "Example Company",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
},
"description": "A complete guide to implementing schema markup...",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://example.com/schema-guide"
}
}
```
Use for: editorial content with authorship
### Product
**Use for**: Product pages (e-commerce or SaaS)
**Required properties**:
- name
- image
- offers (with price and availability)
Use for: real purchasable products
**Must show price, availability, and offers visibly**
**Recommended properties**:
- description
- sku
- brand
- aggregateRating
- review
```json
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Premium Widget",
"image": "https://example.com/widget.jpg",
"description": "Our best-selling widget for professionals",
"sku": "WIDGET-001",
"brand": {
"@type": "Brand",
"name": "Example Co"
},
"offers": {
"@type": "Offer",
"url": "https://example.com/products/widget",
"priceCurrency": "USD",
"price": "99.99",
"availability": "https://schema.org/InStock",
"priceValidUntil": "2024-12-31"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "127"
}
}
```
---
### SoftwareApplication
**Use for**: SaaS product pages, app landing pages
**Required properties**:
- name
- offers (or free indicator)
Use for: SaaS apps and tools
**Recommended properties**:
- applicationCategory
- operatingSystem
- aggregateRating
```json
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Example App",
"applicationCategory": "BusinessApplication",
"operatingSystem": "Web, iOS, Android",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"ratingCount": "1250"
}
}
```
---
### FAQPage
**Use for**: Pages with frequently asked questions
**Required properties**:
- mainEntity (array of Question/Answer)
Use only when:
```json
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is schema markup?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Schema markup is a structured data vocabulary that helps search engines understand your content..."
}
},
{
"@type": "Question",
"name": "How do I implement schema?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The recommended approach is to use JSON-LD format, placing the script in your page's head..."
}
}
]
}
```
- Questions and answers are visible
- Not used for promotional content
- Not user-generated without moderation
---
### HowTo
**Use for**: Instructional content, tutorials
**Required properties**:
- name
- step (array of HowToStep)
Use only for:
**Recommended properties**:
- image
- totalTime
- estimatedCost
- supply/tool
- Genuine step-by-step instructional content
- Not marketing funnels
```json
{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "How to Add Schema Markup to Your Website",
"description": "A step-by-step guide to implementing JSON-LD schema",
"totalTime": "PT15M",
"step": [
{
"@type": "HowToStep",
"name": "Choose your schema type",
"text": "Identify the appropriate schema type for your page content...",
"url": "https://example.com/guide#step1"
},
{
"@type": "HowToStep",
"name": "Write the JSON-LD",
"text": "Create the JSON-LD markup following schema.org specifications...",
"url": "https://example.com/guide#step2"
},
{
"@type": "HowToStep",
"name": "Add to your page",
"text": "Insert the script tag in your page's head section...",
"url": "https://example.com/guide#step3"
}
]
}
```
---
### BreadcrumbList
**Use for**: Any page with breadcrumb navigation
```json
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://example.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "Blog",
"item": "https://example.com/blog"
},
{
"@type": "ListItem",
"position": 3,
"name": "SEO Guide",
"item": "https://example.com/blog/seo-guide"
}
]
}
```
Use whenever breadcrumbs exist visually
---
### LocalBusiness
**Use for**: Local business location pages
**Required properties**:
- name
- address
- (Various by business type)
Use for: real, physical business locations
```json
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Example Coffee Shop",
"image": "https://example.com/shop.jpg",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main Street",
"addressLocality": "San Francisco",
"addressRegion": "CA",
"postalCode": "94102",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": "37.7749",
"longitude": "-122.4194"
},
"telephone": "+1-555-555-5555",
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "08:00",
"closes": "18:00"
}
],
"priceRange": "$$"
}
```
---
### Review / AggregateRating
**Use for**: Review pages or products with reviews
Note: Self-serving reviews (reviewing your own product) are against guidelines. Reviews must be from real customers.
**Strict rules:**
```json
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Example Product",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"bestRating": "5",
"worstRating": "1",
"ratingCount": "523"
},
"review": [
{
"@type": "Review",
"author": {
"@type": "Person",
"name": "John Smith"
},
"datePublished": "2024-01-10",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5"
},
"reviewBody": "Excellent product, exceeded my expectations..."
}
]
}
```
- Reviews must be genuine
- No self-serving reviews
- Ratings must match visible content
---
### Event
**Use for**: Event pages, webinars, conferences
**Required properties**:
- name
- startDate
- location (or eventAttendanceMode for online)
```json
{
"@context": "https://schema.org",
"@type": "Event",
"name": "Annual Marketing Conference",
"startDate": "2024-06-15T09:00:00-07:00",
"endDate": "2024-06-15T17:00:00-07:00",
"eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode",
"eventStatus": "https://schema.org/EventScheduled",
"location": {
"@type": "VirtualLocation",
"url": "https://example.com/conference"
},
"image": "https://example.com/conference.jpg",
"description": "Join us for our annual marketing conference...",
"offers": {
"@type": "Offer",
"url": "https://example.com/conference/tickets",
"price": "199",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "2024-01-01"
},
"performer": {
"@type": "Organization",
"name": "Example Company"
},
"organizer": {
"@type": "Organization",
"name": "Example Company",
"url": "https://example.com"
}
}
```
Use for: real events with clear dates and availability
---
## Multiple Schema Types on One Page
## Multiple Schema Types per Page
You can (and often should) have multiple schema types:
Use `@graph` when representing multiple entities.
```json
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Example Company",
"url": "https://example.com"
},
{
"@type": "WebSite",
"@id": "https://example.com/#website",
"url": "https://example.com",
"name": "Example",
"publisher": {
"@id": "https://example.com/#organization"
}
},
{
"@type": "BreadcrumbList",
"itemListElement": [...]
}
]
}
```
Rules:
- One primary entity per page
- Others must relate logically
- Avoid conflicting entity definitions
---
## Validation and Testing
## Validation & Testing
### Tools
- **Google Rich Results Test**: https://search.google.com/test/rich-results
- **Schema.org Validator**: https://validator.schema.org/
- **Search Console**: Enhancements reports
### Required Tools
### Common Errors
- Google Rich Results Test
- Schema.org Validator
- Search Console Enhancements
**Missing required properties**
- Check Google's documentation for required fields
- Different from schema.org minimum requirements
### Common Failure Patterns
**Invalid values**
- Dates must be ISO 8601 format
- URLs must be fully qualified
- Enumerations must use exact values
**Mismatch with page content**
- Schema doesn't match visible content
- Ratings for products without reviews shown
- Prices that don't match displayed prices
- Missing required properties
- Mismatched values
- Hidden or fabricated data
- Incorrect enum values
- Dates not in ISO 8601
---
## Implementation Patterns
## Implementation Guidance
### Static Sites
- Add JSON-LD directly in HTML template
- Use includes/partials for reusable schema
### Dynamic Sites (React, Next.js, etc.)
- Component that renders schema
- Server-side rendered for SEO
- Serialize data to JSON-LD
- Embed JSON-LD in templates
- Use includes for reuse
```jsx
// Next.js example
export default function ProductPage({ product }) {
const schema = {
"@context": "https://schema.org",
"@type": "Product",
name: product.name,
// ... other properties
};
### Frameworks (React / Next.js)
return (
<>
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
</Head>
{/* Page content */}
</>
);
}
```
- Server-side rendered JSON-LD
- Data serialized directly from source
### CMS / WordPress
- Plugins (Yoast, Rank Math, Schema Pro)
- Theme modifications
- Custom fields to structured data
- Prefer structured plugins
- Use custom fields for dynamic values
- Avoid hardcoded schema in themes
---
## Output Format
## Output Format (Required)
### Schema Strategy Summary
- Eligibility Index score + verdict
- Supported schema types
- Risks and constraints
### JSON-LD Implementation
### Schema Implementation
```json
// Full JSON-LD code block
{
"@context": "https://schema.org",
"@type": "...",
// Complete markup
...
}
```
### Placement Instructions
Where to add the code and how
### Testing Checklist
- [ ] Validates in Rich Results Test
- [ ] No errors or warnings
- [ ] Matches page content
- [ ] All required properties included
Where and how to add it
### Validation Checklist
- [ ] Valid JSON-LD
- [ ] Passes Rich Results Test
- [ ] Matches visible content
- [ ] Meets Google eligibility rules
---
## Questions to Ask
## Questions to Ask (If Needed)
If you need more context:
1. What type of page is this?
2. What rich results are you hoping to achieve?
3. What data is available to populate the schema?
4. Is there existing schema on the page?
5. What's your tech stack for implementation?
1. What content is visible on the page?
2. Which rich result are you targeting (if any)?
3. Is this content templated or editorial?
4. How is this data maintained?
5. Is schema already present?
---
## Related Skills
- **seo-audit**: For overall SEO including schema review
- **programmatic-seo**: For templated schema at scale
- **analytics-tracking**: For measuring rich result impact
- **seo-audit** Full SEO review including schema
- **programmatic-seo** Templated schema at scale
- **analytics-tracking** Measure rich result impact

View File

@@ -1,41 +1,56 @@
---
name: seo-audit
description: When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," or "SEO health check." For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema-markup.
description: >
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.
---
# SEO Audit
You are an expert in search engine optimization. Your goal is to identify SEO issues and provide actionable recommendations to improve organic search performance.
You are an **SEO diagnostic specialist**.
Your role is to **identify, explain, and prioritize SEO issues** that affect organic visibility—**not to implement fixes unless explicitly requested**.
## Initial Assessment
Before auditing, understand:
1. **Site Context**
- What type of site? (SaaS, e-commerce, blog, etc.)
- What's the primary business goal for SEO?
- What keywords/topics are priorities?
2. **Current State**
- Any known issues or concerns?
- Current organic traffic level?
- Recent changes or migrations?
3. **Scope**
- Full site audit or specific pages?
- Technical + on-page, or one focus area?
- Access to Search Console / analytics?
Your output must be **evidence-based, scoped, and actionable**.
---
## Audit Framework
## Scope Gate (Ask First if Missing)
### Priority Order
1. **Crawlability & Indexation** (can Google find and index it?)
2. **Technical Foundations** (is the site fast and functional?)
3. **On-Page Optimization** (is content optimized?)
4. **Content Quality** (does it deserve to rank?)
5. **Authority & Links** (does it have credibility?)
Before performing a full audit, clarify:
1. **Business Context**
* Site type (SaaS, e-commerce, blog, local, marketplace, etc.)
* Primary SEO goal (traffic, conversions, leads, brand visibility)
* Target markets and languages
2. **SEO Focus**
* Full site audit or specific sections/pages?
* Technical SEO, on-page, content, or all?
* Desktop, mobile, or both?
3. **Data Access**
* Google Search Console access?
* Analytics access?
* Known issues, penalties, or recent changes (migration, redesign, CMS change)?
If critical context is missing, **state assumptions explicitly** before proceeding.
---
## Audit Framework (Priority Order)
1. **Crawlability & Indexation** Can search engines access and index the site?
2. **Technical Foundations** Is the site fast, stable, and accessible?
3. **On-Page Optimization** Is each page clearly optimized for its intent?
4. **Content Quality & E-E-A-T** Does the content deserve to rank?
5. **Authority & Signals** Does the site demonstrate trust and relevance?
---
@@ -44,96 +59,96 @@ Before auditing, understand:
### Crawlability
**Robots.txt**
- Check for unintentional blocks
- Verify important pages allowed
- Check sitemap reference
**XML Sitemap**
- Exists and accessible
- Submitted to Search Console
- Contains only canonical, indexable URLs
- Updated regularly
- Proper formatting
* Accidental blocking of important paths
* Sitemap reference present
* Environment-specific rules (prod vs staging)
**XML Sitemaps**
* Accessible and valid
* Contains only canonical, indexable URLs
* Reasonable size and segmentation
* Submitted and processed successfully
**Site Architecture**
- Important pages within 3 clicks of homepage
- Logical hierarchy
- Internal linking structure
- No orphan pages
**Crawl Budget Issues** (for large sites)
- Parameterized URLs under control
- Faceted navigation handled properly
- Infinite scroll with pagination fallback
- Session IDs not in URLs
* Key pages within ~3 clicks
* Logical hierarchy
* Internal linking coverage
* No orphaned URLs
**Crawl Efficiency (Large Sites)**
* Parameter handling
* Faceted navigation controls
* Infinite scroll with crawlable pagination
* Session IDs avoided
---
### Indexation
**Index Status**
- site:domain.com check
- Search Console coverage report
- Compare indexed vs. expected
**Coverage Analysis**
**Indexation Issues**
- Noindex tags on important pages
- Canonicals pointing wrong direction
- Redirect chains/loops
- Soft 404s
- Duplicate content without canonicals
* Indexed vs expected pages
* Excluded URLs (intentional vs accidental)
**Canonicalization**
- All pages have canonical tags
- Self-referencing canonicals on unique pages
- HTTP → HTTPS canonicals
- www vs. non-www consistency
- Trailing slash consistency
**Common Indexation Issues**
### Site Speed & Core Web Vitals
* Incorrect `noindex`
* Canonical conflicts
* Redirect chains or loops
* Soft 404s
* Duplicate content without consolidation
**Core Web Vitals**
- LCP (Largest Contentful Paint): < 2.5s
- INP (Interaction to Next Paint): < 200ms
- CLS (Cumulative Layout Shift): < 0.1
**Canonicalization Consistency**
**Speed Factors**
- Server response time (TTFB)
- Image optimization
- JavaScript execution
- CSS delivery
- Caching headers
- CDN usage
- Font loading
* Self-referencing canonicals
* HTTPS consistency
* Hostname consistency (www / non-www)
* Trailing slash rules
**Tools**
- PageSpeed Insights
- WebPageTest
- Chrome DevTools
- Search Console Core Web Vitals report
---
### Performance & Core Web Vitals
**Key Metrics**
* LCP < 2.5s
* INP < 200ms
* CLS < 0.1
**Contributing Factors**
* Server response time
* Image handling
* JavaScript execution cost
* CSS delivery
* Caching strategy
* CDN usage
* Font loading behavior
---
### Mobile-Friendliness
- Responsive design (not separate m. site)
- Tap target sizes
- Viewport configured
- No horizontal scroll
- Same content as desktop
- Mobile-first indexing readiness
* Responsive layout
* Proper viewport configuration
* Tap target sizing
* No horizontal scrolling
* Content parity with desktop
* Mobile-first indexing readiness
### Security & HTTPS
---
- HTTPS across entire site
- Valid SSL certificate
- No mixed content
- HTTP → HTTPS redirects
- HSTS header (bonus)
### Security & Accessibility Signals
### URL Structure
- Readable, descriptive URLs
- Keywords in URLs where natural
- Consistent structure
- No unnecessary parameters
- Lowercase and hyphen-separated
* HTTPS everywhere
* Valid certificates
* No mixed content
* HTTP → HTTPS redirects
* Accessibility issues that impact UX or crawling
---
@@ -141,244 +156,332 @@ Before auditing, understand:
### Title Tags
**Check for:**
- Unique titles for each page
- Primary keyword near beginning
- 50-60 characters (visible in SERP)
- Compelling and click-worthy
- Brand name placement (end, usually)
**Common issues:**
- Duplicate titles
- Too long (truncated)
- Too short (wasted opportunity)
- Keyword stuffing
- Missing entirely
* Unique per page
* Keyword-aligned
* Appropriate length
* Clear intent and differentiation
### Meta Descriptions
**Check for:**
- Unique descriptions per page
- 150-160 characters
- Includes primary keyword
- Clear value proposition
- Call to action
**Common issues:**
- Duplicate descriptions
- Auto-generated garbage
- Too long/short
- No compelling reason to click
* Unique and descriptive
* Supports click-through
* Not auto-generated noise
### Heading Structure
**Check for:**
- One H1 per page
- H1 contains primary keyword
- Logical hierarchy (H1 → H2 → H3)
- Headings describe content
- Not just for styling
**Common issues:**
- Multiple H1s
- Skip levels (H1 → H3)
- Headings used for styling only
- No H1 on page
* One clear H1
* Logical hierarchy
* Headings reflect content structure
### Content Optimization
**Primary Page Content**
- Keyword in first 100 words
- Related keywords naturally used
- Sufficient depth/length for topic
- Answers search intent
- Better than competitors
* Satisfies search intent
* Sufficient topical depth
* Natural keyword usage
* Not competing with other internal pages
**Thin Content Issues**
- Pages with little unique content
- Tag/category pages with no value
- Doorway pages
- Duplicate or near-duplicate content
### Images
### Image Optimization
**Check for:**
- Descriptive file names
- Alt text on all images
- Alt text describes image
- Compressed file sizes
- Modern formats (WebP)
- Lazy loading implemented
- Responsive images
* Descriptive filenames
* Accurate alt text
* Proper compression and formats
* Responsive handling and lazy loading
### Internal Linking
**Check for:**
- Important pages well-linked
- Descriptive anchor text
- Logical link relationships
- No broken internal links
- Reasonable link count per page
**Common issues:**
- Orphan pages (no internal links)
- Over-optimized anchor text
- Important pages buried
- Excessive footer/sidebar links
### Keyword Targeting
**Per Page**
- Clear primary keyword target
- Title, H1, URL aligned
- Content satisfies search intent
- Not competing with other pages (cannibalization)
**Site-Wide**
- Keyword mapping document
- No major gaps in coverage
- No keyword cannibalization
- Logical topical clusters
* Important pages reinforced
* Descriptive anchor text
* No broken links
* Balanced link distribution
---
## Content Quality Assessment
## Content Quality & E-E-A-T
### E-E-A-T Signals
### Experience & Expertise
**Experience**
- First-hand experience demonstrated
- Original insights/data
- Real examples and case studies
* First-hand knowledge
* Original insights or data
* Clear author attribution
**Expertise**
- Author credentials visible
- Accurate, detailed information
- Properly sourced claims
### Authoritativeness
**Authoritativeness**
- Recognized in the space
- Cited by others
- Industry credentials
* Citations or recognition
* Consistent topical focus
**Trustworthiness**
- Accurate information
- Transparent about business
- Contact information available
- Privacy policy, terms
- Secure site (HTTPS)
### Trustworthiness
### Content Depth
* Accurate, updated content
* Transparent business information
* Policies (privacy, terms)
* Secure site
- Comprehensive coverage of topic
- Answers follow-up questions
- Better than top-ranking competitors
- Updated and current
---
## 🔢 SEO Health Index & Scoring Layer (Additive)
### User Engagement Signals
### Purpose
- Time on page
- Bounce rate in context
- Pages per session
- Return visits
The **SEO Health Index** provides a **normalized, explainable score** that summarizes overall SEO health **without replacing detailed findings**.
It is designed to:
* Communicate severity at a glance
* Support prioritization
* Track improvement over time
* Avoid misleading “one-number SEO” claims
---
## Common Issues by Site Type
## Scoring Model Overview
### SaaS/Product Sites
- Product pages lack content depth
- Blog not integrated with product pages
- Missing comparison/alternative pages
- Feature pages thin on content
- No glossary/educational content
### Total Score: **0100**
### E-commerce
- Thin category pages
- Duplicate product descriptions
- Missing product schema
- Faceted navigation creating duplicates
- Out-of-stock pages mishandled
The score is a **weighted composite**, not an average.
### Content/Blog Sites
- Outdated content not refreshed
- Keyword cannibalization
- No topical clustering
- Poor internal linking
- Missing author pages
| Category | Weight |
| ------------------------- | ------- |
| Crawlability & Indexation | 30 |
| Technical Foundations | 25 |
| On-Page Optimization | 20 |
| Content Quality & E-E-A-T | 15 |
| Authority & Trust Signals | 10 |
| **Total** | **100** |
### Local Business
- Inconsistent NAP
- Missing local schema
- No Google Business Profile optimization
- Missing location pages
- No local content
> If a category is **out of scope**, redistribute its weight proportionally and state this explicitly.
---
## Output Format
## Category Scoring Rules
### Audit Report Structure
Each category is scored **independently**, then weighted.
**Executive Summary**
- Overall health assessment
- Top 3-5 priority issues
- Quick wins identified
### Per-Category Score: 0100
**Technical SEO Findings**
For each issue:
- **Issue**: What's wrong
- **Impact**: SEO impact (High/Medium/Low)
- **Evidence**: How you found it
- **Fix**: Specific recommendation
- **Priority**: 1-5 or High/Medium/Low
Start each category at **100** and subtract points based on issues found.
**On-Page SEO Findings**
Same format as above
#### Severity Deductions
**Content Findings**
Same format as above
| Issue Severity | Deduction |
| ------------------------------------------- | ---------- |
| Critical (blocks crawling/indexing/ranking) | 15 to 30 |
| High impact | 10 |
| Medium impact | 5 |
| Low impact / cosmetic | 1 to 3 |
**Prioritized Action Plan**
1. Critical fixes (blocking indexation/ranking)
2. High-impact improvements
3. Quick wins (easy, immediate benefit)
4. Long-term recommendations
#### Confidence Modifier
If confidence is **Medium**, apply **50%** of the deduction
If confidence is **Low**, apply **25%** of the deduction
---
## Tools Referenced
## Example (Category)
**Free Tools**
- Google Search Console (essential)
- Google PageSpeed Insights
- Bing Webmaster Tools
- Rich Results Test
- Mobile-Friendly Test
- Schema Validator
> Crawlability & Indexation (Weight: 30)
**Paid Tools** (if available)
- Screaming Frog
- Ahrefs / Semrush
- Sitebulb
- ContentKing
* Noindex on key category pages → Critical (25, High confidence)
* XML sitemap includes redirected URLs → Medium (5, Medium confidence → 2.5)
* Missing sitemap reference in robots.txt → Low (2)
**Raw score:** 100 29.5 = **70.5**
**Weighted contribution:** 70.5 × 0.30 = **21.15**
---
## Questions to Ask
## Overall SEO Health Index
If you need more context:
1. What pages/keywords matter most?
2. Do you have Search Console access?
3. Any recent changes or migrations?
4. Who are your top organic competitors?
5. What's your current organic traffic baseline?
### Calculation
```
SEO Health Index =
Σ (Category Score × Category Weight)
```
Rounded to nearest whole number.
---
## Related Skills
## Health Bands (Required)
Always classify the final score into a band:
| Score Range | Health Status | Interpretation |
| ----------- | ------------- | ----------------------------------------------- |
| 90100 | Excellent | Strong SEO foundation, minor optimizations only |
| 7589 | Good | Solid performance with clear improvement areas |
| 6074 | Fair | Meaningful issues limiting growth |
| 4059 | Poor | Serious SEO constraints |
| <40 | Critical | SEO is fundamentally broken |
---
## Output Requirements (Scoring Section)
Include this **after the Executive Summary**:
### SEO Health Index
* **Overall Score:** XX / 100
* **Health Status:** [Excellent / Good / Fair / Poor / Critical]
#### Category Breakdown
| Category | Score | Weight | Weighted Contribution |
| ------------------------- | ----- | ------ | --------------------- |
| Crawlability & Indexation | XX | 30 | XX |
| Technical Foundations | XX | 25 | XX |
| On-Page Optimization | XX | 20 | XX |
| Content Quality & E-E-A-T | XX | 15 | XX |
| Authority & Trust | XX | 10 | XX |
---
## Interpretation Rules (Mandatory)
* The score **does not replace findings**
* Improvements must be traceable to **specific issues**
* A high score with unresolved **Critical issues is invalid** → flag inconsistency
* Always explain **what limits the score from being higher**
---
## Change Tracking (Optional but Recommended)
If a previous audit exists:
* Include **score delta** (+/)
* Attribute change to specific fixes
* Avoid celebrating score increases without validating outcomes
---
## Explicit Limitations (Always State)
* Score reflects **SEO readiness**, not guaranteed rankings
* External factors (competition, algorithm updates) are not scored
* Authority score is directional, not exhaustive
### Findings Classification (Required · Scoring-Aligned)
For **every identified issue**, provide the following fields.
These fields are **mandatory** and directly inform the SEO Health Index.
* **Issue**
A concise description of what is wrong (one sentence, no solution).
* **Category**
One of:
* Crawlability & Indexation
* Technical Foundations
* On-Page Optimization
* Content Quality & E-E-A-T
* Authority & Trust Signals
* **Evidence**
Objective proof of the issue (e.g. URLs, reports, headers, crawl data, screenshots, metrics).
*Do not rely on intuition or best-practice claims.*
* **Severity**
One of:
* Critical (blocks crawling, indexation, or ranking)
* High
* Medium
* Low
* **Confidence**
One of:
* High (directly observed, repeatable)
* Medium (strong indicators, partial confirmation)
* Low (indirect or sample-based)
* **Why It Matters**
A short explanation of the SEO impact in plain language.
* **Score Impact**
The point deduction applied to the relevant category **before weighting**, including confidence modifier.
* **Recommendation**
What should be done to resolve the issue.
**Do not include implementation steps unless explicitly requested.**
---
### Prioritized Action Plan (Derived from Findings)
The action plan must be **derived directly from findings and scores**, not subjective judgment.
Group actions as follows:
1. **Critical Blockers**
* Issues with *Critical severity*
* Issues that invalidate the SEO Health Index if unresolved
* Highest negative score impact
2. **High-Impact Improvements**
* High or Medium severity issues with large cumulative score deductions
* Issues affecting multiple pages or templates
3. **Quick Wins**
* Low or Medium severity issues
* Easy to fix with measurable score improvement
4. **Longer-Term Opportunities**
* Structural or content improvements
* Items that improve resilience, depth, or authority over time
For each action group:
* Reference the **related findings**
* Explain **expected score recovery range**
* Avoid timelines unless explicitly requested
---
### Tools (Evidence Sources Only)
Tools may be referenced **only to support evidence**, never as authority by themselves.
Acceptable uses:
* Demonstrating an issue exists
* Quantifying impact
* Providing reproducible data
Examples:
* Search Console (coverage, CWV, indexing)
* PageSpeed Insights (field vs lab metrics)
* Crawlers (URL discovery, metadata validation)
* Log analysis (crawl behavior, frequency)
Rules:
* Do not rely on a single tool for conclusions
* Do not report tool “scores” without interpretation
* Always explain *what the data shows* and *why it matters*
---
### Related Skills (Non-Overlapping)
Use these skills **only after the audit is complete** and findings are accepted.
* **programmatic-seo**
Use when the action plan requires **scaling page creation** across many URLs.
* **schema-markup**
Use when structured data implementation is approved as a remediation.
* **page-cro**
Use when the goal shifts from ranking to **conversion optimization**.
* **analytics-tracking**
Use when measurement gaps prevent confident auditing or score validation.
- **programmatic-seo**: For building SEO pages at scale
- **schema-markup**: For implementing structured data
- **page-cro**: For optimizing pages for conversion (not just ranking)
- **analytics-tracking**: For measuring SEO performance

View File

@@ -1,129 +1,173 @@
---
name: seo-fundamentals
description: SEO fundamentals, E-E-A-T, Core Web Vitals, and Google algorithm principles.
description: >
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.
allowed-tools: Read, Glob, Grep
---
---
# SEO Fundamentals
> Principles for search engine visibility.
> **Foundational principles for sustainable search visibility.**
> This skill explains _how search engines evaluate quality_, not tactical shortcuts.
---
## 1. E-E-A-T Framework
## 1. E-E-A-T (Quality Evaluation Framework)
| Principle | Signals |
|-----------|---------|
| **Experience** | First-hand knowledge, real examples |
| **Expertise** | Credentials, depth of knowledge |
| **Authoritativeness** | Backlinks, mentions, industry recognition |
| **Trustworthiness** | HTTPS, transparency, accurate info |
E-E-A-T is **not a direct ranking factor**.
It is a framework used by search engines to **evaluate content quality**, especially for sensitive or high-impact topics.
| Dimension | What It Represents | Common Signals |
| --------------------- | ---------------------------------- | --------------------------------------------------- |
| **Experience** | First-hand, real-world involvement | Original examples, lived experience, demonstrations |
| **Expertise** | Subject-matter competence | Credentials, depth, accuracy |
| **Authoritativeness** | Recognition by others | Mentions, citations, links |
| **Trustworthiness** | Reliability and safety | HTTPS, transparency, accuracy |
> Pages competing in the same space are often differentiated by **trust and experience**, not keywords.
---
## 2. Core Web Vitals
## 2. Core Web Vitals (Page Experience Signals)
| Metric | Target | Measures |
|--------|--------|----------|
| **LCP** | < 2.5s | Loading performance |
| **INP** | < 200ms | Interactivity |
| **CLS** | < 0.1 | Visual stability |
Core Web Vitals measure **how users experience a page**, not whether it deserves to rank.
| Metric | Target | What It Reflects |
| ------- | ------- | ------------------- |
| **LCP** | < 2.5s | Loading performance |
| **INP** | < 200ms | Interactivity |
| **CLS** | < 0.1 | Visual stability |
**Important context:**
- CWV rarely override poor content
- They matter most when content quality is comparable
- Failing CWV can _hold back_ otherwise good pages
---
## 3. Technical SEO Principles
### Site Structure
Technical SEO ensures pages are **accessible, understandable, and stable**.
| Element | Purpose |
|---------|---------|
| XML sitemap | Help crawling |
| robots.txt | Control access |
| Canonical tags | Prevent duplicates |
| HTTPS | Security signal |
### Crawl & Index Control
### Performance
| Element | Purpose |
| ----------------- | ---------------------- |
| XML sitemaps | Help discovery |
| robots.txt | Control crawl access |
| Canonical tags | Consolidate duplicates |
| HTTP status codes | Communicate page state |
| HTTPS | Security and trust |
| Factor | Impact |
|--------|--------|
| Page speed | Core Web Vital |
| Mobile-friendly | Ranking factor |
| Clean URLs | Crawlability |
### Performance & Accessibility
| Factor | Why It Matters |
| ---------------------- | ----------------------------- |
| Page speed | User satisfaction |
| Mobile-friendly design | Mobile-first indexing |
| Clean URLs | Crawl clarity |
| Semantic HTML | Accessibility & understanding |
---
## 4. Content SEO Principles
### Page Elements
### Page-Level Elements
| Element | Best Practice |
|---------|---------------|
| Title tag | 50-60 chars, keyword front |
| Meta description | 150-160 chars, compelling |
| H1 | One per page, main keyword |
| H2-H6 | Logical hierarchy |
| Alt text | Descriptive, not stuffed |
| Element | Principle |
| ---------------- | ---------------------------- |
| Title tag | Clear topic + intent |
| Meta description | Click relevance, not ranking |
| H1 | Pages primary subject |
| Headings | Logical structure |
| Alt text | Accessibility and context |
### Content Quality
### Content Quality Signals
| Factor | Importance |
|--------|------------|
| Depth | Comprehensive coverage |
| Freshness | Regular updates |
| Uniqueness | Original value |
| Readability | Clear writing |
| Dimension | What Search Engines Look For |
| ----------- | ---------------------------- |
| Depth | Fully answers the query |
| Originality | Adds unique value |
| Accuracy | Factually correct |
| Clarity | Easy to understand |
| Usefulness | Satisfies intent |
---
## 5. Schema Markup Types
## 5. Structured Data (Schema)
| Type | Use |
|------|-----|
| Article | Blog posts, news |
| Organization | Company info |
| Person | Author profiles |
| FAQPage | Q&A content |
| Product | E-commerce |
| Review | Ratings |
| BreadcrumbList | Navigation |
Structured data helps search engines **understand meaning**, not boost rankings directly.
| Type | Purpose |
| -------------- | ---------------------- |
| Article | Content classification |
| Organization | Entity identity |
| Person | Author information |
| FAQPage | Q&A clarity |
| Product | Commerce details |
| Review | Ratings context |
| BreadcrumbList | Site structure |
> Schema enables eligibility for rich results but does not guarantee them.
---
## 6. AI Content Guidelines
## 6. AI-Assisted Content Principles
### What Google Looks For
Search engines evaluate **output quality**, not authorship method.
| ✅ Do | ❌ Don't |
|-------|----------|
| AI draft + human edit | Publish raw AI content |
| Add original insights | Copy without value |
| Expert review | Skip fact-checking |
| Follow E-E-A-T | Keyword stuffing |
### Effective Use
- AI as a drafting or research assistant
- Human review for accuracy and clarity
- Original insights and synthesis
- Clear accountability
### Risky Use
- Publishing unedited AI output
- Factual errors or hallucinations
- Thin or duplicated content
- Keyword-driven text with no value
---
## 7. Ranking Factors (Prioritized)
## 7. Relative Importance of SEO Factors
| Priority | Factor |
|----------|--------|
| 1 | Quality, relevant content |
| 2 | Backlinks from authority sites |
| 3 | Page experience (Core Web Vitals) |
| 4 | Mobile optimization |
| 5 | Technical SEO fundamentals |
There is **no fixed ranking factor order**.
However, when competing pages are similar, importance tends to follow this pattern:
| Relative Weight | Factor |
| --------------- | --------------------------- |
| Highest | Content relevance & quality |
| High | Authority & trust signals |
| Medium | Page experience (CWV, UX) |
| Medium | Mobile optimization |
| Baseline | Technical accessibility |
> Technical SEO enables ranking; content quality earns it.
---
## 8. Measurement
## 8. Measurement & Evaluation
| Metric | Tool |
|--------|------|
| Rankings | Search Console, Ahrefs |
| Traffic | Analytics |
| Core Web Vitals | PageSpeed Insights |
| Indexing | Search Console |
| Backlinks | Ahrefs, Semrush |
SEO fundamentals should be validated using **multiple signals**, not single metrics.
| Area | What to Observe |
| ----------- | -------------------------- |
| Visibility | Indexed pages, impressions |
| Engagement | Click-through, dwell time |
| Performance | CWV field data |
| Coverage | Indexing status |
| Authority | Mentions and links |
---
> **Remember:** SEO is a long-term game. Quality content + technical excellence + patience = results.
> **Key Principle:**
> Sustainable SEO is built on _useful content_, _technical clarity_, and _trust over time_.
> There are no permanent shortcuts.

View File

@@ -0,0 +1,175 @@
# Voice AI Engine Development Skill
Build production-ready real-time conversational AI voice engines with async worker pipelines, streaming transcription, LLM agents, and TTS synthesis.
## Overview
This skill provides comprehensive guidance for building voice AI engines that enable natural, bidirectional conversations between users and AI agents. It covers the complete architecture from audio input to audio output, including:
- **Async Worker Pipeline Pattern** - Concurrent processing with queue-based communication
- **Streaming Transcription** - Real-time speech-to-text conversion
- **LLM-Powered Agents** - Conversational AI with context awareness
- **Text-to-Speech Synthesis** - Natural voice generation
- **Interrupt Handling** - Users can interrupt the bot mid-sentence
- **Multi-Provider Support** - Swap between different service providers easily
## Quick Start
```python
# Use the skill in your AI assistant
@voice-ai-engine-development I need to build a voice assistant that can handle real-time conversations with interrupts
```
## What's Included
### Main Skill File
- `SKILL.md` - Comprehensive guide to voice AI engine development
### Examples
- `complete_voice_engine.py` - Full working implementation
- `gemini_agent_example.py` - LLM agent with proper response buffering
- `interrupt_system_example.py` - Interrupt handling demonstration
### Templates
- `base_worker_template.py` - Template for creating new workers
- `multi_provider_factory_template.py` - Multi-provider factory pattern
### References
- `common_pitfalls.md` - Common issues and solutions
- `provider_comparison.md` - Comparison of transcription, LLM, and TTS providers
## Key Concepts
### The Worker Pipeline Pattern
Every voice AI engine follows this pipeline:
```
Audio In → Transcriber → Agent → Synthesizer → Audio Out
(Worker 1) (Worker 2) (Worker 3)
```
Each worker:
- Runs independently via asyncio
- Communicates through asyncio.Queue objects
- Can be stopped mid-stream for interrupts
- Handles errors gracefully
### Critical Implementation Details
1. **Buffer LLM Responses** - Always buffer the entire LLM response before sending to synthesizer to prevent audio jumping
2. **Mute Transcriber** - Mute the transcriber when bot speaks to prevent echo/feedback loops
3. **Rate-Limit Audio** - Send audio chunks at real-time speed to enable interrupts
4. **Proper Cleanup** - Always cleanup resources in finally blocks to prevent memory leaks
## Supported Providers
### Transcription
- Deepgram (fastest, best for real-time)
- AssemblyAI (highest accuracy)
- Azure Speech (enterprise-grade)
- Google Cloud Speech (multi-language)
### LLM
- OpenAI GPT-4 (highest quality)
- Google Gemini (cost-effective)
- Anthropic Claude (safety-focused)
### TTS
- ElevenLabs (most natural voices)
- Azure TTS (enterprise-grade)
- Google Cloud TTS (cost-effective)
- Amazon Polly (AWS integration)
- Play.ht (voice cloning)
## Common Use Cases
- Customer service voice bots
- Voice assistants
- Phone automation systems
- Voice-enabled applications
- Interactive voice response (IVR) systems
- Voice-based tutoring systems
## Architecture Highlights
### Async Worker Pattern
```python
class BaseWorker:
async def _run_loop(self):
while self.active:
item = await self.input_queue.get()
await self.process(item)
```
### Interrupt System
```python
# User interrupts bot mid-sentence
if stop_event.is_set():
partial_message = get_message_up_to(seconds_spoken)
return partial_message, True # cut_off = True
```
### Multi-Provider Factory
```python
factory = VoiceComponentFactory()
transcriber = factory.create_transcriber(config) # Deepgram, AssemblyAI, etc.
agent = factory.create_agent(config) # OpenAI, Gemini, etc.
synthesizer = factory.create_synthesizer(config) # ElevenLabs, Azure, etc.
```
## Testing
The skill includes examples for:
- Unit testing workers in isolation
- Integration testing the full pipeline
- Testing interrupt functionality
- Testing with different providers
## Best Practices
1. ✅ Always stream at every stage (transcription, LLM, synthesis)
2. ✅ Buffer entire LLM responses before synthesis
3. ✅ Mute transcriber during bot speech
4. ✅ Rate-limit audio chunks for interrupts
5. ✅ Maintain conversation history for context
6. ✅ Use proper error handling in worker loops
7. ✅ Cleanup resources in finally blocks
8. ✅ Use LINEAR16 PCM at 16kHz for audio
## Common Pitfalls
See `references/common_pitfalls.md` for detailed solutions to:
- Audio jumping/cutting off
- Echo/feedback loops
- Interrupts not working
- Memory leaks
- Lost conversation context
- High latency
- Poor audio quality
## Contributing
This skill is part of the Antigravity Awesome Skills repository. Contributions are welcome!
## Related Skills
- `@websocket-patterns` - WebSocket implementation
- `@async-python` - Asyncio patterns
- `@streaming-apis` - Streaming API integration
- `@audio-processing` - Audio format conversion
## License
MIT License - See repository LICENSE file
## Resources
- [Vocode Documentation](https://docs.vocode.dev/)
- [Deepgram API](https://developers.deepgram.com/)
- [OpenAI API](https://platform.openai.com/docs/)
- [ElevenLabs API](https://elevenlabs.io/docs/)
---
**Built with ❤️ for the Antigravity community**

View File

@@ -0,0 +1,721 @@
---
name: voice-ai-engine-development
description: "Build real-time conversational AI voice engines using async worker pipelines, streaming transcription, LLM agents, and TTS synthesis with interrupt handling and multi-provider support"
---
# Voice AI Engine Development
## Overview
This skill guides you through building production-ready voice AI engines with real-time conversation capabilities. Voice AI engines enable natural, bidirectional conversations between users and AI agents through streaming audio processing, speech-to-text transcription, LLM-powered responses, and text-to-speech synthesis.
The core architecture uses an async queue-based worker pipeline where each component runs independently and communicates via `asyncio.Queue` objects, enabling concurrent processing, interrupt handling, and real-time streaming at every stage.
## When to Use This Skill
Use this skill when:
- Building real-time voice conversation systems
- Implementing voice assistants or chatbots
- Creating voice-enabled customer service agents
- Developing voice AI applications with interrupt capabilities
- Integrating multiple transcription, LLM, or TTS providers
- Working with streaming audio processing pipelines
- The user mentions Vocode, voice engines, or conversational AI
## Core Architecture Principles
### The Worker Pipeline Pattern
Every voice AI engine follows this pipeline:
```
Audio In → Transcriber → Agent → Synthesizer → Audio Out
(Worker 1) (Worker 2) (Worker 3)
```
**Key Benefits:**
- **Decoupling**: Workers only know about their input/output queues
- **Concurrency**: All workers run simultaneously via asyncio
- **Backpressure**: Queues automatically handle rate differences
- **Interruptibility**: Everything can be stopped mid-stream
### Base Worker Pattern
Every worker follows this pattern:
```python
class BaseWorker:
def __init__(self, input_queue, output_queue):
self.input_queue = input_queue # asyncio.Queue to consume from
self.output_queue = output_queue # asyncio.Queue to produce to
self.active = False
def start(self):
"""Start the worker's processing loop"""
self.active = True
asyncio.create_task(self._run_loop())
async def _run_loop(self):
"""Main processing loop - runs forever until terminated"""
while self.active:
item = await self.input_queue.get() # Block until item arrives
await self.process(item) # Process the item
async def process(self, item):
"""Override this - does the actual work"""
raise NotImplementedError
def terminate(self):
"""Stop the worker"""
self.active = False
```
## Component Implementation Guide
### 1. Transcriber (Audio → Text)
**Purpose**: Converts incoming audio chunks to text transcriptions
**Interface Requirements**:
```python
class BaseTranscriber:
def __init__(self, transcriber_config):
self.input_queue = asyncio.Queue() # Audio chunks (bytes)
self.output_queue = asyncio.Queue() # Transcriptions
self.is_muted = False
def send_audio(self, chunk: bytes):
"""Client calls this to send audio"""
if not self.is_muted:
self.input_queue.put_nowait(chunk)
else:
# Send silence instead (prevents echo during bot speech)
self.input_queue.put_nowait(self.create_silent_chunk(len(chunk)))
def mute(self):
"""Called when bot starts speaking (prevents echo)"""
self.is_muted = True
def unmute(self):
"""Called when bot stops speaking"""
self.is_muted = False
```
**Output Format**:
```python
class Transcription:
message: str # "Hello, how are you?"
confidence: float # 0.95
is_final: bool # True = complete sentence, False = partial
is_interrupt: bool # Set by TranscriptionsWorker
```
**Supported Providers**:
- **Deepgram** - Fast, accurate, streaming
- **AssemblyAI** - High accuracy, good for accents
- **Azure Speech** - Enterprise-grade
- **Google Cloud Speech** - Multi-language support
**Critical Implementation Details**:
- Use WebSocket for bidirectional streaming
- Run sender and receiver tasks concurrently with `asyncio.gather()`
- Mute transcriber when bot speaks to prevent echo/feedback loops
- Handle both final and partial transcriptions
### 2. Agent (Text → Response)
**Purpose**: Processes user input and generates conversational responses
**Interface Requirements**:
```python
class BaseAgent:
def __init__(self, agent_config):
self.input_queue = asyncio.Queue() # TranscriptionAgentInput
self.output_queue = asyncio.Queue() # AgentResponse
self.transcript = None # Conversation history
async def generate_response(self, human_input, is_interrupt, conversation_id):
"""Override this - returns AsyncGenerator of responses"""
raise NotImplementedError
```
**Why Streaming Responses?**
- **Lower latency**: Start speaking as soon as first sentence is ready
- **Better interrupts**: Can stop mid-response
- **Sentence-by-sentence**: More natural conversation flow
**Supported Providers**:
- **OpenAI** (GPT-4, GPT-3.5) - High quality, fast
- **Google Gemini** - Multimodal, cost-effective
- **Anthropic Claude** - Long context, nuanced responses
**Critical Implementation Details**:
- Maintain conversation history in `Transcript` object
- Stream responses using `AsyncGenerator`
- **IMPORTANT**: Buffer entire LLM response before yielding to synthesizer (prevents audio jumping)
- Handle interrupts by canceling current generation task
- Update conversation history with partial messages on interrupt
### 3. Synthesizer (Text → Audio)
**Purpose**: Converts agent text responses to speech audio
**Interface Requirements**:
```python
class BaseSynthesizer:
async def create_speech(self, message: BaseMessage, chunk_size: int) -> SynthesisResult:
"""
Returns a SynthesisResult containing:
- chunk_generator: AsyncGenerator that yields audio chunks
- get_message_up_to: Function to get partial text (for interrupts)
"""
raise NotImplementedError
```
**SynthesisResult Structure**:
```python
class SynthesisResult:
chunk_generator: AsyncGenerator[ChunkResult, None]
get_message_up_to: Callable[[float], str] # seconds → partial text
class ChunkResult:
chunk: bytes # Raw PCM audio
is_last_chunk: bool
```
**Supported Providers**:
- **ElevenLabs** - Most natural voices, streaming
- **Azure TTS** - Enterprise-grade, many languages
- **Google Cloud TTS** - Cost-effective, good quality
- **Amazon Polly** - AWS integration
- **Play.ht** - Voice cloning
**Critical Implementation Details**:
- Stream audio chunks as they're generated
- Convert audio to LINEAR16 PCM format (16kHz sample rate)
- Implement `get_message_up_to()` for interrupt handling
- Handle audio format conversion (MP3 → PCM)
### 4. Output Device (Audio → Client)
**Purpose**: Sends synthesized audio back to the client
**CRITICAL: Rate Limiting for Interrupts**
```python
async def send_speech_to_output(self, message, synthesis_result,
stop_event, seconds_per_chunk):
chunk_idx = 0
async for chunk_result in synthesis_result.chunk_generator:
# Check for interrupt
if stop_event.is_set():
logger.debug(f"Interrupted after {chunk_idx} chunks")
message_sent = synthesis_result.get_message_up_to(
chunk_idx * seconds_per_chunk
)
return message_sent, True # cut_off = True
start_time = time.time()
# Send chunk to output device
self.output_device.consume_nonblocking(chunk_result.chunk)
# CRITICAL: Wait for chunk to play before sending next one
# This is what makes interrupts work!
speech_length = seconds_per_chunk
processing_time = time.time() - start_time
await asyncio.sleep(max(speech_length - processing_time, 0))
chunk_idx += 1
return message, False # cut_off = False
```
**Why Rate Limiting?**
Without rate limiting, all audio chunks would be sent immediately, which would:
- Buffer entire message on client side
- Make interrupts impossible (all audio already sent)
- Cause timing issues
By sending one chunk every N seconds:
- Real-time playback is maintained
- Interrupts can stop mid-sentence
- Natural conversation flow is preserved
## The Interrupt System
The interrupt system is critical for natural conversations.
### How Interrupts Work
**Scenario**: Bot is saying "I think the weather will be nice today and tomorrow and—" when user interrupts with "Stop".
**Step 1: User starts speaking**
```python
# TranscriptionsWorker detects new transcription while bot speaking
async def process(self, transcription):
if not self.conversation.is_human_speaking: # Bot was speaking!
# Broadcast interrupt to all in-flight events
interrupted = self.conversation.broadcast_interrupt()
transcription.is_interrupt = interrupted
```
**Step 2: broadcast_interrupt() stops everything**
```python
def broadcast_interrupt(self):
num_interrupts = 0
# Interrupt all queued events
while True:
try:
interruptible_event = self.interruptible_events.get_nowait()
if interruptible_event.interrupt(): # Sets interruption_event
num_interrupts += 1
except queue.Empty:
break
# Cancel current tasks
self.agent.cancel_current_task() # Stop generating text
self.agent_responses_worker.cancel_current_task() # Stop synthesizing
return num_interrupts > 0
```
**Step 3: SynthesisResultsWorker detects interrupt**
```python
async def send_speech_to_output(self, synthesis_result, stop_event, ...):
async for chunk_result in synthesis_result.chunk_generator:
# Check stop_event (this is the interruption_event)
if stop_event.is_set():
logger.debug("Interrupted! Stopping speech.")
# Calculate what was actually spoken
seconds_spoken = chunk_idx * seconds_per_chunk
partial_message = synthesis_result.get_message_up_to(seconds_spoken)
# e.g., "I think the weather will be nice today"
return partial_message, True # cut_off = True
```
**Step 4: Agent updates history**
```python
if cut_off:
# Update conversation history with partial message
self.agent.update_last_bot_message_on_cut_off(message_sent)
# History now shows:
# Bot: "I think the weather will be nice today" (incomplete)
```
### InterruptibleEvent Pattern
Every event in the pipeline is wrapped in an `InterruptibleEvent`:
```python
class InterruptibleEvent:
def __init__(self, payload, is_interruptible=True):
self.payload = payload
self.is_interruptible = is_interruptible
self.interruption_event = threading.Event() # Initially not set
self.interrupted = False
def interrupt(self) -> bool:
"""Interrupt this event"""
if not self.is_interruptible:
return False
if not self.interrupted:
self.interruption_event.set() # Signal to stop!
self.interrupted = True
return True
return False
def is_interrupted(self) -> bool:
return self.interruption_event.is_set()
```
## Multi-Provider Factory Pattern
Support multiple providers with a factory pattern:
```python
class VoiceHandler:
"""Multi-provider factory for voice components"""
def create_transcriber(self, agent_config: Dict):
"""Create transcriber based on transcriberProvider"""
provider = agent_config.get("transcriberProvider", "deepgram")
if provider == "deepgram":
return self._create_deepgram_transcriber(agent_config)
elif provider == "assemblyai":
return self._create_assemblyai_transcriber(agent_config)
elif provider == "azure":
return self._create_azure_transcriber(agent_config)
elif provider == "google":
return self._create_google_transcriber(agent_config)
else:
raise ValueError(f"Unknown transcriber provider: {provider}")
def create_agent(self, agent_config: Dict):
"""Create LLM agent based on llmProvider"""
provider = agent_config.get("llmProvider", "openai")
if provider == "openai":
return self._create_openai_agent(agent_config)
elif provider == "gemini":
return self._create_gemini_agent(agent_config)
else:
raise ValueError(f"Unknown LLM provider: {provider}")
def create_synthesizer(self, agent_config: Dict):
"""Create voice synthesizer based on voiceProvider"""
provider = agent_config.get("voiceProvider", "elevenlabs")
if provider == "elevenlabs":
return self._create_elevenlabs_synthesizer(agent_config)
elif provider == "azure":
return self._create_azure_synthesizer(agent_config)
elif provider == "google":
return self._create_google_synthesizer(agent_config)
elif provider == "polly":
return self._create_polly_synthesizer(agent_config)
elif provider == "playht":
return self._create_playht_synthesizer(agent_config)
else:
raise ValueError(f"Unknown voice provider: {provider}")
```
## WebSocket Integration
Voice AI engines typically use WebSocket for bidirectional audio streaming:
```python
@app.websocket("/conversation")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
# Create voice components
voice_handler = VoiceHandler()
transcriber = voice_handler.create_transcriber(agent_config)
agent = voice_handler.create_agent(agent_config)
synthesizer = voice_handler.create_synthesizer(agent_config)
# Create output device
output_device = WebsocketOutputDevice(
ws=websocket,
sampling_rate=16000,
audio_encoding=AudioEncoding.LINEAR16
)
# Create conversation orchestrator
conversation = StreamingConversation(
output_device=output_device,
transcriber=transcriber,
agent=agent,
synthesizer=synthesizer
)
# Start all workers
await conversation.start()
try:
# Receive audio from client
async for message in websocket.iter_bytes():
conversation.receive_audio(message)
except WebSocketDisconnect:
logger.info("Client disconnected")
finally:
await conversation.terminate()
```
## Common Pitfalls and Solutions
### 1. Audio Jumping/Cutting Off
**Problem**: Bot's audio jumps or cuts off mid-response.
**Cause**: Sending text to synthesizer in small chunks causes multiple TTS calls.
**Solution**: Buffer the entire LLM response before sending to synthesizer:
```python
# ❌ Bad: Yields sentence-by-sentence
async for sentence in llm_stream:
yield GeneratedResponse(message=BaseMessage(text=sentence))
# ✅ Good: Buffer entire response
full_response = ""
async for chunk in llm_stream:
full_response += chunk
yield GeneratedResponse(message=BaseMessage(text=full_response))
```
### 2. Echo/Feedback Loop
**Problem**: Bot hears itself speaking and responds to its own audio.
**Cause**: Transcriber not muted during bot speech.
**Solution**: Mute transcriber when bot starts speaking:
```python
# Before sending audio to output
self.transcriber.mute()
# After audio playback complete
self.transcriber.unmute()
```
### 3. Interrupts Not Working
**Problem**: User can't interrupt bot mid-sentence.
**Cause**: All audio chunks sent at once instead of rate-limited.
**Solution**: Rate-limit audio chunks to match real-time playback:
```python
async for chunk in synthesis_result.chunk_generator:
start_time = time.time()
# Send chunk
output_device.consume_nonblocking(chunk)
# Wait for chunk duration before sending next
processing_time = time.time() - start_time
await asyncio.sleep(max(seconds_per_chunk - processing_time, 0))
```
### 4. Memory Leaks from Unclosed Streams
**Problem**: Memory usage grows over time.
**Cause**: WebSocket connections or API streams not properly closed.
**Solution**: Always use context managers and cleanup:
```python
try:
async with websockets.connect(url) as ws:
# Use websocket
pass
finally:
# Cleanup
await conversation.terminate()
await transcriber.terminate()
```
## Production Considerations
### 1. Error Handling
```python
async def _run_loop(self):
while self.active:
try:
item = await self.input_queue.get()
await self.process(item)
except Exception as e:
logger.error(f"Worker error: {e}", exc_info=True)
# Don't crash the worker, continue processing
```
### 2. Graceful Shutdown
```python
async def terminate(self):
"""Gracefully shut down all workers"""
self.active = False
# Stop all workers
self.transcriber.terminate()
self.agent.terminate()
self.synthesizer.terminate()
# Wait for queues to drain
await asyncio.sleep(0.5)
# Close connections
if self.websocket:
await self.websocket.close()
```
### 3. Monitoring and Logging
```python
# Log key events
logger.info(f"🎤 [TRANSCRIBER] Received: '{transcription.message}'")
logger.info(f"🤖 [AGENT] Generating response...")
logger.info(f"🔊 [SYNTHESIZER] Synthesizing {len(text)} characters")
logger.info(f"⚠️ [INTERRUPT] User interrupted bot")
# Track metrics
metrics.increment("transcriptions.count")
metrics.timing("agent.response_time", duration)
metrics.gauge("active_conversations", count)
```
### 4. Rate Limiting and Quotas
```python
# Implement rate limiting for API calls
from aiolimiter import AsyncLimiter
rate_limiter = AsyncLimiter(max_rate=10, time_period=1) # 10 calls/second
async def call_api(self, data):
async with rate_limiter:
return await self.client.post(data)
```
## Key Design Patterns
### 1. Producer-Consumer with Queues
```python
# Producer
async def producer(queue):
while True:
item = await generate_item()
queue.put_nowait(item)
# Consumer
async def consumer(queue):
while True:
item = await queue.get()
await process_item(item)
```
### 2. Streaming Generators
Instead of returning complete results:
```python
# ❌ Bad: Wait for entire response
async def generate_response(prompt):
response = await openai.complete(prompt) # 5 seconds
return response
# ✅ Good: Stream chunks as they arrive
async def generate_response(prompt):
async for chunk in openai.complete(prompt, stream=True):
yield chunk # Yield after 0.1s, 0.2s, etc.
```
### 3. Conversation State Management
Maintain conversation history for context:
```python
class Transcript:
event_logs: List[Message] = []
def add_human_message(self, text):
self.event_logs.append(Message(sender=Sender.HUMAN, text=text))
def add_bot_message(self, text):
self.event_logs.append(Message(sender=Sender.BOT, text=text))
def to_openai_messages(self):
return [
{"role": "user" if msg.sender == Sender.HUMAN else "assistant",
"content": msg.text}
for msg in self.event_logs
]
```
## Testing Strategies
### 1. Unit Test Workers in Isolation
```python
async def test_transcriber():
transcriber = DeepgramTranscriber(config)
# Mock audio input
audio_chunk = b'\x00\x01\x02...'
transcriber.send_audio(audio_chunk)
# Check output
transcription = await transcriber.output_queue.get()
assert transcription.message == "expected text"
```
### 2. Integration Test Pipeline
```python
async def test_full_pipeline():
# Create all components
conversation = create_test_conversation()
# Send test audio
conversation.receive_audio(test_audio_chunk)
# Wait for response
response = await wait_for_audio_output(timeout=5)
assert response is not None
```
### 3. Test Interrupts
```python
async def test_interrupt():
conversation = create_test_conversation()
# Start bot speaking
await conversation.agent.generate_response("Tell me a long story")
# Interrupt mid-response
await asyncio.sleep(1) # Let it speak for 1 second
conversation.broadcast_interrupt()
# Verify partial message in transcript
last_message = conversation.transcript.event_logs[-1]
assert last_message.text != full_expected_message
```
## Implementation Workflow
When implementing a voice AI engine:
1. **Start with Base Workers**: Implement the base worker pattern first
2. **Add Transcriber**: Choose a provider and implement streaming transcription
3. **Add Agent**: Implement LLM integration with streaming responses
4. **Add Synthesizer**: Implement TTS with audio streaming
5. **Connect Pipeline**: Wire all workers together with queues
6. **Add Interrupts**: Implement the interrupt system
7. **Add WebSocket**: Create WebSocket endpoint for client communication
8. **Test Components**: Unit test each worker in isolation
9. **Test Integration**: Test the full pipeline end-to-end
10. **Add Error Handling**: Implement robust error handling and logging
11. **Optimize**: Add rate limiting, monitoring, and performance optimizations
## Related Skills
- `@websocket-patterns` - For WebSocket implementation details
- `@async-python` - For asyncio and async patterns
- `@streaming-apis` - For streaming API integration
- `@audio-processing` - For audio format conversion and processing
- `@systematic-debugging` - For debugging complex async pipelines
## Resources
**Libraries**:
- `asyncio` - Async programming
- `websockets` - WebSocket client/server
- `FastAPI` - WebSocket server framework
- `pydub` - Audio manipulation
- `numpy` - Audio data processing
**API Providers**:
- Transcription: Deepgram, AssemblyAI, Azure Speech, Google Cloud Speech
- LLM: OpenAI, Google Gemini, Anthropic Claude
- TTS: ElevenLabs, Azure TTS, Google Cloud TTS, Amazon Polly, Play.ht
## Summary
Building a voice AI engine requires:
- ✅ Async worker pipeline for concurrent processing
- ✅ Queue-based communication between components
- ✅ Streaming at every stage (transcription, LLM, synthesis)
- ✅ Interrupt system for natural conversations
- ✅ Rate limiting for real-time audio playback
- ✅ Multi-provider support for flexibility
- ✅ Proper error handling and graceful shutdown
**The key insight**: Everything must stream and everything must be interruptible for natural, real-time conversations.

View File

@@ -0,0 +1,423 @@
"""
Example: Complete Voice AI Engine Implementation
This example demonstrates a minimal but complete voice AI engine
with all core components: Transcriber, Agent, Synthesizer, and WebSocket integration.
"""
import asyncio
from typing import Dict, AsyncGenerator
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from dataclasses import dataclass
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI()
# ============================================================================
# Data Models
# ============================================================================
@dataclass
class Transcription:
message: str
confidence: float
is_final: bool
is_interrupt: bool = False
@dataclass
class AgentResponse:
message: str
is_interruptible: bool = True
@dataclass
class SynthesisResult:
chunk_generator: AsyncGenerator[bytes, None]
get_message_up_to: callable
# ============================================================================
# Base Worker Pattern
# ============================================================================
class BaseWorker:
"""Base class for all workers in the pipeline"""
def __init__(self, input_queue: asyncio.Queue, output_queue: asyncio.Queue):
self.input_queue = input_queue
self.output_queue = output_queue
self.active = False
self._task = None
def start(self):
"""Start the worker's processing loop"""
self.active = True
self._task = asyncio.create_task(self._run_loop())
async def _run_loop(self):
"""Main processing loop - runs forever until terminated"""
while self.active:
try:
item = await self.input_queue.get()
await self.process(item)
except Exception as e:
logger.error(f"Worker error: {e}", exc_info=True)
async def process(self, item):
"""Override this - does the actual work"""
raise NotImplementedError
def terminate(self):
"""Stop the worker"""
self.active = False
if self._task:
self._task.cancel()
# ============================================================================
# Transcriber Component
# ============================================================================
class DeepgramTranscriber(BaseWorker):
"""Converts audio chunks to text transcriptions using Deepgram"""
def __init__(self, config: Dict):
super().__init__(asyncio.Queue(), asyncio.Queue())
self.config = config
self.is_muted = False
def send_audio(self, chunk: bytes):
"""Client calls this to send audio"""
if not self.is_muted:
self.input_queue.put_nowait(chunk)
else:
# Send silence instead (prevents echo during bot speech)
self.input_queue.put_nowait(self.create_silent_chunk(len(chunk)))
def create_silent_chunk(self, size: int) -> bytes:
"""Create a silent audio chunk"""
return b'\x00' * size
def mute(self):
"""Called when bot starts speaking (prevents echo)"""
self.is_muted = True
logger.info("🔇 [TRANSCRIBER] Muted")
def unmute(self):
"""Called when bot stops speaking"""
self.is_muted = False
logger.info("🔊 [TRANSCRIBER] Unmuted")
async def process(self, audio_chunk: bytes):
"""Process audio chunk and generate transcription"""
# In a real implementation, this would call Deepgram API
# For this example, we'll simulate a transcription
# Simulate API call delay
await asyncio.sleep(0.1)
# Mock transcription
transcription = Transcription(
message="Hello, how can I help you?",
confidence=0.95,
is_final=True
)
logger.info(f"🎤 [TRANSCRIBER] Received: '{transcription.message}'")
self.output_queue.put_nowait(transcription)
# ============================================================================
# Agent Component
# ============================================================================
class GeminiAgent(BaseWorker):
"""LLM-powered conversational agent using Google Gemini"""
def __init__(self, config: Dict):
super().__init__(asyncio.Queue(), asyncio.Queue())
self.config = config
self.conversation_history = []
async def process(self, transcription: Transcription):
"""Process transcription and generate response"""
# Add user message to history
self.conversation_history.append({
"role": "user",
"content": transcription.message
})
logger.info(f"🤖 [AGENT] Generating response for: '{transcription.message}'")
# Generate response (streaming)
async for response in self.generate_response(transcription.message):
self.output_queue.put_nowait(response)
async def generate_response(self, user_input: str) -> AsyncGenerator[AgentResponse, None]:
"""Generate streaming response from LLM"""
# In a real implementation, this would call Gemini API
# For this example, we'll simulate a streaming response
# Simulate streaming delay
await asyncio.sleep(0.5)
# IMPORTANT: Buffer entire response before yielding
# This prevents audio jumping/cutting off
full_response = f"I understand you said: {user_input}. How can I assist you further?"
# Add to conversation history
self.conversation_history.append({
"role": "assistant",
"content": full_response
})
logger.info(f"🤖 [AGENT] Generated: '{full_response}'")
# Yield complete response
yield AgentResponse(
message=full_response,
is_interruptible=True
)
# ============================================================================
# Synthesizer Component
# ============================================================================
class ElevenLabsSynthesizer:
"""Converts text to speech using ElevenLabs"""
def __init__(self, config: Dict):
self.config = config
async def create_speech(self, message: str, chunk_size: int = 1024) -> SynthesisResult:
"""
Generate speech audio from text
Returns SynthesisResult with:
- chunk_generator: AsyncGenerator yielding audio chunks
- get_message_up_to: Function to get partial text for interrupts
"""
# In a real implementation, this would call ElevenLabs API
# For this example, we'll simulate audio generation
logger.info(f"🔊 [SYNTHESIZER] Synthesizing {len(message)} characters")
async def chunk_generator():
# Simulate streaming audio chunks
num_chunks = len(message) // 10 + 1
for i in range(num_chunks):
# Simulate API delay
await asyncio.sleep(0.1)
# Mock audio chunk (in reality, this would be PCM audio)
chunk = b'\x00' * chunk_size
yield chunk
def get_message_up_to(seconds: float) -> str:
"""Calculate partial message based on playback time"""
# Estimate: ~150 words per minute = ~2.5 words per second
# Rough estimate: 5 characters per word
chars_per_second = 12.5
char_index = int(seconds * chars_per_second)
return message[:char_index]
return SynthesisResult(
chunk_generator=chunk_generator(),
get_message_up_to=get_message_up_to
)
# ============================================================================
# Output Device
# ============================================================================
class WebsocketOutputDevice:
"""Sends audio chunks to client via WebSocket"""
def __init__(self, websocket: WebSocket):
self.websocket = websocket
async def consume_nonblocking(self, chunk: bytes):
"""Send audio chunk to client"""
await self.websocket.send_bytes(chunk)
# ============================================================================
# Conversation Orchestrator
# ============================================================================
class StreamingConversation:
"""Orchestrates the entire voice conversation pipeline"""
def __init__(
self,
output_device: WebsocketOutputDevice,
transcriber: DeepgramTranscriber,
agent: GeminiAgent,
synthesizer: ElevenLabsSynthesizer
):
self.output_device = output_device
self.transcriber = transcriber
self.agent = agent
self.synthesizer = synthesizer
self.is_human_speaking = True
self.interrupt_event = asyncio.Event()
async def start(self):
"""Start all workers"""
logger.info("🚀 [CONVERSATION] Starting...")
# Start workers
self.transcriber.start()
self.agent.start()
# Start processing pipelines
asyncio.create_task(self._process_transcriptions())
asyncio.create_task(self._process_agent_responses())
async def _process_transcriptions(self):
"""Process transcriptions from transcriber"""
while True:
transcription = await self.transcriber.output_queue.get()
# Check if this is an interrupt
if not self.is_human_speaking:
logger.info("⚠️ [INTERRUPT] User interrupted bot")
self.interrupt_event.set()
transcription.is_interrupt = True
self.is_human_speaking = True
# Send to agent
await self.agent.input_queue.put(transcription)
async def _process_agent_responses(self):
"""Process responses from agent and synthesize"""
while True:
response = await self.agent.output_queue.get()
self.is_human_speaking = False
# Mute transcriber to prevent echo
self.transcriber.mute()
# Synthesize and play
synthesis_result = await self.synthesizer.create_speech(response.message)
await self._send_speech_to_output(synthesis_result, seconds_per_chunk=0.1)
# Unmute transcriber
self.transcriber.unmute()
self.is_human_speaking = True
async def _send_speech_to_output(self, synthesis_result: SynthesisResult, seconds_per_chunk: float):
"""
Send synthesized audio to output with rate limiting
CRITICAL: Rate limiting enables interrupts to work
"""
chunk_idx = 0
async for chunk in synthesis_result.chunk_generator:
# Check for interrupt
if self.interrupt_event.is_set():
logger.info(f"🛑 [INTERRUPT] Stopped after {chunk_idx} chunks")
# Calculate what was actually spoken
seconds_spoken = chunk_idx * seconds_per_chunk
partial_message = synthesis_result.get_message_up_to(seconds_spoken)
logger.info(f"📝 [INTERRUPT] Partial message: '{partial_message}'")
# Clear interrupt event
self.interrupt_event.clear()
return
start_time = asyncio.get_event_loop().time()
# Send chunk to output device
await self.output_device.consume_nonblocking(chunk)
# CRITICAL: Wait for chunk to play before sending next one
# This is what makes interrupts work!
processing_time = asyncio.get_event_loop().time() - start_time
await asyncio.sleep(max(seconds_per_chunk - processing_time, 0))
chunk_idx += 1
def receive_audio(self, audio_chunk: bytes):
"""Receive audio from client"""
self.transcriber.send_audio(audio_chunk)
async def terminate(self):
"""Gracefully shut down all workers"""
logger.info("🛑 [CONVERSATION] Terminating...")
self.transcriber.terminate()
self.agent.terminate()
# Wait for queues to drain
await asyncio.sleep(0.5)
# ============================================================================
# WebSocket Endpoint
# ============================================================================
@app.websocket("/conversation")
async def conversation_endpoint(websocket: WebSocket):
"""WebSocket endpoint for voice conversations"""
await websocket.accept()
logger.info("✅ [WEBSOCKET] Client connected")
# Configuration
config = {
"transcriberProvider": "deepgram",
"llmProvider": "gemini",
"voiceProvider": "elevenlabs",
"prompt": "You are a helpful AI assistant.",
}
# Create components
transcriber = DeepgramTranscriber(config)
agent = GeminiAgent(config)
synthesizer = ElevenLabsSynthesizer(config)
output_device = WebsocketOutputDevice(websocket)
# Create conversation
conversation = StreamingConversation(
output_device=output_device,
transcriber=transcriber,
agent=agent,
synthesizer=synthesizer
)
# Start conversation
await conversation.start()
try:
# Process incoming audio
async for message in websocket.iter_bytes():
conversation.receive_audio(message)
except WebSocketDisconnect:
logger.info("❌ [WEBSOCKET] Client disconnected")
except Exception as e:
logger.error(f"❌ [WEBSOCKET] Error: {e}", exc_info=True)
finally:
await conversation.terminate()
# ============================================================================
# Main Entry Point
# ============================================================================
if __name__ == "__main__":
import uvicorn
logger.info("🚀 Starting Voice AI Engine...")
uvicorn.run(app, host="0.0.0.0", port=8000)

View File

@@ -0,0 +1,239 @@
"""
Example: Gemini Agent Implementation with Streaming
This example shows how to implement a Gemini-powered agent
that properly buffers responses to prevent audio jumping.
"""
import asyncio
from typing import AsyncGenerator, List, Dict
from dataclasses import dataclass
import logging
logger = logging.getLogger(__name__)
@dataclass
class Message:
role: str # "user" or "assistant"
content: str
@dataclass
class GeneratedResponse:
message: str
is_interruptible: bool = True
class GeminiAgent:
"""
LLM-powered conversational agent using Google Gemini
Key Features:
- Maintains conversation history
- Streams responses from Gemini API
- Buffers entire response before yielding (prevents audio jumping)
- Handles interrupts gracefully
"""
def __init__(self, config: Dict):
self.config = config
self.conversation_history: List[Message] = []
self.system_prompt = config.get("prompt", "You are a helpful AI assistant.")
self.current_task = None
async def generate_response(
self,
user_input: str,
is_interrupt: bool = False
) -> AsyncGenerator[GeneratedResponse, None]:
"""
Generate streaming response from Gemini
IMPORTANT: This buffers the entire LLM response before yielding
to prevent audio jumping/cutting off.
Args:
user_input: The user's message
is_interrupt: Whether this is an interrupt
Yields:
GeneratedResponse with complete buffered message
"""
# Add user message to history
self.conversation_history.append(
Message(role="user", content=user_input)
)
logger.info(f"🤖 [AGENT] Generating response for: '{user_input}'")
# Build conversation context for Gemini
contents = self._build_gemini_contents()
# Stream response from Gemini and buffer it
full_response = ""
try:
# In a real implementation, this would call Gemini API
# async for chunk in self._create_gemini_stream(contents):
# if isinstance(chunk, str):
# full_response += chunk
# For this example, simulate streaming
async for chunk in self._simulate_gemini_stream(user_input):
full_response += chunk
# Log progress (optional)
if len(full_response) % 50 == 0:
logger.debug(f"🤖 [AGENT] Buffered {len(full_response)} chars...")
except Exception as e:
logger.error(f"❌ [AGENT] Error generating response: {e}")
full_response = "I apologize, but I encountered an error. Could you please try again?"
# CRITICAL: Only yield after buffering the ENTIRE response
# This prevents multiple TTS calls that cause audio jumping
if full_response.strip():
# Add to conversation history
self.conversation_history.append(
Message(role="assistant", content=full_response)
)
logger.info(f"✅ [AGENT] Generated complete response ({len(full_response)} chars)")
yield GeneratedResponse(
message=full_response.strip(),
is_interruptible=True
)
def _build_gemini_contents(self) -> List[Dict]:
"""
Build conversation contents for Gemini API
Format:
[
{"role": "user", "parts": [{"text": "System: ..."}]},
{"role": "model", "parts": [{"text": "Understood."}]},
{"role": "user", "parts": [{"text": "Hello"}]},
{"role": "model", "parts": [{"text": "Hi there!"}]},
...
]
"""
contents = []
# Add system prompt as first user message
if self.system_prompt:
contents.append({
"role": "user",
"parts": [{"text": f"System Instruction: {self.system_prompt}"}]
})
contents.append({
"role": "model",
"parts": [{"text": "Understood."}]
})
# Add conversation history
for message in self.conversation_history:
role = "user" if message.role == "user" else "model"
contents.append({
"role": role,
"parts": [{"text": message.content}]
})
return contents
async def _simulate_gemini_stream(self, user_input: str) -> AsyncGenerator[str, None]:
"""
Simulate Gemini streaming response
In a real implementation, this would be:
async def _create_gemini_stream(self, contents):
response = await genai.GenerativeModel('gemini-pro').generate_content_async(
contents,
stream=True
)
async for chunk in response:
if chunk.text:
yield chunk.text
"""
# Simulate response
response = f"I understand you said: {user_input}. How can I assist you further?"
# Simulate streaming by yielding chunks
chunk_size = 10
for i in range(0, len(response), chunk_size):
chunk = response[i:i + chunk_size]
await asyncio.sleep(0.05) # Simulate network delay
yield chunk
def update_last_bot_message_on_cut_off(self, partial_message: str):
"""
Update conversation history when bot is interrupted
This ensures the conversation history reflects what was actually spoken,
not what was planned to be spoken.
Args:
partial_message: The partial message that was actually spoken
"""
if self.conversation_history and self.conversation_history[-1].role == "assistant":
# Update the last bot message with the partial message
self.conversation_history[-1].content = partial_message
logger.info(f"📝 [AGENT] Updated history with partial message: '{partial_message}'")
def cancel_current_task(self):
"""Cancel the current generation task (for interrupts)"""
if self.current_task and not self.current_task.done():
self.current_task.cancel()
logger.info("🛑 [AGENT] Cancelled current generation task")
def get_conversation_history(self) -> List[Message]:
"""Get the full conversation history"""
return self.conversation_history.copy()
def clear_conversation_history(self):
"""Clear the conversation history"""
self.conversation_history.clear()
logger.info("🗑️ [AGENT] Cleared conversation history")
# ============================================================================
# Example Usage
# ============================================================================
async def example_usage():
"""Example of how to use the GeminiAgent"""
# Configure agent
config = {
"prompt": "You are a helpful AI assistant specializing in voice conversations.",
"llmProvider": "gemini"
}
# Create agent
agent = GeminiAgent(config)
# Simulate conversation
user_messages = [
"Hello, how are you?",
"What's the weather like today?",
"Thank you!"
]
for user_message in user_messages:
print(f"\n👤 User: {user_message}")
# Generate response
async for response in agent.generate_response(user_message):
print(f"🤖 Bot: {response.message}")
# Print conversation history
print("\n📜 Conversation History:")
for i, message in enumerate(agent.get_conversation_history(), 1):
print(f"{i}. {message.role}: {message.content}")
if __name__ == "__main__":
asyncio.run(example_usage())

View File

@@ -0,0 +1,334 @@
"""
Example: Interrupt System Implementation
This example demonstrates how to implement a robust interrupt system
that allows users to interrupt the bot mid-sentence.
"""
import asyncio
import threading
from typing import Any
from dataclasses import dataclass
import logging
logger = logging.getLogger(__name__)
# ============================================================================
# InterruptibleEvent Pattern
# ============================================================================
class InterruptibleEvent:
"""
Wrapper for events that can be interrupted
Every event in the pipeline is wrapped in an InterruptibleEvent,
allowing the system to stop processing mid-stream.
"""
def __init__(self, payload: Any, is_interruptible: bool = True):
self.payload = payload
self.is_interruptible = is_interruptible
self.interruption_event = threading.Event() # Initially not set
self.interrupted = False
def interrupt(self) -> bool:
"""
Interrupt this event
Returns:
True if the event was interrupted, False if it was not interruptible
"""
if not self.is_interruptible:
return False
if not self.interrupted:
self.interruption_event.set() # Signal to stop!
self.interrupted = True
logger.info("⚠️ [INTERRUPT] Event interrupted")
return True
return False
def is_interrupted(self) -> bool:
"""Check if this event has been interrupted"""
return self.interruption_event.is_set()
# ============================================================================
# Conversation with Interrupt Support
# ============================================================================
class ConversationWithInterrupts:
"""
Conversation orchestrator with interrupt support
Key Features:
- Tracks all in-flight interruptible events
- Broadcasts interrupts to all workers
- Cancels current tasks
- Updates conversation history with partial messages
"""
def __init__(self):
self.is_human_speaking = True
self.interruptible_events = asyncio.Queue()
self.agent = None # Set externally
self.synthesizer_worker = None # Set externally
def broadcast_interrupt(self) -> bool:
"""
Broadcast interrupt to all in-flight events
This is called when the user starts speaking while the bot is speaking.
Returns:
True if any events were interrupted
"""
num_interrupts = 0
# Interrupt all queued events
while True:
try:
interruptible_event = self.interruptible_events.get_nowait()
if interruptible_event.interrupt():
num_interrupts += 1
except asyncio.QueueEmpty:
break
# Cancel current tasks
if self.agent:
self.agent.cancel_current_task()
if self.synthesizer_worker:
self.synthesizer_worker.cancel_current_task()
logger.info(f"⚠️ [INTERRUPT] Interrupted {num_interrupts} events")
return num_interrupts > 0
def add_interruptible_event(self, event: InterruptibleEvent):
"""Add an event to the interruptible queue"""
self.interruptible_events.put_nowait(event)
# ============================================================================
# Synthesis Worker with Interrupt Support
# ============================================================================
class SynthesisWorkerWithInterrupts:
"""
Synthesis worker that supports interrupts
Key Features:
- Checks for interrupts before sending each audio chunk
- Calculates partial message when interrupted
- Updates agent's conversation history with partial message
"""
def __init__(self, agent, output_device):
self.agent = agent
self.output_device = output_device
self.current_task = None
async def send_speech_to_output(
self,
message: str,
synthesis_result,
stop_event: threading.Event,
seconds_per_chunk: float = 0.1
) -> tuple[str, bool]:
"""
Send synthesized speech to output with interrupt support
Args:
message: The full message being synthesized
synthesis_result: SynthesisResult with chunk_generator and get_message_up_to
stop_event: Event that signals when to stop (interrupt)
seconds_per_chunk: Duration of each audio chunk in seconds
Returns:
Tuple of (message_sent, was_cut_off)
- message_sent: The actual message sent (partial if interrupted)
- was_cut_off: True if interrupted, False if completed
"""
chunk_idx = 0
async for chunk_result in synthesis_result.chunk_generator:
# CRITICAL: Check for interrupt before sending each chunk
if stop_event.is_set():
logger.info(f"🛑 [SYNTHESIZER] Interrupted after {chunk_idx} chunks")
# Calculate what was actually spoken
seconds_spoken = chunk_idx * seconds_per_chunk
partial_message = synthesis_result.get_message_up_to(seconds_spoken)
logger.info(f"📝 [SYNTHESIZER] Partial message: '{partial_message}'")
return partial_message, True # cut_off = True
start_time = asyncio.get_event_loop().time()
# Send chunk to output device
await self.output_device.consume_nonblocking(chunk_result.chunk)
# CRITICAL: Wait for chunk to play before sending next one
# This is what makes interrupts work!
processing_time = asyncio.get_event_loop().time() - start_time
await asyncio.sleep(max(seconds_per_chunk - processing_time, 0))
chunk_idx += 1
# Completed without interruption
logger.info(f"✅ [SYNTHESIZER] Completed {chunk_idx} chunks")
return message, False # cut_off = False
def cancel_current_task(self):
"""Cancel the current synthesis task"""
if self.current_task and not self.current_task.done():
self.current_task.cancel()
logger.info("🛑 [SYNTHESIZER] Cancelled current task")
# ============================================================================
# Transcription Worker with Interrupt Detection
# ============================================================================
class TranscriptionWorkerWithInterrupts:
"""
Transcription worker that detects interrupts
Key Features:
- Detects when user speaks while bot is speaking
- Marks transcription as interrupt
- Triggers broadcast_interrupt()
"""
def __init__(self, conversation):
self.conversation = conversation
async def process(self, transcription):
"""
Process transcription and detect interrupts
If the user starts speaking while the bot is speaking,
this is an interrupt.
"""
# Check if this is an interrupt
if not self.conversation.is_human_speaking:
logger.info("⚠️ [TRANSCRIPTION] User interrupted bot!")
# Broadcast interrupt to all in-flight events
interrupted = self.conversation.broadcast_interrupt()
transcription.is_interrupt = interrupted
# Update speaking state
self.conversation.is_human_speaking = True
# Continue processing transcription...
logger.info(f"🎤 [TRANSCRIPTION] Received: '{transcription.message}'")
# ============================================================================
# Example Usage
# ============================================================================
@dataclass
class MockTranscription:
message: str
is_interrupt: bool = False
@dataclass
class MockSynthesisResult:
async def chunk_generator(self):
"""Generate mock audio chunks"""
for i in range(10):
await asyncio.sleep(0.1)
yield type('obj', (object,), {'chunk': b'\x00' * 1024})()
def get_message_up_to(self, seconds: float) -> str:
"""Get partial message up to specified seconds"""
full_message = "I think the weather will be nice today and tomorrow and the day after."
chars_per_second = len(full_message) / 1.0 # Assume 1 second total
char_index = int(seconds * chars_per_second)
return full_message[:char_index]
async def example_interrupt_scenario():
"""
Example scenario: User interrupts bot mid-sentence
"""
print("🎬 Scenario: User interrupts bot mid-sentence\n")
# Create conversation
conversation = ConversationWithInterrupts()
# Create mock components
class MockAgent:
def cancel_current_task(self):
print("🛑 [AGENT] Task cancelled")
def update_last_bot_message_on_cut_off(self, partial_message):
print(f"📝 [AGENT] Updated history: '{partial_message}'")
class MockOutputDevice:
async def consume_nonblocking(self, chunk):
pass
agent = MockAgent()
output_device = MockOutputDevice()
conversation.agent = agent
# Create synthesis worker
synthesis_worker = SynthesisWorkerWithInterrupts(agent, output_device)
conversation.synthesizer_worker = synthesis_worker
# Create interruptible event
stop_event = threading.Event()
interruptible_event = InterruptibleEvent(
payload="Bot is speaking...",
is_interruptible=True
)
conversation.add_interruptible_event(interruptible_event)
# Start bot speaking
print("🤖 Bot starts speaking: 'I think the weather will be nice today and tomorrow and the day after.'\n")
conversation.is_human_speaking = False
# Simulate synthesis in background
synthesis_result = MockSynthesisResult()
synthesis_task = asyncio.create_task(
synthesis_worker.send_speech_to_output(
message="I think the weather will be nice today and tomorrow and the day after.",
synthesis_result=synthesis_result,
stop_event=stop_event,
seconds_per_chunk=0.1
)
)
# Wait a bit, then interrupt
await asyncio.sleep(0.3)
print("👤 User interrupts: 'Stop!'\n")
# Trigger interrupt
conversation.broadcast_interrupt()
stop_event.set()
# Wait for synthesis to finish
message_sent, was_cut_off = await synthesis_task
print(f"\n✅ Result:")
print(f" - Message sent: '{message_sent}'")
print(f" - Was cut off: {was_cut_off}")
# Update agent history
if was_cut_off:
agent.update_last_bot_message_on_cut_off(message_sent)
if __name__ == "__main__":
asyncio.run(example_interrupt_scenario())

View File

@@ -0,0 +1,471 @@
# Common Pitfalls and Solutions
This document covers common issues encountered when building voice AI engines and their solutions.
## 1. Audio Jumping/Cutting Off
### Problem
The bot's audio jumps or cuts off mid-response, creating a jarring user experience.
### Symptoms
- Audio plays in fragments
- Sentences are incomplete
- Multiple audio streams overlap
- Unnatural pauses or gaps
### Root Cause
Sending text to the synthesizer in small chunks (sentence-by-sentence or word-by-word) causes multiple TTS API calls. Each call generates a separate audio stream, resulting in:
- Multiple audio files being played sequentially
- Timing issues between chunks
- Potential overlapping audio
- Inconsistent voice characteristics between chunks
### Solution
Buffer the entire LLM response before sending it to the synthesizer:
**❌ Bad: Yields sentence-by-sentence**
```python
async def generate_response(self, prompt):
async for sentence in llm_stream:
# This creates multiple TTS calls!
yield GeneratedResponse(message=BaseMessage(text=sentence))
```
**✅ Good: Buffer entire response**
```python
async def generate_response(self, prompt):
# Buffer the entire response
full_response = ""
async for chunk in llm_stream:
full_response += chunk
# Yield once with complete response
yield GeneratedResponse(message=BaseMessage(text=full_response))
```
### Why This Works
- Single TTS call for the entire response
- Consistent voice characteristics
- Proper timing and pacing
- No gaps or overlaps
---
## 2. Echo/Feedback Loop
### Problem
The bot hears itself speaking and responds to its own audio, creating an infinite loop.
### Symptoms
- Bot responds to its own speech
- Conversation becomes nonsensical
- Transcriptions include bot's own words
- System becomes unresponsive
### Root Cause
The transcriber continues to process audio while the bot is speaking. If the bot's audio is being played through speakers and captured by the microphone, the transcriber will transcribe the bot's own speech.
### Solution
Mute the transcriber when the bot starts speaking:
```python
# Before sending audio to output
self.transcriber.mute()
# Send audio...
await self.send_speech_to_output(synthesis_result)
# After audio playback complete
self.transcriber.unmute()
```
### Implementation in Transcriber
```python
class BaseTranscriber:
def __init__(self):
self.is_muted = False
def send_audio(self, chunk: bytes):
"""Client calls this to send audio"""
if not self.is_muted:
self.input_queue.put_nowait(chunk)
else:
# Send silence instead (prevents echo)
self.input_queue.put_nowait(self.create_silent_chunk(len(chunk)))
def mute(self):
"""Called when bot starts speaking"""
self.is_muted = True
def unmute(self):
"""Called when bot stops speaking"""
self.is_muted = False
def create_silent_chunk(self, size: int) -> bytes:
"""Create a silent audio chunk"""
return b'\x00' * size
```
### Why This Works
- Transcriber receives silence while bot speaks
- No transcription of bot's own speech
- Prevents feedback loop
- Maintains audio stream continuity
---
## 3. Interrupts Not Working
### Problem
Users cannot interrupt the bot mid-sentence. The bot continues speaking even when the user starts talking.
### Symptoms
- Bot speaks over user
- User must wait for bot to finish
- Unnatural conversation flow
- Poor user experience
### Root Cause
All audio chunks are sent to the client immediately, buffering the entire message on the client side. By the time an interrupt is detected, all audio has already been sent and is queued for playback.
### Solution
Rate-limit audio chunks to match real-time playback:
**❌ Bad: Send all chunks immediately**
```python
async for chunk in synthesis_result.chunk_generator:
# Sends all chunks as fast as possible
output_device.consume_nonblocking(chunk)
```
**✅ Good: Rate-limit chunks**
```python
async for chunk in synthesis_result.chunk_generator:
# Check for interrupt
if stop_event.is_set():
# Calculate partial message
partial_message = synthesis_result.get_message_up_to(
chunk_idx * seconds_per_chunk
)
return partial_message, True # cut_off = True
start_time = time.time()
# Send chunk
output_device.consume_nonblocking(chunk)
# CRITICAL: Wait for chunk duration before sending next
processing_time = time.time() - start_time
await asyncio.sleep(max(seconds_per_chunk - processing_time, 0))
chunk_idx += 1
```
### Why This Works
- Only one chunk is buffered on client at a time
- Interrupts can stop mid-sentence
- Natural conversation flow
- Real-time playback maintained
### Calculating `seconds_per_chunk`
```python
# For LINEAR16 PCM audio at 16kHz
sample_rate = 16000 # Hz
chunk_size = 1024 # bytes
bytes_per_sample = 2 # 16-bit = 2 bytes
samples_per_chunk = chunk_size / bytes_per_sample
seconds_per_chunk = samples_per_chunk / sample_rate
# = 1024 / 2 / 16000 = 0.032 seconds
```
---
## 4. Memory Leaks from Unclosed Streams
### Problem
Memory usage grows over time, eventually causing the application to crash.
### Symptoms
- Increasing memory usage
- Slow performance over time
- WebSocket connections not closing
- Resource exhaustion
### Root Cause
WebSocket connections, API streams, or async tasks are not properly closed when conversations end or errors occur.
### Solution
Always use context managers and cleanup:
**❌ Bad: No cleanup**
```python
async def handle_conversation(websocket):
conversation = create_conversation()
await conversation.start()
async for message in websocket.iter_bytes():
conversation.receive_audio(message)
# No cleanup! Resources leak
```
**✅ Good: Proper cleanup**
```python
async def handle_conversation(websocket):
conversation = None
try:
conversation = create_conversation()
await conversation.start()
async for message in websocket.iter_bytes():
conversation.receive_audio(message)
except WebSocketDisconnect:
logger.info("Client disconnected")
except Exception as e:
logger.error(f"Error: {e}", exc_info=True)
finally:
# Always cleanup
if conversation:
await conversation.terminate()
```
### Proper Termination
```python
async def terminate(self):
"""Gracefully shut down all workers"""
self.active = False
# Stop all workers
self.transcriber.terminate()
self.agent.terminate()
self.synthesizer.terminate()
# Wait for queues to drain
await asyncio.sleep(0.5)
# Close connections
if self.websocket:
await self.websocket.close()
# Cancel tasks
for task in self.tasks:
if not task.done():
task.cancel()
```
---
## 5. Conversation History Not Updating
### Problem
The agent doesn't remember previous messages or context is lost.
### Symptoms
- Agent repeats itself
- No context from previous messages
- Each response is independent
- Poor conversation quality
### Root Cause
Conversation history is not being maintained or updated correctly.
### Solution
Maintain conversation history in the agent:
```python
class Agent:
def __init__(self):
self.conversation_history = []
async def generate_response(self, user_input):
# Add user message to history
self.conversation_history.append({
"role": "user",
"content": user_input
})
# Generate response with full history
response = await self.llm.generate(self.conversation_history)
# Add bot response to history
self.conversation_history.append({
"role": "assistant",
"content": response
})
return response
```
### Handling Interrupts
When the bot is interrupted, update history with partial message:
```python
def update_last_bot_message_on_cut_off(self, partial_message):
"""Update history when bot is interrupted"""
if self.conversation_history and \
self.conversation_history[-1]["role"] == "assistant":
# Update with what was actually spoken
self.conversation_history[-1]["content"] = partial_message
```
---
## 6. WebSocket Connection Drops
### Problem
WebSocket connections drop unexpectedly, interrupting conversations.
### Symptoms
- Frequent disconnections
- Connection timeouts
- "Connection closed" errors
- Unstable conversations
### Root Cause
- No heartbeat/ping mechanism
- Idle timeout
- Network issues
- Server overload
### Solution
Implement heartbeat and reconnection:
```python
@app.websocket("/conversation")
async def conversation_endpoint(websocket: WebSocket):
await websocket.accept()
# Start heartbeat
async def heartbeat():
while True:
try:
await websocket.send_json({"type": "ping"})
await asyncio.sleep(30) # Ping every 30 seconds
except:
break
heartbeat_task = asyncio.create_task(heartbeat())
try:
async for message in websocket.iter_bytes():
# Process message
pass
finally:
heartbeat_task.cancel()
```
---
## 7. High Latency / Slow Responses
### Problem
Long delays between user speech and bot response.
### Symptoms
- Noticeable lag
- Poor user experience
- Conversation feels unnatural
- Users repeat themselves
### Root Causes & Solutions
**1. Not using streaming**
```python
# ❌ Bad: Wait for entire response
response = await llm.complete(prompt)
# ✅ Good: Stream response
async for chunk in llm.complete(prompt, stream=True):
yield chunk
```
**2. Sequential processing**
```python
# ❌ Bad: Sequential
transcription = await transcriber.transcribe(audio)
response = await agent.generate(transcription)
audio = await synthesizer.synthesize(response)
# ✅ Good: Concurrent with queues
# All workers run simultaneously
```
**3. Large chunk sizes**
```python
# ❌ Bad: Large chunks (high latency)
chunk_size = 8192 # 0.25 seconds
# ✅ Good: Small chunks (low latency)
chunk_size = 1024 # 0.032 seconds
```
---
## 8. Audio Quality Issues
### Problem
Poor audio quality, distortion, or artifacts.
### Symptoms
- Robotic voice
- Crackling or popping
- Distorted audio
- Inconsistent volume
### Root Causes & Solutions
**1. Wrong audio format**
```python
# ✅ Use LINEAR16 PCM at 16kHz
audio_encoding = AudioEncoding.LINEAR16
sample_rate = 16000
```
**2. Incorrect format conversion**
```python
# ✅ Proper MP3 to PCM conversion
from pydub import AudioSegment
import io
def mp3_to_pcm(mp3_bytes):
audio = AudioSegment.from_mp3(io.BytesIO(mp3_bytes))
audio = audio.set_frame_rate(16000)
audio = audio.set_channels(1)
audio = audio.set_sample_width(2) # 16-bit
return audio.raw_data
```
**3. Buffer underruns**
```python
# ✅ Ensure consistent chunk timing
await asyncio.sleep(max(seconds_per_chunk - processing_time, 0))
```
---
## Summary
| Problem | Root Cause | Solution |
|---------|-----------|----------|
| Audio jumping | Multiple TTS calls | Buffer entire response |
| Echo/feedback | Transcriber active during bot speech | Mute transcriber |
| Interrupts not working | All chunks sent immediately | Rate-limit chunks |
| Memory leaks | Unclosed streams | Proper cleanup |
| Lost context | History not maintained | Update conversation history |
| Connection drops | No heartbeat | Implement ping/pong |
| High latency | Sequential processing | Use streaming + queues |
| Poor audio quality | Wrong format/conversion | Use LINEAR16 PCM 16kHz |
---
## Best Practices
1. **Always buffer LLM responses** before sending to synthesizer
2. **Always mute transcriber** when bot is speaking
3. **Always rate-limit audio chunks** to enable interrupts
4. **Always cleanup resources** in finally blocks
5. **Always maintain conversation history** for context
6. **Always use streaming** for low latency
7. **Always use LINEAR16 PCM** at 16kHz for audio
8. **Always implement error handling** in worker loops

View File

@@ -0,0 +1,515 @@
# Provider Comparison Guide
This guide compares different providers for transcription, LLM, and TTS services to help you choose the best option for your voice AI engine.
## Transcription Providers
### Deepgram
**Strengths:**
- ✅ Fastest transcription speed (< 300ms latency)
- ✅ Excellent streaming support
- ✅ High accuracy (95%+ on clear audio)
- ✅ Good pricing ($0.0043/minute)
- ✅ Nova-2 model optimized for real-time
- ✅ Excellent documentation
**Weaknesses:**
- ❌ Less accurate with heavy accents
- ❌ Smaller company (potential reliability concerns)
**Best For:**
- Real-time voice conversations
- Low-latency applications
- English-language applications
- Startups and small businesses
**Configuration:**
```python
{
"transcriberProvider": "deepgram",
"deepgramApiKey": "your-api-key",
"deepgramModel": "nova-2",
"language": "en-US"
}
```
---
### AssemblyAI
**Strengths:**
- ✅ Very high accuracy (96%+ on clear audio)
- ✅ Excellent with accents and dialects
- ✅ Good speaker diarization
- ✅ Competitive pricing ($0.00025/second)
- ✅ Strong customer support
**Weaknesses:**
- ❌ Slightly higher latency than Deepgram
- ❌ Streaming support is newer
**Best For:**
- Applications requiring highest accuracy
- Multi-speaker scenarios
- Diverse user base with accents
- Enterprise applications
**Configuration:**
```python
{
"transcriberProvider": "assemblyai",
"assemblyaiApiKey": "your-api-key",
"language": "en"
}
```
---
### Azure Speech
**Strengths:**
- ✅ Enterprise-grade reliability
- ✅ Excellent multi-language support (100+ languages)
- ✅ Strong security and compliance
- ✅ Integration with Azure ecosystem
- ✅ Custom model training available
**Weaknesses:**
- ❌ Higher cost ($1/hour)
- ❌ More complex setup
- ❌ Slower than specialized providers
**Best For:**
- Enterprise applications
- Multi-language requirements
- Azure-based infrastructure
- Compliance-sensitive applications
**Configuration:**
```python
{
"transcriberProvider": "azure",
"azureSpeechKey": "your-key",
"azureSpeechRegion": "eastus",
"language": "en-US"
}
```
---
### Google Cloud Speech
**Strengths:**
- ✅ Excellent multi-language support (125+ languages)
- ✅ Good accuracy
- ✅ Integration with Google Cloud
- ✅ Automatic punctuation
- ✅ Speaker diarization
**Weaknesses:**
- ❌ Higher latency for streaming
- ❌ Complex pricing model
- ❌ Requires Google Cloud account
**Best For:**
- Multi-language applications
- Google Cloud infrastructure
- Applications needing speaker diarization
**Configuration:**
```python
{
"transcriberProvider": "google",
"googleCredentials": "path/to/credentials.json",
"language": "en-US"
}
```
---
## LLM Providers
### OpenAI (GPT-4, GPT-3.5)
**Strengths:**
- ✅ Highest quality responses
- ✅ Excellent instruction following
- ✅ Fast streaming
- ✅ Large context window (128k for GPT-4)
- ✅ Best-in-class reasoning
**Weaknesses:**
- ❌ Higher cost ($0.01-0.03/1k tokens)
- ❌ Rate limits can be restrictive
- ❌ No free tier
**Best For:**
- High-quality conversational AI
- Complex reasoning tasks
- Production applications
- Enterprise use cases
**Configuration:**
```python
{
"llmProvider": "openai",
"openaiApiKey": "your-api-key",
"openaiModel": "gpt-4-turbo",
"prompt": "You are a helpful AI assistant."
}
```
**Pricing:**
- GPT-4 Turbo: $0.01/1k input tokens, $0.03/1k output tokens
- GPT-3.5 Turbo: $0.0005/1k input tokens, $0.0015/1k output tokens
---
### Google Gemini
**Strengths:**
- ✅ Excellent cost-effectiveness (free tier available)
- ✅ Multimodal capabilities
- ✅ Good streaming support
- ✅ Large context window (1M tokens for Pro)
- ✅ Fast response times
**Weaknesses:**
- ❌ Slightly lower quality than GPT-4
- ❌ Less predictable behavior
- ❌ Newer, less battle-tested
**Best For:**
- Cost-sensitive applications
- Multimodal applications
- Startups and prototypes
- High-volume applications
**Configuration:**
```python
{
"llmProvider": "gemini",
"geminiApiKey": "your-api-key",
"geminiModel": "gemini-pro",
"prompt": "You are a helpful AI assistant."
}
```
**Pricing:**
- Gemini Pro: Free up to 60 requests/minute
- Gemini Pro (paid): $0.00025/1k input tokens, $0.0005/1k output tokens
---
### Anthropic Claude
**Strengths:**
- ✅ Excellent safety and alignment
- ✅ Very long context window (200k tokens)
- ✅ High-quality responses
- ✅ Good at following complex instructions
- ✅ Strong reasoning capabilities
**Weaknesses:**
- ❌ Higher cost than Gemini
- ❌ Slower streaming than OpenAI
- ❌ More conservative responses
**Best For:**
- Safety-critical applications
- Long-context applications
- Nuanced conversations
- Enterprise applications
**Configuration:**
```python
{
"llmProvider": "claude",
"claudeApiKey": "your-api-key",
"claudeModel": "claude-3-opus",
"prompt": "You are a helpful AI assistant."
}
```
**Pricing:**
- Claude 3 Opus: $0.015/1k input tokens, $0.075/1k output tokens
- Claude 3 Sonnet: $0.003/1k input tokens, $0.015/1k output tokens
---
## TTS Providers
### ElevenLabs
**Strengths:**
- ✅ Most natural-sounding voices
- ✅ Excellent emotional range
- ✅ Voice cloning capabilities
- ✅ Good streaming support
- ✅ Multiple languages
**Weaknesses:**
- ❌ Higher cost ($0.30/1k characters)
- ❌ Rate limits on lower tiers
- ❌ Occasional pronunciation errors
**Best For:**
- Premium voice experiences
- Customer-facing applications
- Voice cloning needs
- High-quality audio requirements
**Configuration:**
```python
{
"voiceProvider": "elevenlabs",
"elevenlabsApiKey": "your-api-key",
"elevenlabsVoiceId": "voice-id",
"elevenlabsModel": "eleven_monolingual_v1"
}
```
**Pricing:**
- Free: 10k characters/month
- Starter: $5/month, 30k characters
- Creator: $22/month, 100k characters
---
### Azure TTS
**Strengths:**
- ✅ Enterprise-grade reliability
- ✅ Many languages (100+)
- ✅ Neural voices available
- ✅ SSML support for fine control
- ✅ Good pricing ($4/1M characters)
**Weaknesses:**
- ❌ Less natural than ElevenLabs
- ❌ More complex setup
- ❌ Requires Azure account
**Best For:**
- Enterprise applications
- Multi-language requirements
- Azure-based infrastructure
- Cost-sensitive high-volume applications
**Configuration:**
```python
{
"voiceProvider": "azure",
"azureSpeechKey": "your-key",
"azureSpeechRegion": "eastus",
"azureVoiceName": "en-US-JennyNeural"
}
```
**Pricing:**
- Neural voices: $16/1M characters
- Standard voices: $4/1M characters
---
### Google Cloud TTS
**Strengths:**
- ✅ Good quality neural voices
- ✅ Many languages (40+)
- ✅ WaveNet voices available
- ✅ Competitive pricing ($4/1M characters)
- ✅ SSML support
**Weaknesses:**
- ❌ Less natural than ElevenLabs
- ❌ Requires Google Cloud account
- ❌ Complex setup
**Best For:**
- Multi-language applications
- Google Cloud infrastructure
- Cost-effective neural voices
**Configuration:**
```python
{
"voiceProvider": "google",
"googleCredentials": "path/to/credentials.json",
"googleVoiceName": "en-US-Neural2-F"
}
```
**Pricing:**
- WaveNet voices: $16/1M characters
- Neural2 voices: $16/1M characters
- Standard voices: $4/1M characters
---
### Amazon Polly
**Strengths:**
- ✅ AWS integration
- ✅ Good pricing ($4/1M characters)
- ✅ Neural voices available
- ✅ SSML support
- ✅ Reliable service
**Weaknesses:**
- ❌ Less natural than ElevenLabs
- ❌ Fewer voice options
- ❌ Requires AWS account
**Best For:**
- AWS-based infrastructure
- Cost-effective neural voices
- Enterprise applications
**Configuration:**
```python
{
"voiceProvider": "polly",
"awsAccessKey": "your-access-key",
"awsSecretKey": "your-secret-key",
"awsRegion": "us-east-1",
"pollyVoiceId": "Joanna"
}
```
**Pricing:**
- Neural voices: $16/1M characters
- Standard voices: $4/1M characters
---
### Play.ht
**Strengths:**
- ✅ Voice cloning capabilities
- ✅ Natural-sounding voices
- ✅ Good streaming support
- ✅ Easy to use API
- ✅ Multiple languages
**Weaknesses:**
- ❌ Higher cost than cloud providers
- ❌ Smaller company
- ❌ Less documentation
**Best For:**
- Voice cloning applications
- Premium voice experiences
- Startups and small businesses
**Configuration:**
```python
{
"voiceProvider": "playht",
"playhtApiKey": "your-api-key",
"playhtUserId": "your-user-id",
"playhtVoiceId": "voice-id"
}
```
**Pricing:**
- Free: 2.5k characters
- Creator: $31/month, 50k characters
- Pro: $79/month, 150k characters
---
## Recommended Combinations
### Budget-Conscious Startup
```python
{
"transcriberProvider": "deepgram", # Fast and affordable
"llmProvider": "gemini", # Free tier available
"voiceProvider": "google" # Cost-effective neural voices
}
```
**Estimated cost:** ~$0.01 per minute of conversation
---
### Premium Experience
```python
{
"transcriberProvider": "assemblyai", # Highest accuracy
"llmProvider": "openai", # Best quality responses
"voiceProvider": "elevenlabs" # Most natural voices
}
```
**Estimated cost:** ~$0.05 per minute of conversation
---
### Enterprise Application
```python
{
"transcriberProvider": "azure", # Enterprise reliability
"llmProvider": "openai", # Best quality
"voiceProvider": "azure" # Enterprise reliability
}
```
**Estimated cost:** ~$0.03 per minute of conversation
---
### Multi-Language Application
```python
{
"transcriberProvider": "google", # 125+ languages
"llmProvider": "gemini", # Good multi-language support
"voiceProvider": "google" # 40+ languages
}
```
**Estimated cost:** ~$0.02 per minute of conversation
---
## Decision Matrix
| Priority | Transcriber | LLM | TTS |
|----------|-------------|-----|-----|
| **Lowest Cost** | Deepgram | Gemini | Google |
| **Highest Quality** | AssemblyAI | OpenAI | ElevenLabs |
| **Fastest Speed** | Deepgram | OpenAI | ElevenLabs |
| **Enterprise** | Azure | OpenAI | Azure |
| **Multi-Language** | Google | Gemini | Google |
| **Voice Cloning** | N/A | N/A | ElevenLabs/Play.ht |
---
## Testing Recommendations
Before committing to providers, test with your specific use case:
1. **Create test conversations** with representative audio
2. **Measure latency** end-to-end
3. **Evaluate quality** with real users
4. **Calculate costs** based on expected volume
5. **Test edge cases** (accents, background noise, interrupts)
---
## Switching Providers
The multi-provider factory pattern makes switching easy:
```python
# Just change the configuration
config = {
"transcriberProvider": "deepgram", # Change to "assemblyai"
"llmProvider": "gemini", # Change to "openai"
"voiceProvider": "google" # Change to "elevenlabs"
}
# No code changes needed!
factory = VoiceComponentFactory()
transcriber = factory.create_transcriber(config)
agent = factory.create_agent(config)
synthesizer = factory.create_synthesizer(config)
```

View File

@@ -0,0 +1,193 @@
"""
Template: Base Worker Implementation
Use this template as a starting point for creating new workers
in your voice AI pipeline.
"""
import asyncio
from typing import Any
import logging
logger = logging.getLogger(__name__)
class BaseWorker:
"""
Base class for all workers in the voice AI pipeline
Workers follow the producer-consumer pattern:
- Consume items from input_queue
- Process items
- Produce results to output_queue
All workers run concurrently via asyncio.
"""
def __init__(self, input_queue: asyncio.Queue, output_queue: asyncio.Queue):
"""
Initialize the worker
Args:
input_queue: Queue to consume items from
output_queue: Queue to produce results to
"""
self.input_queue = input_queue
self.output_queue = output_queue
self.active = False
self._task = None
def start(self):
"""Start the worker's processing loop"""
self.active = True
self._task = asyncio.create_task(self._run_loop())
logger.info(f"✅ [{self.__class__.__name__}] Started")
async def _run_loop(self):
"""
Main processing loop - runs forever until terminated
This loop:
1. Waits for items from input_queue
2. Processes each item
3. Handles errors gracefully
"""
while self.active:
try:
# Block until item arrives
item = await self.input_queue.get()
# Process the item
await self.process(item)
except asyncio.CancelledError:
# Task was cancelled (normal during shutdown)
logger.info(f"🛑 [{self.__class__.__name__}] Task cancelled")
break
except Exception as e:
# Log error but don't crash the worker
logger.error(
f"❌ [{self.__class__.__name__}] Error processing item: {e}",
exc_info=True
)
# Continue processing next item
async def process(self, item: Any):
"""
Process a single item
Override this method in your worker implementation.
Args:
item: The item to process
"""
raise NotImplementedError(
f"{self.__class__.__name__} must implement process()"
)
def terminate(self):
"""
Stop the worker gracefully
This sets active=False and cancels the processing task.
"""
self.active = False
if self._task and not self._task.done():
self._task.cancel()
logger.info(f"🛑 [{self.__class__.__name__}] Terminated")
async def wait_for_completion(self):
"""Wait for the worker task to complete"""
if self._task:
try:
await self._task
except asyncio.CancelledError:
pass
# ============================================================================
# Example: Custom Worker Implementation
# ============================================================================
class ExampleWorker(BaseWorker):
"""
Example worker that demonstrates how to extend BaseWorker
This worker receives strings, converts them to uppercase,
and sends them to the output queue.
"""
def __init__(self, input_queue: asyncio.Queue, output_queue: asyncio.Queue):
super().__init__(input_queue, output_queue)
# Add any custom initialization here
self.processed_count = 0
async def process(self, item: str):
"""
Process a single item
Args:
item: String to convert to uppercase
"""
# Simulate some processing time
await asyncio.sleep(0.1)
# Process the item
result = item.upper()
# Send to output queue
self.output_queue.put_nowait(result)
# Update counter
self.processed_count += 1
logger.info(
f"✅ [{self.__class__.__name__}] "
f"Processed '{item}' -> '{result}' "
f"(total: {self.processed_count})"
)
# ============================================================================
# Example Usage
# ============================================================================
async def example_usage():
"""Example of how to use the worker"""
# Create queues
input_queue = asyncio.Queue()
output_queue = asyncio.Queue()
# Create worker
worker = ExampleWorker(input_queue, output_queue)
# Start worker
worker.start()
# Send items to process
items = ["hello", "world", "voice", "ai"]
for item in items:
input_queue.put_nowait(item)
# Wait for processing
await asyncio.sleep(0.5)
# Get results
results = []
while not output_queue.empty():
results.append(await output_queue.get())
print(f"\n✅ Results: {results}")
# Terminate worker
worker.terminate()
await worker.wait_for_completion()
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
asyncio.run(example_usage())

View File

@@ -0,0 +1,289 @@
"""
Template: Multi-Provider Factory
Use this template to create a factory that supports multiple providers
for transcription, LLM, and TTS services.
"""
from typing import Dict, Any
from abc import ABC, abstractmethod
import logging
logger = logging.getLogger(__name__)
# ============================================================================
# Provider Interfaces
# ============================================================================
class TranscriberProvider(ABC):
"""Abstract base class for transcriber providers"""
@abstractmethod
async def transcribe_stream(self, audio_stream):
"""Transcribe streaming audio"""
pass
class LLMProvider(ABC):
"""Abstract base class for LLM providers"""
@abstractmethod
async def generate_response(self, messages, stream=True):
"""Generate response from messages"""
pass
class TTSProvider(ABC):
"""Abstract base class for TTS providers"""
@abstractmethod
async def synthesize_speech(self, text):
"""Synthesize speech from text"""
pass
# ============================================================================
# Multi-Provider Factory
# ============================================================================
class VoiceComponentFactory:
"""
Factory for creating voice AI components with multiple provider support
Supports:
- Multiple transcription providers (Deepgram, AssemblyAI, Azure, Google)
- Multiple LLM providers (OpenAI, Gemini, Claude)
- Multiple TTS providers (ElevenLabs, Azure, Google, Polly, Play.ht)
"""
def __init__(self):
self.transcriber_providers = {
"deepgram": self._create_deepgram_transcriber,
"assemblyai": self._create_assemblyai_transcriber,
"azure": self._create_azure_transcriber,
"google": self._create_google_transcriber,
}
self.llm_providers = {
"openai": self._create_openai_agent,
"gemini": self._create_gemini_agent,
"claude": self._create_claude_agent,
}
self.tts_providers = {
"elevenlabs": self._create_elevenlabs_synthesizer,
"azure": self._create_azure_synthesizer,
"google": self._create_google_synthesizer,
"polly": self._create_polly_synthesizer,
"playht": self._create_playht_synthesizer,
}
def create_transcriber(self, config: Dict[str, Any]):
"""
Create transcriber based on configuration
Args:
config: Configuration dict with 'transcriberProvider' key
Returns:
Transcriber instance
Raises:
ValueError: If provider is not supported
"""
provider = config.get("transcriberProvider", "deepgram").lower()
if provider not in self.transcriber_providers:
raise ValueError(
f"Unknown transcriber provider: {provider}. "
f"Supported: {list(self.transcriber_providers.keys())}"
)
logger.info(f"🎤 Creating transcriber: {provider}")
return self.transcriber_providers[provider](config)
def create_agent(self, config: Dict[str, Any]):
"""
Create LLM agent based on configuration
Args:
config: Configuration dict with 'llmProvider' key
Returns:
Agent instance
Raises:
ValueError: If provider is not supported
"""
provider = config.get("llmProvider", "openai").lower()
if provider not in self.llm_providers:
raise ValueError(
f"Unknown LLM provider: {provider}. "
f"Supported: {list(self.llm_providers.keys())}"
)
logger.info(f"🤖 Creating agent: {provider}")
return self.llm_providers[provider](config)
def create_synthesizer(self, config: Dict[str, Any]):
"""
Create TTS synthesizer based on configuration
Args:
config: Configuration dict with 'voiceProvider' key
Returns:
Synthesizer instance
Raises:
ValueError: If provider is not supported
"""
provider = config.get("voiceProvider", "elevenlabs").lower()
if provider not in self.tts_providers:
raise ValueError(
f"Unknown voice provider: {provider}. "
f"Supported: {list(self.tts_providers.keys())}"
)
logger.info(f"🔊 Creating synthesizer: {provider}")
return self.tts_providers[provider](config)
# ========================================================================
# Transcriber Implementations
# ========================================================================
def _create_deepgram_transcriber(self, config: Dict[str, Any]):
"""Create Deepgram transcriber"""
# TODO: Implement Deepgram transcriber
# from .transcribers.deepgram import DeepgramTranscriber
# return DeepgramTranscriber(
# api_key=config.get("deepgramApiKey"),
# model=config.get("deepgramModel", "nova-2"),
# language=config.get("language", "en-US")
# )
raise NotImplementedError("Deepgram transcriber not implemented")
def _create_assemblyai_transcriber(self, config: Dict[str, Any]):
"""Create AssemblyAI transcriber"""
# TODO: Implement AssemblyAI transcriber
raise NotImplementedError("AssemblyAI transcriber not implemented")
def _create_azure_transcriber(self, config: Dict[str, Any]):
"""Create Azure Speech transcriber"""
# TODO: Implement Azure transcriber
raise NotImplementedError("Azure transcriber not implemented")
def _create_google_transcriber(self, config: Dict[str, Any]):
"""Create Google Cloud Speech transcriber"""
# TODO: Implement Google transcriber
raise NotImplementedError("Google transcriber not implemented")
# ========================================================================
# LLM Agent Implementations
# ========================================================================
def _create_openai_agent(self, config: Dict[str, Any]):
"""Create OpenAI agent"""
# TODO: Implement OpenAI agent
# from .agents.openai import OpenAIAgent
# return OpenAIAgent(
# api_key=config.get("openaiApiKey"),
# model=config.get("openaiModel", "gpt-4"),
# system_prompt=config.get("prompt", "You are a helpful assistant.")
# )
raise NotImplementedError("OpenAI agent not implemented")
def _create_gemini_agent(self, config: Dict[str, Any]):
"""Create Google Gemini agent"""
# TODO: Implement Gemini agent
# from .agents.gemini import GeminiAgent
# return GeminiAgent(
# api_key=config.get("geminiApiKey"),
# model=config.get("geminiModel", "gemini-pro"),
# system_prompt=config.get("prompt", "You are a helpful assistant.")
# )
raise NotImplementedError("Gemini agent not implemented")
def _create_claude_agent(self, config: Dict[str, Any]):
"""Create Anthropic Claude agent"""
# TODO: Implement Claude agent
raise NotImplementedError("Claude agent not implemented")
# ========================================================================
# TTS Synthesizer Implementations
# ========================================================================
def _create_elevenlabs_synthesizer(self, config: Dict[str, Any]):
"""Create ElevenLabs synthesizer"""
# TODO: Implement ElevenLabs synthesizer
# from .synthesizers.elevenlabs import ElevenLabsSynthesizer
# return ElevenLabsSynthesizer(
# api_key=config.get("elevenlabsApiKey"),
# voice_id=config.get("elevenlabsVoiceId"),
# model_id=config.get("elevenlabsModel", "eleven_monolingual_v1")
# )
raise NotImplementedError("ElevenLabs synthesizer not implemented")
def _create_azure_synthesizer(self, config: Dict[str, Any]):
"""Create Azure TTS synthesizer"""
# TODO: Implement Azure synthesizer
raise NotImplementedError("Azure synthesizer not implemented")
def _create_google_synthesizer(self, config: Dict[str, Any]):
"""Create Google Cloud TTS synthesizer"""
# TODO: Implement Google synthesizer
raise NotImplementedError("Google synthesizer not implemented")
def _create_polly_synthesizer(self, config: Dict[str, Any]):
"""Create Amazon Polly synthesizer"""
# TODO: Implement Polly synthesizer
raise NotImplementedError("Polly synthesizer not implemented")
def _create_playht_synthesizer(self, config: Dict[str, Any]):
"""Create Play.ht synthesizer"""
# TODO: Implement Play.ht synthesizer
raise NotImplementedError("Play.ht synthesizer not implemented")
# ============================================================================
# Example Usage
# ============================================================================
def example_usage():
"""Example of how to use the factory"""
# Configuration
config = {
"transcriberProvider": "deepgram",
"deepgramApiKey": "your-api-key",
"llmProvider": "gemini",
"geminiApiKey": "your-api-key",
"voiceProvider": "elevenlabs",
"elevenlabsApiKey": "your-api-key",
"elevenlabsVoiceId": "your-voice-id",
"prompt": "You are a helpful AI assistant."
}
# Create factory
factory = VoiceComponentFactory()
try:
# Create components
transcriber = factory.create_transcriber(config)
agent = factory.create_agent(config)
synthesizer = factory.create_synthesizer(config)
print("✅ All components created successfully!")
except ValueError as e:
print(f"❌ Configuration error: {e}")
except NotImplementedError as e:
print(f"⚠️ Not implemented: {e}")
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
example_usage()

File diff suppressed because it is too large Load Diff