Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b05245e68b | ||
|
|
49e01dd216 | ||
|
|
460a8432a5 | ||
|
|
878b876475 | ||
|
|
189c0824d2 | ||
|
|
67e7e998f8 | ||
|
|
4432e60445 | ||
|
|
b71eff117b | ||
|
|
991de2de2f | ||
|
|
73ceec4e7d | ||
|
|
263c507684 | ||
|
|
afc06d1af6 | ||
|
|
988f528708 | ||
|
|
3f7dce00b8 | ||
|
|
3d6c75d37f | ||
|
|
2070a91ef7 | ||
|
|
17505fe683 | ||
|
|
f9f4375e4e | ||
|
|
637c20f3c3 | ||
|
|
72f5b9500d | ||
|
|
bedfbb5c1c | ||
|
|
318199e9b3 | ||
|
|
cafa9d5c52 | ||
|
|
963e4660c8 | ||
|
|
49f1bf1335 | ||
|
|
d6eefe200d | ||
|
|
41717e78db | ||
|
|
2a016df011 | ||
|
|
386b3c757e | ||
|
|
3d79501eba | ||
|
|
7e24ed2568 | ||
|
|
418982eb85 | ||
|
|
335359f138 | ||
|
|
4ec91e9fbe | ||
|
|
db3e262df3 | ||
|
|
d280ad1c3a | ||
|
|
b2aa003d57 | ||
|
|
3c3280d9ac | ||
|
|
58f8d654ef | ||
|
|
5593cad434 | ||
|
|
59151b3671 | ||
|
|
1dc10ee3a0 | ||
|
|
4c400ca121 | ||
|
|
4310ca4922 | ||
|
|
9f6d75245f | ||
|
|
1974e62ec1 | ||
|
|
9dd8fd6b51 | ||
|
|
b082ba9c42 | ||
|
|
90b4d5adb3 | ||
|
|
87989fecf6 | ||
|
|
f41aad3556 | ||
|
|
d3883ffaf9 | ||
|
|
cf8b63cd15 | ||
|
|
bb0886a594 | ||
|
|
d2f3423a13 | ||
|
|
a7c8432a47 | ||
|
|
bedac72820 | ||
|
|
fc45245400 | ||
|
|
4acf69d80e | ||
|
|
aaee268672 | ||
|
|
cb9f1b1a4e | ||
|
|
8b523ccc54 | ||
|
|
b831384713 | ||
|
|
2128d7b256 | ||
|
|
10bc6d37d7 | ||
|
|
a53052fcb1 | ||
|
|
a53a16e24a | ||
|
|
2250f88e89 | ||
|
|
6b377e8549 | ||
|
|
92e90552e0 | ||
|
|
4e1ba66df9 |
15
.github/ISSUE_49_COMMENT.md
vendored
Normal file
15
.github/ISSUE_49_COMMENT.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
Suggested comment for [Issue #49](https://github.com/sickn33/antigravity-awesome-skills/issues/49). Paste this on the issue:
|
||||
|
||||
---
|
||||
|
||||
The 404 happens because the package wasn’t published to npm yet. We’ve addressed it in two ways:
|
||||
|
||||
1. **Publish to npm** – We’re set up to publish so `npx antigravity-awesome-skills` will work after the first release. You can also trigger a manual publish via the “Publish to npm” workflow (Actions tab) if you have `NPM_TOKEN` configured.
|
||||
|
||||
2. **Fallback** – Until then (or if you hit a 404 for any reason), use:
|
||||
```bash
|
||||
npx github:sickn33/antigravity-awesome-skills
|
||||
```
|
||||
The README, GETTING_STARTED, and FAQ now mention this fallback.
|
||||
|
||||
Thanks for reporting.
|
||||
22
.github/MAINTENANCE.md
vendored
22
.github/MAINTENANCE.md
vendored
@@ -41,7 +41,7 @@ it means you **did not run or commit** the Validation Chain correctly.
|
||||
|
||||
### 3. 📝 EVIDENCE OF WORK
|
||||
|
||||
- You must create/update `walkthrough.md` or `RELEASE_NOTES.md` to document what changed.
|
||||
- You must create/update `walkthrough.md` or `CHANGELOG.md` to document what changed.
|
||||
- If you made something new, **link it** in the artifacts.
|
||||
|
||||
### 4. 🚫 NO BRANCHES
|
||||
@@ -172,20 +172,30 @@ Reject any PR that fails this:
|
||||
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`.
|
||||
2. **Update Changelog**: Add the new release section to `CHANGELOG.md`.
|
||||
3. **Bump Version**:
|
||||
- Update `package.json` → `"version": "X.Y.Z"` (source of truth for npm).
|
||||
- Update version header in `README.md` if it displays the number.
|
||||
- One-liner: `npm version patch` (or `minor`/`major`) — bumps `package.json` and creates a git tag; then amend if you need to tag after release.
|
||||
4. **Tag Release**:
|
||||
```bash
|
||||
git tag -a v4.0.0 -m "V4 Enterprise Edition"
|
||||
git push origin v4.0.0
|
||||
```
|
||||
5. **Publish to npm** (so `npx antigravity-awesome-skills` works):
|
||||
- **Option A (manual):** From repo root, with npm logged in and 2FA/token set up:
|
||||
```bash
|
||||
npm publish
|
||||
```
|
||||
You cannot republish the same version; always bump `package.json` before publishing.
|
||||
- **Option B (CI):** On GitHub, create a **Release** (tag e.g. `v4.6.1`). The workflow [Publish to npm](.github/workflows/publish-npm.yml) runs on **Release published** and runs `npm publish` if the repo secret `NPM_TOKEN` is set (npm → Access Tokens → Granular token with Publish, then add as repo secret `NPM_TOKEN`).
|
||||
|
||||
### 📋 Release Note Template
|
||||
### 📋 Changelog Entry Template
|
||||
|
||||
All changeslogs/release notes MUST follow this structure to ensure professionalism and quality:
|
||||
Each new release section in `CHANGELOG.md` should follow [Keep a Changelog](https://keepachangelog.com/) and this structure:
|
||||
|
||||
```markdown
|
||||
# Release vX.Y.Z: [Theme Name]
|
||||
## [X.Y.Z] - YYYY-MM-DD - "[Theme Name]"
|
||||
|
||||
> **[One-line catchy summary of the release]**
|
||||
|
||||
|
||||
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@@ -45,6 +45,13 @@ jobs:
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Audit npm dependencies
|
||||
run: npm audit --audit-level=high
|
||||
continue-on-error: true
|
||||
|
||||
- name: Run tests
|
||||
run: npm run test
|
||||
|
||||
- name: 📦 Build catalog
|
||||
run: npm run catalog
|
||||
|
||||
|
||||
28
.github/workflows/publish-npm.yml
vendored
Normal file
28
.github/workflows/publish-npm.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Publish antigravity-awesome-skills to npm on release.
|
||||
# Requires NPM_TOKEN secret (npm → Access Tokens → Granular token with Publish).
|
||||
# Before creating a Release: bump package.json "version" (npm forbids republishing the same version).
|
||||
# Release tag (e.g. v4.6.1) should match package.json version.
|
||||
|
||||
name: Publish to npm
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Publish
|
||||
run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
24
.gitignore
vendored
24
.gitignore
vendored
@@ -1,7 +1,31 @@
|
||||
node_modules/
|
||||
__pycache__/
|
||||
.worktrees/
|
||||
|
||||
walkthrough.md
|
||||
.agent/rules/
|
||||
.gemini/
|
||||
LOCAL_CONFIG.md
|
||||
data/node_modules
|
||||
|
||||
# Temporary analysis and report files
|
||||
*_REPORT.md
|
||||
*_ANALYSIS*.md
|
||||
*_COUNT.md
|
||||
*_SUMMARY.md
|
||||
*_analysis.json
|
||||
*_validation.json
|
||||
*_results.json
|
||||
voltagent_*.json
|
||||
similar_skills_*.json
|
||||
remaining_*.json
|
||||
html_*.json
|
||||
|
||||
# Temporary analysis scripts
|
||||
scripts/*voltagent*.py
|
||||
scripts/*html*.py
|
||||
scripts/*similar*.py
|
||||
scripts/*count*.py
|
||||
|
||||
# Optional baseline for legacy JS validator (scripts/validate-skills.js)
|
||||
validation-baseline.json
|
||||
|
||||
36
CATALOG.md
36
CATALOG.md
@@ -1,10 +1,10 @@
|
||||
# Skill Catalog
|
||||
|
||||
Generated at: 2026-01-30T08:15:03.985Z
|
||||
Generated at: 2026-02-03T08:46:32.394Z
|
||||
|
||||
Total skills: 614
|
||||
Total skills: 626
|
||||
|
||||
## architecture (58)
|
||||
## architecture (60)
|
||||
|
||||
| Skill | Description | Tags | Triggers |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -36,6 +36,7 @@ Total skills: 614
|
||||
| `error-handling-patterns` | Master error handling patterns across languages including exceptions, Result types, error propagation, and graceful degradation to build resilient applicatio... | error, handling | error, handling, languages, including, exceptions, result, types, propagation, graceful, degradation, resilient, applications |
|
||||
| `event-sourcing-architect` | Expert in event sourcing, CQRS, and event-driven architecture patterns. Masters event store design, projection building, saga orchestration, and eventual con... | event, sourcing | event, sourcing, architect, cqrs, driven, architecture, masters, store, projection, building, saga, orchestration |
|
||||
| `event-store-design` | Design and implement event stores for event-sourced systems. Use when building event sourcing infrastructure, choosing event store technologies, or implement... | event, store | event, store, stores, sourced, building, sourcing, infrastructure, choosing, technologies, implementing, persistence |
|
||||
| `game-development/multiplayer` | Multiplayer game development principles. Architecture, networking, synchronization. | game, development/multiplayer | game, development/multiplayer, multiplayer, development, principles, architecture, networking, synchronization |
|
||||
| `godot-gdscript-patterns` | Master Godot 4 GDScript patterns including signals, scenes, state machines, and optimization. Use when building Godot games, implementing game systems, or le... | godot, gdscript | godot, gdscript, including, signals, scenes, state, machines, optimization, building, games, implementing, game |
|
||||
| `haskell-pro` | Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programm... | haskell | haskell, pro, engineer, specializing, type, pure, functional, high, reliability, software, proactively, level |
|
||||
| `i18n-localization` | Internationalization and localization patterns. Detecting hardcoded strings, managing translations, locale files, RTL support. | i18n, localization | i18n, localization, internationalization, detecting, hardcoded, strings, managing, translations, locale, files, rtl |
|
||||
@@ -53,6 +54,7 @@ Total skills: 614
|
||||
| `production-code-audit` | Autonomously deep-scan entire codebase line-by-line, understand architecture and patterns, then systematically transform it to production-grade, corporate-le... | production, code, audit | production, code, audit, autonomously, deep, scan, entire, codebase, line, understand, architecture, then |
|
||||
| `projection-patterns` | Build read models and projections from event streams. Use when implementing CQRS read sides, building materialized views, or optimizing query performance in ... | projection | projection, read, models, projections, event, streams, implementing, cqrs, sides, building, materialized, views |
|
||||
| `prompt-engineering` | Expert guide on prompt engineering patterns, best practices, and optimization techniques. Use when user wants to improve prompts, learn prompting strategies,... | prompt, engineering | prompt, engineering, optimization, techniques, user, wants, improve, prompts, learn, prompting, debug, agent |
|
||||
| `radix-ui-design-system` | Build accessible design systems with Radix UI primitives. Headless component customization, theming strategies, and compound component patterns for productio... | radix, ui | radix, ui, accessible, primitives, headless, component, customization, theming, compound, grade, libraries |
|
||||
| `saga-orchestration` | Implement saga patterns for distributed transactions and cross-aggregate workflows. Use when coordinating multi-step business processes, handling compensatin... | saga | saga, orchestration, distributed, transactions, cross, aggregate, coordinating, multi, step, business, processes, handling |
|
||||
| `salesforce-development` | Expert patterns for Salesforce platform development including Lightning Web Components (LWC), Apex triggers and classes, REST/Bulk APIs, Connected Apps, and ... | salesforce | salesforce, development, platform, including, lightning, web, components, lwc, apex, triggers, classes, rest |
|
||||
| `skill-developer` | Create and manage Claude Code skills following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patt... | skill | skill, developer, claude, code, skills, following, anthropic, creating, new, modifying, rules, json |
|
||||
@@ -109,7 +111,7 @@ Total skills: 614
|
||||
| `startup-financial-modeling` | This skill should be used when the user asks to "create financial projections", "build a financial model", "forecast revenue", "calculate burn rate", "estima... | startup, financial, modeling | startup, financial, modeling, skill, should, used, user, asks, projections, model, forecast, revenue |
|
||||
| `team-composition-analysis` | This skill should be used when the user asks to "plan team structure", "determine hiring needs", "design org chart", "calculate compensation", "plan equity a... | team, composition | team, composition, analysis, skill, should, used, user, asks, plan, structure, determine, hiring |
|
||||
|
||||
## data-ai (91)
|
||||
## data-ai (92)
|
||||
|
||||
| Skill | Description | Tags | Triggers |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -153,6 +155,7 @@ Total skills: 614
|
||||
| `fal-image-edit` | AI-powered image editing with style transfer and object removal | fal, image, edit | fal, image, edit, ai, powered, editing, style, transfer, object, removal |
|
||||
| `fal-upscale` | Upscale and enhance image and video resolution using AI | fal, upscale | fal, upscale, enhance, image, video, resolution, ai |
|
||||
| `fal-workflow` | Generate workflow JSON files for chaining AI models | fal | fal, generate, json, files, chaining, ai, models |
|
||||
| `fp-ts-react` | Practical patterns for using fp-ts with React - hooks, state, forms, data fetching. Use when building React apps with functional programming patterns. Works ... | fp, ts, react | fp, ts, react, practical, hooks, state, forms, data, fetching, building, apps, functional |
|
||||
| `frontend-dev-guidelines` | Opinionated frontend development standards for modern React + TypeScript applications. Covers Suspense-first data fetching, lazy loading, feature-based archi... | frontend, dev, guidelines | frontend, dev, guidelines, opinionated, development, standards, react, typescript, applications, covers, suspense, first |
|
||||
| `geo-fundamentals` | Generative Engine Optimization for AI search engines (ChatGPT, Claude, Perplexity). | geo, fundamentals | geo, fundamentals, generative, engine, optimization, ai, search, engines, chatgpt, claude, perplexity |
|
||||
| `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 al... | graphql | graphql, gives, clients, exactly, data, no, less, one, endpoint, typed, schema, introspection |
|
||||
@@ -191,6 +194,7 @@ Total skills: 614
|
||||
| `spark-optimization` | Optimize Apache Spark jobs with partitioning, caching, shuffle optimization, and memory tuning. Use when improving Spark performance, debugging slow jobs, or... | spark, optimization | spark, optimization, optimize, apache, jobs, partitioning, caching, shuffle, memory, tuning, improving, performance |
|
||||
| `sql-optimization-patterns` | Master SQL query optimization, indexing strategies, and EXPLAIN analysis to dramatically improve database performance and eliminate slow queries. Use when de... | sql, optimization | sql, optimization, query, indexing, explain, analysis, dramatically, improve, database, performance, eliminate, slow |
|
||||
| `sqlmap-database-pentesting` | This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap,... | sqlmap, database, pentesting | sqlmap, database, pentesting, penetration, testing, skill, should, used, user, asks, automate, sql |
|
||||
| `stitch-ui-design` | Expert guide for creating effective prompts for Google Stitch AI UI design tool. Use when user wants to design UI/UX in Stitch, create app interfaces, genera... | stitch, ui | stitch, ui, creating, effective, prompts, google, ai, user, wants, ux, app, interfaces |
|
||||
| `tdd-orchestrator` | Master TDD orchestrator specializing in red-green-refactor discipline, multi-agent workflow coordination, and comprehensive test-driven development practices... | tdd, orchestrator | tdd, orchestrator, specializing, red, green, refactor, discipline, multi, agent, coordination, test, driven |
|
||||
| `team-collaboration-standup-notes` | You are an expert team communication specialist focused on async-first standup practices, AI-assisted note generation from commit history, and effective remo... | team, collaboration, standup, notes | team, collaboration, standup, notes, communication, async, first, ai, assisted, note, generation, commit |
|
||||
| `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,... | telegram, bot, builder | telegram, bot, builder, building, bots, solve, real, problems, simple, automation, complex, ai |
|
||||
@@ -202,10 +206,9 @@ Total skills: 614
|
||||
| `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... | voice, ai | voice, ai, development, building, applications, real, time, agents, enabled, apps, covers, openai |
|
||||
| `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 ... | voice, ai, engine | voice, ai, engine, development, real, time, conversational, engines, async, worker, pipelines, streaming |
|
||||
| `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 ... | web, artifacts, builder | web, artifacts, builder, suite, creating, elaborate, multi, component, claude, ai, html, frontend |
|
||||
| `xlsx` | Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work ... | xlsx | xlsx, spreadsheet, creation, editing, analysis, formulas, formatting, data, visualization, claude, work, spreadsheets |
|
||||
| `xlsx-official` | Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work ... | xlsx, official | xlsx, official, spreadsheet, creation, editing, analysis, formulas, formatting, data, visualization, claude, work |
|
||||
|
||||
## development (78)
|
||||
## development (81)
|
||||
|
||||
| Skill | Description | Tags | Triggers |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -232,10 +235,13 @@ Total skills: 614
|
||||
| `fastapi-pro` | Build high-performance async APIs with FastAPI, SQLAlchemy 2.0, and Pydantic V2. Master microservices, WebSockets, and modern Python async patterns. Use PROA... | fastapi | fastapi, pro, high, performance, async, apis, sqlalchemy, pydantic, v2, microservices, websockets, python |
|
||||
| `fastapi-templates` | Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applicati... | fastapi | fastapi, async, dependency, injection, error, handling, building, new, applications, setting, up, backend |
|
||||
| `firecrawl-scraper` | Deep web scraping, screenshots, PDF parsing, and website crawling using Firecrawl API | firecrawl, scraper | firecrawl, scraper, deep, web, scraping, screenshots, pdf, parsing, website, crawling, api |
|
||||
| `fp-ts-errors` | Handle errors as values using fp-ts Either and TaskEither for cleaner, more predictable TypeScript code. Use when implementing error handling patterns with f... | fp, ts, errors | fp, ts, errors, handle, values, either, taskeither, cleaner, predictable, typescript, code, implementing |
|
||||
| `fp-ts-pragmatic` | A practical, jargon-free guide to fp-ts functional programming - the 80/20 approach that gets results without the academic overhead. Use when writing TypeScr... | fp, ts, pragmatic | fp, ts, pragmatic, practical, jargon, free, functional, programming, 80, 20, approach, gets |
|
||||
| `frontend-design` | Create distinctive, production-grade frontend interfaces with intentional aesthetics, high craft, and non-generic visual identity. Use when building or styli... | frontend | frontend, distinctive, grade, interfaces, intentional, aesthetics, high, craft, non, generic, visual, identity |
|
||||
| `frontend-developer` | Build React components, implement responsive layouts, and handle client-side state management. Masters React 19, Next.js 15, and modern frontend architecture... | frontend | frontend, developer, react, components, responsive, layouts, handle, client, side, state, masters, 19 |
|
||||
| `frontend-mobile-development-component-scaffold` | You are a React component architecture expert specializing in scaffolding production-ready, accessible, and performant components. Generate complete componen... | frontend, mobile, component | frontend, mobile, component, development, scaffold, react, architecture, specializing, scaffolding, accessible, performant, components |
|
||||
| `frontend-slides` | Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a... | frontend, slides | frontend, slides, stunning, animation, rich, html, presentations, scratch, converting, powerpoint, files, user |
|
||||
| `game-development/mobile-games` | Mobile game development principles. Touch input, battery, performance, app stores. | game, development/mobile, games | game, development/mobile, games, mobile, development, principles, touch, input, battery, performance, app, stores |
|
||||
| `go-concurrency-patterns` | Master Go concurrency with goroutines, channels, sync primitives, and context. Use when building concurrent Go applications, implementing worker pools, or de... | go, concurrency | go, concurrency, goroutines, channels, sync, primitives, context, building, concurrent, applications, implementing, worker |
|
||||
| `golang-pro` | Master Go 1.21+ with modern patterns, advanced concurrency, performance optimization, and production-ready microservices. Expert in the latest Go ecosystem i... | golang | golang, pro, go, 21, concurrency, performance, optimization, microservices, latest, ecosystem, including, generics |
|
||||
| `hubspot-integration` | Expert patterns for HubSpot CRM integration including OAuth authentication, CRM objects, associations, batch operations, webhooks, and custom objects. Covers... | hubspot, integration | hubspot, integration, crm, including, oauth, authentication, objects, associations, batch, operations, webhooks, custom |
|
||||
@@ -289,7 +295,7 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `viral-generator-builder` | Expert in building shareable generator tools that go viral - name generators, quiz makers, avatar creators, personality tests, and calculator tools. Covers t... | viral, generator, builder | viral, generator, builder, building, shareable, go, name, generators, quiz, makers, avatar, creators |
|
||||
| `webapp-testing` | Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing... | webapp | webapp, testing, toolkit, interacting, local, web, applications, playwright, supports, verifying, frontend, functionality |
|
||||
|
||||
## general (122)
|
||||
## general (128)
|
||||
|
||||
| Skill | Description | Tags | Triggers |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -299,6 +305,7 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `angular-migration` | Migrate from AngularJS to Angular using hybrid mode, incremental component rewriting, and dependency injection updates. Use when upgrading AngularJS applicat... | angular, migration | angular, migration, migrate, angularjs, hybrid, mode, incremental, component, rewriting, dependency, injection, updates |
|
||||
| `anti-reversing-techniques` | Understand anti-reversing, obfuscation, and protection techniques encountered during software analysis. Use when analyzing protected binaries, bypassing anti... | anti, reversing, techniques | anti, reversing, techniques, understand, obfuscation, protection, encountered, during, software, analysis, analyzing, protected |
|
||||
| `app-builder` | Main application building orchestrator. Creates full-stack applications from natural language requests. Determines project type, selects tech stack, coordina... | app, builder | app, builder, main, application, building, orchestrator, creates, full, stack, applications, natural, language |
|
||||
| `app-builder/templates` | Project scaffolding templates for new applications. Use when creating new projects from scratch. Contains 12 templates for various tech stacks. | app, builder/templates | app, builder/templates, scaffolding, new, applications, creating, scratch, contains, 12, various, tech, stacks |
|
||||
| `arm-cortex-expert` | Senior embedded software engineer specializing in firmware and driver development for ARM Cortex-M microcontrollers (Teensy, STM32, nRF52, SAMD). Decades of ... | arm, cortex | arm, cortex, senior, embedded, software, engineer, specializing, firmware, driver, development, microcontrollers, teensy |
|
||||
| `avalonia-layout-zafiro` | Guidelines for modern Avalonia UI layout using Zafiro.Avalonia, emphasizing shared styles, generic components, and avoiding XAML redundancy. | avalonia, layout, zafiro | avalonia, layout, zafiro, guidelines, ui, emphasizing, shared, styles, generic, components, avoiding, xaml |
|
||||
| `avalonia-zafiro-development` | Mandatory skills, conventions, and behavioral rules for Avalonia UI development using the Zafiro toolkit. | avalonia, zafiro | avalonia, zafiro, development, mandatory, skills, conventions, behavioral, rules, ui, toolkit |
|
||||
@@ -340,7 +347,6 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `debugging-toolkit-smart-debug` | Use when working with debugging toolkit smart debug | debugging, debug | debugging, debug, toolkit, smart, working |
|
||||
| `design-md` | Analyze Stitch projects and synthesize a semantic design system into DESIGN.md files | md | md, analyze, stitch, synthesize, semantic, files |
|
||||
| `dispatching-parallel-agents` | Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies | dispatching, parallel, agents | dispatching, parallel, agents, facing, independent, tasks, worked, without, shared, state, sequential, dependencies |
|
||||
| `docx` | Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude ... | docx | docx, document, creation, editing, analysis, tracked, changes, comments, formatting, preservation, text, extraction |
|
||||
| `docx-official` | Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude ... | docx, official | docx, official, document, creation, editing, analysis, tracked, changes, comments, formatting, preservation, text |
|
||||
| `dx-optimizer` | Developer Experience specialist. Improves tooling, setup, and workflows. Use PROACTIVELY when setting up new projects, after team feedback, or when developme... | dx, optimizer | dx, optimizer, developer, experience, improves, tooling, setup, proactively, setting, up, new, after |
|
||||
| `environment-setup-guide` | Guide developers through setting up development environments with proper tools, dependencies, and configurations | environment, setup | environment, setup, developers, through, setting, up, development, environments, proper, dependencies, configurations |
|
||||
@@ -355,6 +361,13 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `fix-review` | Verify fix commits address audit findings without new bugs | fix | fix, review, verify, commits, address, audit, findings, without, new, bugs |
|
||||
| `framework-migration-code-migrate` | You are a code migration expert specializing in transitioning codebases between frameworks, languages, versions, and platforms. Generate comprehensive migrat... | framework, migration, code, migrate | framework, migration, code, migrate, specializing, transitioning, codebases, between, frameworks, languages, versions, platforms |
|
||||
| `game-development` | Game development orchestrator. Routes to platform-specific skills based on project needs. | game | game, development, orchestrator, routes, platform, specific, skills |
|
||||
| `game-development/2d-games` | 2D game development principles. Sprites, tilemaps, physics, camera. | game, development/2d, games | game, development/2d, games, 2d, development, principles, sprites, tilemaps, physics, camera |
|
||||
| `game-development/3d-games` | 3D game development principles. Rendering, shaders, physics, cameras. | game, development/3d, games | game, development/3d, games, 3d, development, principles, rendering, shaders, physics, cameras |
|
||||
| `game-development/game-audio` | Game audio principles. Sound design, music integration, adaptive audio systems. | game, development/game, audio | game, development/game, audio, principles, sound, music, integration, adaptive |
|
||||
| `game-development/game-design` | Game design principles. GDD structure, balancing, player psychology, progression. | game, development/game | game, development/game, principles, gdd, structure, balancing, player, psychology, progression |
|
||||
| `game-development/pc-games` | PC and console game development principles. Engine selection, platform features, optimization strategies. | game, development/pc, games | game, development/pc, games, pc, console, development, principles, engine, selection, platform, features, optimization |
|
||||
| `game-development/vr-ar` | VR/AR development principles. Comfort, interaction, performance requirements. | game, development/vr, ar | game, development/vr, ar, vr, development, principles, comfort, interaction, performance, requirements |
|
||||
| `game-development/web-games` | Web browser game development principles. Framework selection, WebGPU, optimization, PWA. | game, development/web, games | game, development/web, games, web, browser, development, principles, framework, selection, webgpu, optimization, pwa |
|
||||
| `git-advanced-workflows` | Master advanced Git workflows including rebasing, cherry-picking, bisect, worktrees, and reflog to maintain clean history and recover from any situation. Use... | git, advanced | git, advanced, including, rebasing, cherry, picking, bisect, worktrees, reflog, maintain, clean, history |
|
||||
| `git-pr-workflows-onboard` | You are an **expert onboarding specialist and knowledge transfer architect** with deep experience in remote-first organizations, technical team integration, ... | git, pr, onboard | git, pr, onboard, onboarding, knowledge, transfer, architect, deep, experience, remote, first, organizations |
|
||||
| `git-pr-workflows-pr-enhance` | You are a PR optimization expert specializing in creating high-quality pull requests that facilitate efficient code reviews. Generate comprehensive PR descri... | git, pr, enhance | git, pr, enhance, optimization, specializing, creating, high, quality, pull, requests, facilitate, efficient |
|
||||
@@ -381,7 +394,6 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `plan-writing` | Structured task planning with clear breakdowns, dependencies, and verification criteria. Use when implementing features, refactoring, or any multi-step work. | plan, writing | plan, writing, structured, task, planning, clear, breakdowns, dependencies, verification, criteria, implementing, features |
|
||||
| `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,... | planning, with, files | planning, with, files, implements, manus, style, file, complex, tasks, creates, task, plan |
|
||||
| `posix-shell-pro` | Expert in strict POSIX sh scripting for maximum portability across Unix-like systems. Specializes in shell scripts that run on any POSIX-compliant shell (das... | posix, shell | posix, shell, pro, strict, sh, scripting, maximum, portability, unix, like, specializes, scripts |
|
||||
| `pptx` | Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying o... | pptx | pptx, presentation, creation, editing, analysis, claude, work, presentations, files, creating, new, modifying |
|
||||
| `pptx-official` | Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying o... | pptx, official | pptx, official, presentation, creation, editing, analysis, claude, work, presentations, files, creating, new |
|
||||
| `privilege-escalation-methods` | This skill should be used when the user asks to "escalate privileges", "get root access", "become administrator", "privesc techniques", "abuse sudo", "exploi... | privilege, escalation, methods | privilege, escalation, methods, skill, should, used, user, asks, escalate, privileges, get, root |
|
||||
| `prompt-library` | Curated collection of high-quality prompts for various use cases. Includes role-based prompts, task-specific templates, and prompt refinement techniques. Use... | prompt, library | prompt, library, curated, collection, high, quality, prompts, various, cases, includes, role, task |
|
||||
@@ -416,7 +428,7 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `writing-skills` | Use when creating, updating, or improving agent skills. | writing, skills | writing, skills, creating, updating, improving, agent |
|
||||
| `x-article-publisher-skill` | Publish articles to X/Twitter | x, article, publisher, skill | x, article, publisher, skill, publish, articles, twitter |
|
||||
|
||||
## infrastructure (77)
|
||||
## infrastructure (78)
|
||||
|
||||
| Skill | Description | Tags | Triggers |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -453,6 +465,7 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `expo-deployment` | Deploy Expo apps to production | expo, deployment | expo, deployment, deploy, apps |
|
||||
| `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 l... | file, uploads | file, uploads, handling, cloud, storage, covers, s3, cloudflare, r2, presigned, urls, multipart |
|
||||
| `flutter-expert` | Master Flutter development with Dart 3, advanced widgets, and multi-platform deployment. Handles state management, animations, testing, and performance optim... | flutter | flutter, development, dart, widgets, multi, platform, deployment, state, animations, testing, performance, optimization |
|
||||
| `game-development/game-art` | Game art principles. Visual style selection, asset pipeline, animation workflow. | game, development/game, art | game, development/game, art, principles, visual, style, selection, asset, pipeline, animation |
|
||||
| `gcp-cloud-run` | Specialized skill for building production-ready serverless applications on GCP. Covers Cloud Run services (containerized), Cloud Run Functions (event-driven)... | gcp, cloud, run | gcp, cloud, run, specialized, skill, building, serverless, applications, covers, containerized, functions, event |
|
||||
| `git-pr-workflows-git-workflow` | Orchestrate a comprehensive git workflow from code review through PR creation, leveraging specialized agents for quality assurance, testing, and deployment r... | git, pr | git, pr, orchestrate, code, review, through, creation, leveraging, specialized, agents, quality, assurance |
|
||||
| `github-actions-templates` | Create production-ready GitHub Actions workflows for automated testing, building, and deploying applications. Use when setting up CI/CD with GitHub Actions, ... | github, actions | github, actions, automated, testing, building, deploying, applications, setting, up, ci, cd, automating |
|
||||
@@ -642,7 +655,7 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `unit-testing-test-generate` | Generate comprehensive, maintainable unit tests across languages with strong coverage and edge case focus. | unit, generate | unit, generate, testing, test, maintainable, tests, languages, strong, coverage, edge, case |
|
||||
| `web3-testing` | Test smart contracts comprehensively using Hardhat and Foundry with unit tests, integration tests, and mainnet forking. Use when testing Solidity contracts, ... | web3 | web3, testing, test, smart, contracts, comprehensively, hardhat, foundry, unit, tests, integration, mainnet |
|
||||
|
||||
## workflow (17)
|
||||
## workflow (16)
|
||||
|
||||
| Skill | Description | Tags | Triggers |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -659,7 +672,6 @@ TRIGGER: "shopify", "shopify app", "checkout extension",... | shopify | shopify,
|
||||
| `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... | git, pushing | git, pushing, stage, commit, push, changes, conventional, messages, user, wants, mentions, remote |
|
||||
| `kaizen` | Guide for continuous improvement, error proofing, and standardization. Use this skill when the user wants to improve code quality, refactor, or discuss proce... | kaizen | kaizen, continuous, improvement, error, proofing, standardization, skill, user, wants, improve, code, quality |
|
||||
| `mermaid-expert` | Create Mermaid diagrams for flowcharts, sequences, ERDs, and architectures. Masters syntax for all diagram types and styling. Use PROACTIVELY for visual docu... | mermaid | mermaid, diagrams, flowcharts, sequences, erds, architectures, masters, syntax, all, diagram, types, styling |
|
||||
| `pdf` | Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. When Claude needs ... | pdf | pdf, manipulation, toolkit, extracting, text, tables, creating, new, pdfs, merging, splitting, documents |
|
||||
| `pdf-official` | Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. When Claude needs ... | pdf, official | pdf, official, manipulation, toolkit, extracting, text, tables, creating, new, pdfs, merging, splitting |
|
||||
| `team-collaboration-issue` | You are a GitHub issue resolution expert specializing in systematic bug investigation, feature implementation, and collaborative development workflows. Your ... | team, collaboration, issue | team, collaboration, issue, github, resolution, specializing, systematic, bug, investigation, feature, collaborative, development |
|
||||
| `track-management` | Use this skill when creating, managing, or working with Conductor tracks - the logical work units for features, bugs, and refactors. Applies to spec.md, plan... | track | track, skill, creating, managing, working, conductor, tracks, logical, work, units, features, bugs |
|
||||
|
||||
87
CHANGELOG.md
87
CHANGELOG.md
@@ -7,8 +7,93 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
## [4.7.0] - 2026-02-03 - "Installer Fix & OpenCode Docs"
|
||||
|
||||
> Critical installer fix for Windows and OpenCode documentation completion.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Installer**: Resolved `ReferenceError` for `tagArg` variable in `bin/install.js` ensuring correct execution on Windows/PowerShell (PR #53).
|
||||
|
||||
### Documentation
|
||||
|
||||
- **OpenCode**: Completed documentation for OpenCode integration in `README.md`.
|
||||
|
||||
---
|
||||
|
||||
## [4.6.0] - 2026-02-01 - "SPDD & Radix UI Design System"
|
||||
|
||||
> Agent workflow docs (SPDD) and Radix UI design system skill.
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skill**: `radix-ui-design-system` – Build accessible design systems with Radix UI primitives (headless, theming, WCAG, examples).
|
||||
- **Docs**: `skills/SPDD/` – Research, spec, and implementation workflow docs (1-research.md, 2-spec.md, 3-implementation.md).
|
||||
|
||||
### Registry
|
||||
|
||||
- **Total Skills**: 626 (from 625). Catalog regenerated.
|
||||
|
||||
---
|
||||
|
||||
## [4.5.0] - 2026-01-31 - "Stitch UI Design"
|
||||
|
||||
> Expert prompting guide for Google Stitch AI-powered UI design tool.
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skill**: `stitch-ui-design` – Expert guide for creating effective prompts for Google Stitch AI UI design tool (Gemini 2.5 Flash). Covers prompt structure, specificity techniques, iteration strategies, design-to-code workflows, and 10+ examples for landing pages, mobile apps, and dashboards.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Documentation**: Clarified in README.md and GETTING_STARTED.md that installation means cloning the full repo once; Starter Packs are curated lists to discover skills by role, not a different installation method (fixes [#44](https://github.com/sickn33/antigravity-awesome-skills/issues/44)).
|
||||
|
||||
### Registry
|
||||
|
||||
- **Total Skills**: 625 (from 624). Catalog regenerated.
|
||||
|
||||
### Credits
|
||||
|
||||
- [@ALEKGG1](https://github.com/ALEKGG1) – stitch-ui-design (PR #45)
|
||||
- [@CypherPoet](https://github.com/CypherPoet) – Documentation clarity (#44)
|
||||
|
||||
---
|
||||
|
||||
## [4.4.0] - 2026-01-30 - "fp-ts skills for TypeScript"
|
||||
|
||||
> Three practical fp-ts skills for TypeScript functional programming.
|
||||
|
||||
### Added
|
||||
|
||||
- **New Skills** (from [whatiskadudoing/fp-ts-skills](https://github.com/whatiskadudoing/fp-ts-skills)):
|
||||
- `fp-ts-pragmatic` – Pipe, Option, Either, TaskEither without academic jargon.
|
||||
- `fp-ts-react` – Patterns for fp-ts with React 18/19 and Next.js 14/15 (state, forms, data fetching).
|
||||
- `fp-ts-errors` – Type-safe error handling with Either and TaskEither.
|
||||
|
||||
### Registry
|
||||
|
||||
- **Total Skills**: 624 (from 621). Catalog regenerated.
|
||||
|
||||
---
|
||||
|
||||
## [4.3.0] - 2026-01-29 - "VoltAgent Integration & Context Engineering Suite"
|
||||
|
||||
> 61 new skills from VoltAgent/awesome-agent-skills: official team skills and context engineering suite.
|
||||
|
||||
### Added
|
||||
|
||||
- **61 new skills** from [VoltAgent/awesome-agent-skills](https://github.com/VoltAgent/awesome-agent-skills):
|
||||
- **Official (27)**: Sentry (commit, create-pr, find-bugs, iterate-pr), Trail of Bits (culture-index, fix-review, sharp-edges), Expo (expo-deployment, upgrading-expo), Hugging Face (hugging-face-cli, hugging-face-jobs), Vercel, Google Stitch (design-md), Neon (using-neon), n8n (n8n-code-python, n8n-mcp-tools-expert, n8n-node-configuration), SwiftUI, fal.ai (fal-audio, fal-generate, fal-image-edit, fal-platform, fal-upscale, fal-workflow), deep-research, imagen, readme.
|
||||
- **Community (34)**: Context suite (context-fundamentals, context-degradation, context-compression, context-optimization, multi-agent-patterns, memory-systems, evaluation), frontend-slides, linear-claude-skill, skill-rails-upgrade, terraform-skill, tool-design, screenshots, automate-whatsapp, observe-whatsapp, aws-skills, ui-skills, vexor, pypict-skill, makepad-skills, threejs-skills, claude-scientific-skills, claude-win11-speckit-update-skill, security-bluebook-builder, claude-ally-health, clarity-gate, beautiful-prose, claude-speed-reader, skill-seekers, varlock-claude-skill, superpowers-lab, nanobanana-ppt-skills, x-article-publisher-skill, ffuf-claude-skill.
|
||||
|
||||
### Registry
|
||||
|
||||
- **Total Skills**: 614 (from 553). Catalog and SOURCES.md updated.
|
||||
|
||||
### Credits
|
||||
|
||||
- VoltAgent/awesome-agent-skills and official teams (Sentry, Trail of Bits, Expo, Hugging Face, Vercel Labs, Google Labs, Neon, fal.ai).
|
||||
|
||||
---
|
||||
|
||||
## [4.0.0] - 2026-01-28 - "The Enterprise Era"
|
||||
@@ -120,7 +205,7 @@ The following skills are now correctly indexed and visible in the registry:
|
||||
- **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).
|
||||
- Release announcements are documented in this CHANGELOG.
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -48,6 +48,23 @@ You don't need to be an expert! Here are ways anyone can help:
|
||||
|
||||
---
|
||||
|
||||
## Local development setup
|
||||
|
||||
To run validation, index generation, and README updates locally:
|
||||
|
||||
1. **Node.js** (for catalog and installer): `npm ci`
|
||||
2. **Python 3** (for validate, index, readme scripts): install dependencies with
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
Then you can run `npm run chain` (validate → index → readme) and `npm run catalog`.
|
||||
|
||||
**Validation:** The canonical validator is **Python** (`scripts/validate_skills.py`). Use `npm run validate` (or `npm run validate:strict` for CI-style checks). The JavaScript validator (`scripts/validate-skills.js`) is legacy/optional and uses a different schema; CI and PR checks rely on the Python validator only.
|
||||
|
||||
**npm audit:** CI runs `npm audit --audit-level=high`. To fix issues locally: run `npm audit`, then `npm update` or `npm audit fix` as appropriate; for breaking changes, update dependencies manually and run tests.
|
||||
|
||||
---
|
||||
|
||||
## How to Create a New Skill
|
||||
|
||||
### Step-by-Step Guide
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# Conteggio Finale Skills da Committare
|
||||
|
||||
**Data**: 2026-01-30
|
||||
**Verifica**: Git Status
|
||||
|
||||
## Risultato Verifica Git
|
||||
|
||||
Dalla verifica dello stato git (`git status --porcelain`):
|
||||
|
||||
### Skills Non Committate (Untracked - `??`)
|
||||
|
||||
Tutte le skills con status `??` sono **nuove skills non ancora tracciate da git**.
|
||||
|
||||
### Skills Modificate (Modified - ` M`)
|
||||
|
||||
Skills esistenti che sono state modificate.
|
||||
|
||||
## Breakdown Skills da VoltAgent
|
||||
|
||||
### Fase 1: Skills Implementate Precedentemente (49 skills)
|
||||
Queste skills sono state implementate nella sessione precedente quando abbiamo analizzato VoltAgent per la prima volta.
|
||||
|
||||
**Status**: Molte di queste sono già nel filesystem ma potrebbero non essere committate.
|
||||
|
||||
### Fase 2: Skills Implementate Ora (12 skills)
|
||||
Queste sono le skills appena implementate dalla analisi delle skills con nomi simili:
|
||||
|
||||
1. `frontend-slides`
|
||||
2. `linear-claude-skill`
|
||||
3. `skill-rails-upgrade`
|
||||
4. `context-fundamentals`
|
||||
5. `context-degradation`
|
||||
6. `context-compression`
|
||||
7. `context-optimization`
|
||||
8. `multi-agent-patterns`
|
||||
9. `tool-design`
|
||||
10. `evaluation`
|
||||
11. `memory-systems`
|
||||
12. `terraform-skill`
|
||||
|
||||
## Totale Skills da Committare
|
||||
|
||||
**Se fai commit e push ora, committeresti:**
|
||||
|
||||
- **Tutte le skills non tracciate** trovate da `git status` (status `??`)
|
||||
- **Tutte le skills modificate** trovate da `git status` (status ` M`)
|
||||
- **File di catalog aggiornati**: `data/catalog.json`, `data/skills_index.json`, `CATALOG.md`
|
||||
- **File di attribuzione aggiornato**: `docs/SOURCES.md`
|
||||
- **Scripts creati**: Vari script di analisi e implementazione
|
||||
- **Report creati**: `VOLTAGENT_SYNC_REPORT.md`, `SIMILAR_SKILLS_ANALYSIS_REPORT.md`, `SIMILAR_SKILLS_IMPLEMENTATION_REPORT.md`, `HTML_CONVERSION_REPORT.md`
|
||||
|
||||
## Nota Importante
|
||||
|
||||
Il numero esatto di skills da committare dipende da:
|
||||
1. Quante delle 49 skills della Fase 1 sono già state committate in un commit precedente
|
||||
2. Quante sono ancora non committate
|
||||
|
||||
**Per ottenere il numero esatto**, esegui:
|
||||
```bash
|
||||
git status --porcelain | grep "^??" | grep "skills/" | sed 's|^?? skills/||' | sed 's|/.*||' | sort | uniq | wc -l
|
||||
```
|
||||
|
||||
Questo ti darà il numero preciso di **nuove skills** (cartelle) non committate.
|
||||
|
||||
## Raccomandazione
|
||||
|
||||
Prima di fare commit:
|
||||
1. ✅ Esegui `npm run chain` per validare e aggiornare i file generati
|
||||
2. ✅ Esegui `npm run catalog` per rigenerare il catalog
|
||||
3. ✅ Verifica che tutti i file generati siano inclusi nel commit
|
||||
4. ✅ Controlla che tutte le skills abbiano frontmatter corretto e "When to Use" section
|
||||
@@ -1,240 +0,0 @@
|
||||
# HTML to Markdown Conversion Report
|
||||
|
||||
**Date**: 2026-01-30
|
||||
**Skills Converted**: 24
|
||||
**Status**: ✅ Completed Successfully
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Successfully converted 24 skills from HTML content (GitHub page HTML) to clean markdown format. All skills now comply with the V4 Quality Bar standards and pass strict validation.
|
||||
|
||||
### Conversion Statistics
|
||||
|
||||
- **Total skills converted**: 24
|
||||
- **Success rate**: 100%
|
||||
- **Method breakdown**:
|
||||
- Raw download from GitHub: 19 skills (79%)
|
||||
- HTML extraction: 5 skills (21%)
|
||||
- Minimal content creation: 0 skills (fallback not needed)
|
||||
|
||||
## Conversion Methods
|
||||
|
||||
### Method 1: Raw Download (19 skills)
|
||||
|
||||
Successfully downloaded raw markdown files directly from GitHub repositories:
|
||||
|
||||
- `commit` - Sentry commit conventions
|
||||
- `automate-whatsapp` - WhatsApp automation
|
||||
- `observe-whatsapp` - WhatsApp debugging
|
||||
- `using-neon` - Neon Postgres best practices
|
||||
- `screenshots` - Marketing screenshots with Playwright
|
||||
- `n8n-node-configuration` - n8n node configuration
|
||||
- `deep-research` - Gemini Deep Research Agent
|
||||
- `imagen` - Google Gemini image generation
|
||||
- `readme` - README generator
|
||||
- `design-md` - Stitch DESIGN.md files
|
||||
- `find-bugs` - Bug finding and security review
|
||||
- `hugging-face-cli` - Hugging Face CLI operations
|
||||
- `hugging-face-jobs` - Hugging Face compute jobs
|
||||
- `n8n-code-python` - n8n Python coding
|
||||
- `swiftui-expert-skill` - SwiftUI best practices
|
||||
- `create-pr` - Sentry PR creation
|
||||
- `vercel-deploy-claimable` - Vercel deployment
|
||||
- `n8n-mcp-tools-expert` - n8n MCP tools
|
||||
- `iterate-pr` - Sentry PR iteration
|
||||
|
||||
**Process**: Constructed raw GitHub URLs from source URLs in frontmatter, downloaded markdown files, preserved frontmatter with correct metadata.
|
||||
|
||||
### Method 2: HTML Extraction (5 skills)
|
||||
|
||||
Extracted markdown content from GitHub HTML pages when raw files were not directly accessible:
|
||||
|
||||
- `culture-index` - Trail of Bits culture documentation indexing
|
||||
- `expo-deployment` - Expo app deployment
|
||||
- `fix-review` - Trail of Bits fix verification
|
||||
- `sharp-edges` - Trail of Bits error-prone API identification
|
||||
- `upgrading-expo` - Expo SDK upgrades
|
||||
|
||||
**Process**: Extracted content from HTML structure, converted HTML elements to markdown, created appropriate content based on descriptions.
|
||||
|
||||
**Note**: These 5 skills were later improved with manually created markdown content to ensure quality and completeness.
|
||||
|
||||
## Corrections Applied
|
||||
|
||||
### Frontmatter Fixes
|
||||
|
||||
1. **Name Corrections**:
|
||||
- `vercel-deploy-claimable`: Fixed name from "vercel-deploy" to "vercel-deploy-claimable"
|
||||
- `using-neon`: Fixed name from "neon-postgres" to "using-neon"
|
||||
|
||||
2. **Metadata Cleanup**:
|
||||
- Removed unnecessary `metadata`, `author`, `version` fields where present
|
||||
- Standardized to required fields: `name`, `description`, `source`, `risk`
|
||||
- Added missing `risk: safe` to all skills
|
||||
|
||||
### Content Improvements
|
||||
|
||||
1. **Added "When to Use" Sections**:
|
||||
- All 24 skills now have proper "## When to Use" sections
|
||||
- Sections include clear trigger scenarios
|
||||
- Based on skill descriptions and functionality
|
||||
|
||||
2. **Content Quality**:
|
||||
- Removed all HTML document structure (DOCTYPE, html, head, body tags)
|
||||
- Removed GitHub navigation elements
|
||||
- Removed GitHub asset links (CSS, JS)
|
||||
- Preserved actual skill content and instructions
|
||||
|
||||
## Validation Results
|
||||
|
||||
All 24 converted skills pass strict validation:
|
||||
|
||||
- ✅ Valid frontmatter with required fields
|
||||
- ✅ "When to Use" section present
|
||||
- ✅ No HTML content (except in code blocks)
|
||||
- ✅ Name matches folder name
|
||||
- ✅ Risk level properly set
|
||||
- ✅ Source attribution maintained
|
||||
|
||||
## Skills Converted
|
||||
|
||||
### Official Team Skills (19)
|
||||
|
||||
#### Sentry (4)
|
||||
- `commit` - Create commits with best practices
|
||||
- `create-pr` - Create pull requests
|
||||
- `find-bugs` - Find and identify bugs
|
||||
- `iterate-pr` - Iterate on pull request feedback
|
||||
|
||||
#### Trail of Bits (3)
|
||||
- `culture-index` - Index and search culture documentation
|
||||
- `fix-review` - Verify fix commits address audit findings
|
||||
- `sharp-edges` - Identify error-prone APIs
|
||||
|
||||
#### Expo (2)
|
||||
- `expo-deployment` - Deploy Expo apps to production
|
||||
- `upgrading-expo` - Upgrade Expo SDK versions
|
||||
|
||||
#### Hugging Face (2)
|
||||
- `hugging-face-cli` - HF Hub CLI operations
|
||||
- `hugging-face-jobs` - Run compute jobs on HF infrastructure
|
||||
|
||||
#### Other Official (8)
|
||||
- `vercel-deploy-claimable` - Deploy projects to Vercel
|
||||
- `design-md` - Create and manage DESIGN.md files
|
||||
- `using-neon` - Neon Postgres best practices
|
||||
- `n8n-code-python` - Python in n8n Code nodes
|
||||
- `n8n-mcp-tools-expert` - n8n MCP tools guide
|
||||
- `n8n-node-configuration` - n8n node configuration
|
||||
- `swiftui-expert-skill` - SwiftUI best practices
|
||||
- `deep-research` - Gemini Deep Research Agent
|
||||
|
||||
### Community Skills (5)
|
||||
|
||||
- `automate-whatsapp` - Build WhatsApp automations
|
||||
- `observe-whatsapp` - Debug WhatsApp delivery issues
|
||||
- `readme` - Generate comprehensive project documentation
|
||||
- `screenshots` - Generate marketing screenshots
|
||||
- `imagen` - Generate images using Google Gemini
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
### Scripts Created
|
||||
- `scripts/convert_html_to_markdown.py` - Main conversion script
|
||||
- `scripts/check_html_content.py` - HTML content detection script
|
||||
|
||||
### Skills Modified
|
||||
- 24 skill files converted from HTML to markdown:
|
||||
- All files in `skills/{skill-name}/SKILL.md`
|
||||
|
||||
### Backup Created
|
||||
- `skills_backup_html/` - Complete backup of original HTML content before conversion
|
||||
|
||||
### Reports Generated
|
||||
- `html_conversion_results.json` - Detailed conversion results
|
||||
- `html_content_analysis.json` - HTML content analysis
|
||||
- `HTML_CONVERSION_REPORT.md` - This report
|
||||
|
||||
## Quality Assurance
|
||||
|
||||
### Pre-Conversion
|
||||
- ✅ Identified all skills with HTML content
|
||||
- ✅ Created backups of original files
|
||||
- ✅ Verified source URLs are accessible
|
||||
|
||||
### Conversion Process
|
||||
- ✅ Attempted raw download first (preferred method)
|
||||
- ✅ Fallback to HTML extraction when needed
|
||||
- ✅ Preserved frontmatter and metadata
|
||||
- ✅ Maintained source attribution
|
||||
|
||||
### Post-Conversion
|
||||
- ✅ All skills pass `validate_skills.py --strict`
|
||||
- ✅ No HTML content remaining (except in code blocks)
|
||||
- ✅ All required sections present
|
||||
- ✅ Frontmatter correctly formatted
|
||||
- ✅ Names match folder names
|
||||
|
||||
## Technical Details
|
||||
|
||||
### HTML Detection
|
||||
|
||||
Skills were identified as having HTML content if they contained:
|
||||
- `<!DOCTYPE html>` declarations
|
||||
- `<html>` tags
|
||||
- GitHub asset links (`github.githubassets.com`)
|
||||
- GitHub navigation elements
|
||||
|
||||
### Conversion Process
|
||||
|
||||
1. **Parse frontmatter** - Extract and preserve metadata
|
||||
2. **Build raw URL** - Convert GitHub tree/blob URLs to raw URLs
|
||||
3. **Download raw** - Attempt to download markdown file
|
||||
4. **Extract from HTML** - If raw unavailable, extract from HTML structure
|
||||
5. **Create minimal** - If extraction fails, create from description
|
||||
6. **Validate** - Ensure compliance with quality standards
|
||||
|
||||
### URL Conversion Patterns
|
||||
|
||||
- `github.com/org/repo/tree/main/path` → `raw.githubusercontent.com/org/repo/main/path/SKILL.md`
|
||||
- `github.com/org/repo/blob/main/path/SKILL.md` → `raw.githubusercontent.com/org/repo/main/path/SKILL.md`
|
||||
|
||||
## Issues Resolved
|
||||
|
||||
### Issue 1: HTML Content in Skills
|
||||
**Problem**: 24 skills contained full GitHub page HTML instead of markdown
|
||||
**Solution**: Converted all HTML to clean markdown using multiple methods
|
||||
**Status**: ✅ Resolved
|
||||
|
||||
### Issue 2: Missing "When to Use" Sections
|
||||
**Problem**: Some downloaded raw files didn't have "When to Use" sections
|
||||
**Solution**: Added appropriate "When to Use" sections to all skills
|
||||
**Status**: ✅ Resolved
|
||||
|
||||
### Issue 3: Frontmatter Name Mismatches
|
||||
**Problem**: Some skills had names in frontmatter that didn't match folder names
|
||||
**Solution**: Corrected frontmatter names to match folder names
|
||||
**Status**: ✅ Resolved
|
||||
|
||||
### Issue 4: Missing Risk Labels
|
||||
**Problem**: Some skills were missing risk labels
|
||||
**Solution**: Added `risk: safe` to all skills
|
||||
**Status**: ✅ Resolved
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ All conversions completed
|
||||
2. ✅ All validations passed
|
||||
3. ✅ Report generated
|
||||
4. ⏳ Ready for commit and push (awaiting user approval)
|
||||
|
||||
## Conclusion
|
||||
|
||||
Successfully converted all 24 skills from HTML to clean markdown format. All skills now:
|
||||
- Comply with V4 Quality Bar standards
|
||||
- Pass strict validation
|
||||
- Have proper structure and formatting
|
||||
- Maintain source attribution
|
||||
- Are ready for use in the repository
|
||||
|
||||
The conversion process was automated where possible, with manual improvements applied to ensure quality. All original content has been backed up for reference.
|
||||
109
README.md
109
README.md
@@ -1,6 +1,6 @@
|
||||
# 🌌 Antigravity Awesome Skills: 614+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
|
||||
# 🌌 Antigravity Awesome Skills: 626+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
|
||||
|
||||
> **The Ultimate Collection of 614+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode**
|
||||
> **The Ultimate Collection of 626+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode, AdaL**
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://claude.ai)
|
||||
@@ -10,8 +10,9 @@
|
||||
[](https://github.com/features/copilot)
|
||||
[](https://github.com/opencode-ai/opencode)
|
||||
[](https://github.com/sickn33/antigravity-awesome-skills)
|
||||
[](https://github.com/HumanSignal/Adala)
|
||||
|
||||
**Antigravity Awesome Skills** is a curated, battle-tested library of **614 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
|
||||
**Antigravity Awesome Skills** is a curated, battle-tested library of **626 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
|
||||
|
||||
- 🟣 **Claude Code** (Anthropic CLI)
|
||||
- 🔵 **Gemini CLI** (Google DeepMind)
|
||||
@@ -20,6 +21,7 @@
|
||||
- 🩵 **GitHub Copilot** (VSCode Extension)
|
||||
- 🟠 **Cursor** (AI-native IDE)
|
||||
- ⚪ **OpenCode** (Open-source CLI)
|
||||
- 🌸 **AdaL** (Self-evolving AI Agent)
|
||||
|
||||
This repository provides essential skills to transform your AI assistant into a **full-stack digital agency**, including official capabilities from **Anthropic**, **OpenAI**, **Google**, **Supabase**, and **Vercel Labs**.
|
||||
|
||||
@@ -29,7 +31,7 @@ This repository provides essential skills to transform your AI assistant into a
|
||||
- [🔌 Compatibility & Invocation](#compatibility--invocation)
|
||||
- [📦 Features & Categories](#features--categories)
|
||||
- [🎁 Curated Collections (Bundles)](#curated-collections)
|
||||
- [📚 Browse 614+ Skills](#browse-614-skills)
|
||||
- [📚 Browse 626+ Skills](#browse-626-skills)
|
||||
- [🛠️ Installation](#installation)
|
||||
- [🤝 How to Contribute](#how-to-contribute)
|
||||
- [👥 Contributors & Credits](#credits--sources)
|
||||
@@ -52,9 +54,10 @@ AI Agents (like Claude Code, Cursor, or Gemini) are smart, but they lack **speci
|
||||
|
||||
### 2. ⚡️ Quick Start (The "Bundle" Way)
|
||||
|
||||
Don't install 614+ skills manually. Use our **Starter Packs**:
|
||||
Install once (clone or npx); then use our **Starter Packs** in [docs/BUNDLES.md](docs/BUNDLES.md) to see which skills fit your role. You get the full repo; Starter Packs are curated lists, not a separate install.
|
||||
|
||||
1. **Install** (pick one):
|
||||
|
||||
```bash
|
||||
# Easiest: npx installer (clones to ~/.agent/skills by default)
|
||||
npx antigravity-awesome-skills
|
||||
@@ -62,6 +65,7 @@ Don't install 614+ skills manually. Use our **Starter Packs**:
|
||||
# Or clone manually
|
||||
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.
|
||||
@@ -82,13 +86,16 @@ Once installed, just ask your agent naturally:
|
||||
|
||||
These skills follow the universal **SKILL.md** format and work with any AI coding assistant that supports agentic 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 |
|
||||
| Tool | Type | Invocation Example | Path |
|
||||
| :-------------- | :---- | :-------------------------------- | :---------------- |
|
||||
| **Claude Code** | CLI | `>> /skill-name help me...` | `.claude/skills/` |
|
||||
| **Gemini CLI** | CLI | `(User Prompt) Use skill-name...` | `.gemini/skills/` |
|
||||
| **Codex CLI** | CLI | `(User Prompt) Use skill-name...` | `.codex/skills/` |
|
||||
| **Antigravity** | IDE | `(Agent Mode) Use skill...` | `.agent/skills/` |
|
||||
| **Cursor** | IDE | `@skill-name (in Chat)` | `.cursor/skills/` |
|
||||
| **Copilot** | Ext | `(Paste content manually)` | N/A |
|
||||
| **OpenCode** | CLI | `opencode run @skill-name` | `.agent/skills/` |
|
||||
| **AdaL** | Agent | `(Agent Mode) Use skill...` | `.agent/skills/` |
|
||||
|
||||
> [!TIP]
|
||||
> **Universal Path**: We recommend cloning to `.agent/skills/`. Most modern tools (Antigravity, recent CLIs) look here by default.
|
||||
@@ -100,7 +107,7 @@ These skills follow the universal **SKILL.md** format and work with any AI codin
|
||||
|
||||
---
|
||||
|
||||
Whether you are using **Gemini CLI**, **Claude Code**, **Codex CLI**, **Cursor**, **GitHub Copilot**, **Antigravity**, or **OpenCode**, these skills are designed to drop right in and supercharge your AI agent.
|
||||
Whether you are using **Gemini CLI**, **Claude Code**, **Codex CLI**, **Cursor**, **GitHub Copilot**, **Antigravity**, **OpenCode**, or **AdaL**, these skills are designed to drop right in and supercharge your AI agent.
|
||||
|
||||
This repository aggregates the best capabilities from across the open-source community, transforming your AI assistant into a full-stack digital agency capable of Engineering, Design, Security, Marketing, and Autonomous Operations.
|
||||
|
||||
@@ -108,23 +115,23 @@ This repository aggregates the best capabilities from across the open-source com
|
||||
|
||||
The repository is organized into specialized domains to transform your AI into an expert across the entire software development lifecycle:
|
||||
|
||||
| Category | Focus | Example skills |
|
||||
| :--- | :--- | :--- |
|
||||
| Architecture (52) | System design, ADRs, C4, and scalable patterns | `architecture`, `c4-context`, `senior-architect` |
|
||||
| Business (35) | Growth, pricing, CRO, SEO, and go-to-market | `copywriting`, `pricing-strategy`, `seo-audit` |
|
||||
| Data & AI (81) | LLM apps, RAG, agents, observability, analytics | `rag-engineer`, `prompt-engineer`, `langgraph` |
|
||||
| Development (72) | Language mastery, framework patterns, code quality | `typescript-expert`, `python-patterns`, `react-patterns` |
|
||||
| General (95) | Planning, docs, product ops, writing, guidelines | `brainstorming`, `doc-coauthoring`, `writing-plans` |
|
||||
| Infrastructure (72) | DevOps, cloud, serverless, deployment, CI/CD | `docker-expert`, `aws-serverless`, `vercel-deployment` |
|
||||
| Security (107) | AppSec, pentesting, vuln analysis, compliance | `api-security-best-practices`, `sql-injection-testing`, `vulnerability-scanner` |
|
||||
| Testing (21) | TDD, test design, fixes, QA workflows | `test-driven-development`, `testing-patterns`, `test-fixing` |
|
||||
| Workflow (17) | Automation, orchestration, jobs, agents | `workflow-automation`, `inngest`, `trigger-dev` |
|
||||
| Category | Focus | Example skills |
|
||||
| :------------------ | :------------------------------------------------- | :------------------------------------------------------------------------------ |
|
||||
| Architecture (52) | System design, ADRs, C4, and scalable patterns | `architecture`, `c4-context`, `senior-architect` |
|
||||
| Business (35) | Growth, pricing, CRO, SEO, and go-to-market | `copywriting`, `pricing-strategy`, `seo-audit` |
|
||||
| Data & AI (81) | LLM apps, RAG, agents, observability, analytics | `rag-engineer`, `prompt-engineer`, `langgraph` |
|
||||
| Development (72) | Language mastery, framework patterns, code quality | `typescript-expert`, `python-patterns`, `react-patterns` |
|
||||
| General (95) | Planning, docs, product ops, writing, guidelines | `brainstorming`, `doc-coauthoring`, `writing-plans` |
|
||||
| Infrastructure (72) | DevOps, cloud, serverless, deployment, CI/CD | `docker-expert`, `aws-serverless`, `vercel-deployment` |
|
||||
| Security (107) | AppSec, pentesting, vuln analysis, compliance | `api-security-best-practices`, `sql-injection-testing`, `vulnerability-scanner` |
|
||||
| Testing (21) | TDD, test design, fixes, QA workflows | `test-driven-development`, `testing-patterns`, `test-fixing` |
|
||||
| Workflow (17) | Automation, orchestration, jobs, agents | `workflow-automation`, `inngest`, `trigger-dev` |
|
||||
|
||||
## Curated Collections
|
||||
|
||||
[Check out our Starter Packs in docs/BUNDLES.md](docs/BUNDLES.md) to find the perfect toolkit for your role.
|
||||
|
||||
## Browse 614+ Skills
|
||||
## Browse 626+ Skills
|
||||
|
||||
We have moved the full skill registry to a dedicated catalog to keep this README clean.
|
||||
|
||||
@@ -132,7 +139,7 @@ We have moved the full skill registry to a dedicated catalog to keep this README
|
||||
|
||||
## Installation
|
||||
|
||||
To use these skills with **Claude Code**, **Gemini CLI**, **Codex CLI**, **Cursor**, **Antigravity**, or **OpenCode**:
|
||||
To use these skills with **Claude Code**, **Gemini CLI**, **Codex CLI**, **Cursor**, **Antigravity**, **OpenCode**, or **AdaL**:
|
||||
|
||||
### Option A: npx (recommended)
|
||||
|
||||
@@ -149,12 +156,20 @@ npx antigravity-awesome-skills --claude
|
||||
# Gemini CLI
|
||||
npx antigravity-awesome-skills --gemini
|
||||
|
||||
# Codex CLI
|
||||
npx antigravity-awesome-skills --codex
|
||||
|
||||
# OpenCode (Universal)
|
||||
npx antigravity-awesome-skills
|
||||
|
||||
# Custom path
|
||||
npx antigravity-awesome-skills --path ./my-skills
|
||||
```
|
||||
|
||||
Run `npx antigravity-awesome-skills --help` for all options. If the directory already exists, the installer runs `git pull` to update.
|
||||
|
||||
> **If you see a 404 error:** the package may not be published to npm yet. Use: `npx github:sickn33/antigravity-awesome-skills`
|
||||
|
||||
### Option B: git clone
|
||||
|
||||
```bash
|
||||
@@ -167,8 +182,14 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .claude/skil
|
||||
# Gemini CLI specific
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .gemini/skills
|
||||
|
||||
# Codex CLI specific
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .codex/skills
|
||||
|
||||
# Cursor specific
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .cursor/skills
|
||||
|
||||
# OpenCode specific (Universal path)
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
```
|
||||
|
||||
---
|
||||
@@ -223,11 +244,13 @@ This collection would not be possible without the incredible work of the Claude
|
||||
- **[zebbern/claude-code-guide](https://github.com/zebbern/claude-code-guide)**: Comprehensive Security suite & Guide (Source for ~60 new skills).
|
||||
- **[alirezarezvani/claude-skills](https://github.com/alirezarezvani/claude-skills)**: Senior Engineering and PM toolkit.
|
||||
- **[karanb192/awesome-claude-skills](https://github.com/karanb192/awesome-claude-skills)**: A massive list of verified skills for Claude Code.
|
||||
- **[VoltAgent/awesome-agent-skills](https://github.com/VoltAgent/awesome-agent-skills)**: Curated collection of 61 high-quality skills including official team skills from Sentry, Trail of Bits, Expo, Hugging Face, and comprehensive context engineering suite (v4.3.0 integration).
|
||||
- **[zircote/.claude](https://github.com/zircote/.claude)**: Shopify development skill reference.
|
||||
- **[vibeforge1111/vibeship-spawner-skills](https://github.com/vibeforge1111/vibeship-spawner-skills)**: AI Agents, Integrations, Maker Tools (57 skills, Apache 2.0).
|
||||
- **[coreyhaines31/marketingskills](https://github.com/coreyhaines31/marketingskills)**: Marketing skills for CRO, copywriting, SEO, paid ads, and growth (23 skills, MIT).
|
||||
- **[vudovn/antigravity-kit](https://github.com/vudovn/antigravity-kit)**: AI Agent templates with Skills, Agents, and Workflows (33 skills, MIT).
|
||||
- **[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).
|
||||
- **[whatiskadudoing/fp-ts-skills](https://github.com/whatiskadudoing/fp-ts-skills)**: Practical fp-ts skills for TypeScript – fp-ts-pragmatic, fp-ts-react, fp-ts-errors (v4.4.0).
|
||||
- **[webzler/agentMemory](https://github.com/webzler/agentMemory)**: Source for the agent-memory-mcp skill.
|
||||
- **[sstklen/claude-api-cost-optimization](https://github.com/sstklen/claude-api-cost-optimization)**: Save 50-90% on Claude API costs with smart optimization strategies (MIT).
|
||||
|
||||
@@ -265,33 +288,47 @@ ai-developer-tools, ai-pair-programming, vibe-coding, skill, skills, SKILL.md, r
|
||||
|
||||
## Repo Contributors
|
||||
|
||||
<a href="https://github.com/sickn33/antigravity-awesome-skills/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=sickn33/antigravity-awesome-skills" />
|
||||
</a>
|
||||
|
||||
Made with [contrib.rocks](https://contrib.rocks).
|
||||
|
||||
We officially thank the following contributors for their help in making this repository awesome!
|
||||
|
||||
- [mvanhorn](https://github.com/mvanhorn)
|
||||
- [rookie-ricardo](https://github.com/rookie-ricardo)
|
||||
- [sck_0](https://github.com/sck_0)
|
||||
- [Munir Abbasi](https://github.com/munirabbasi)
|
||||
- [Mohammad Faiz](https://github.com/mohdfaiz2k9)
|
||||
- [Ianj332](https://github.com/Ianj332)
|
||||
- [sck_0](https://github.com/sck000)
|
||||
- [Munir Abbasi](https://github.com/munir-abbasi)
|
||||
- [sickn33](https://github.com/sickn33)
|
||||
- [Mohammad Faiz](https://github.com/Mohammad-Faiz-Cloud-Engineer)
|
||||
- [Đỗ Khắc Gia Khoa](https://github.com/Dokhacgiakhoa)
|
||||
- [Ianj332](https://github.com/IanJ332)
|
||||
- [GuppyTheCat](https://github.com/GuppyTheCat)
|
||||
- [Tiger-Foxx](https://github.com/Tiger-Foxx)
|
||||
- [arathiesh](https://github.com/arathiesh)
|
||||
- [1bcMax](https://github.com/1bcMax)
|
||||
- [ALEKGG1](https://github.com/ALEKGG1)
|
||||
- [Ahmed Rehan](https://github.com/ar27111994)
|
||||
- [BenedictKing](https://github.com/BenedictKing)
|
||||
- [whatiskadudoing](https://github.com/whatiskadudoing)
|
||||
- [Nguyen Huu Loc](https://github.com/LocNguyenSGU)
|
||||
- [Owen Wu](https://github.com/yubing744)
|
||||
- [SuperJMN](https://github.com/SuperJMN)
|
||||
- [Truong Nguyen](https://github.com/truongnmt)
|
||||
- [Viktor Ferenczi](https://github.com/viktor-ferenczi)
|
||||
- [Đỗ Khắc Gia Khoa](https://github.com/Dokhacgiakhoa)
|
||||
- [evandro-miguel](https://github.com/evandro-miguel)
|
||||
- [c1c3ru](https://github.com/c1c3ru)
|
||||
- [ckdwns9121](https://github.com/ckdwns9121)
|
||||
- [junited31](https://github.com/junited31)
|
||||
- [krisnasantosa15](https://github.com/krisnasantosa15)
|
||||
- [raeef1001](https://github.com/raeef1001)
|
||||
- [liyin2015](https://github.com/liyin2015)
|
||||
- [krisnasantosa15](https://github.com/KrisnaSantosa15)
|
||||
- [sstklen](https://github.com/sstklen)
|
||||
- [taksrules](https://github.com/taksrules)
|
||||
- [zebbern](https://github.com/zebbern)
|
||||
- [vuth-dogo](https://github.com/vuth-dogo)
|
||||
- [mvanhorn](https://github.com/mvanhorn)
|
||||
- [rookie-ricardo](https://github.com/rookie-ricardo)
|
||||
- [evandro-miguel](https://github.com/evandro-miguel)
|
||||
- [raeef1001](https://github.com/raeef1001)
|
||||
- [devchangjun](https://github.com/devchangjun)
|
||||
|
||||
## Star History
|
||||
|
||||
|
||||
133
RELEASE_NOTES.md
133
RELEASE_NOTES.md
@@ -1,133 +0,0 @@
|
||||
# Release v4.3.0: VoltAgent Integration & Context Engineering Suite
|
||||
|
||||
> **Massive expansion with 61 new skills from VoltAgent repository, including official team skills and comprehensive context engineering capabilities**
|
||||
|
||||
This release adds 61 high-quality skills sourced from the VoltAgent/awesome-agent-skills curated collection, bringing the total to 614 skills. Highlights include official skills from Sentry, Trail of Bits, Expo, Hugging Face, and a complete context engineering suite for building sophisticated AI agents.
|
||||
|
||||
## 🚀 New Skills
|
||||
|
||||
### Official Team Skills (27)
|
||||
|
||||
#### Sentry (4)
|
||||
- **[commit](skills/commit/)** – Create commits with best practices following Sentry conventions
|
||||
- **[create-pr](skills/create-pr/)** – Create pull requests with proper descriptions and review guidelines
|
||||
- **[find-bugs](skills/find-bugs/)** – Find and identify bugs in code systematically
|
||||
- **[iterate-pr](skills/iterate-pr/)** – Iterate on pull request feedback efficiently
|
||||
|
||||
#### Trail of Bits (3)
|
||||
- **[culture-index](skills/culture-index/)** – Index and search culture documentation
|
||||
- **[fix-review](skills/fix-review/)** – Verify fix commits address audit findings without new bugs
|
||||
- **[sharp-edges](skills/sharp-edges/)** – Identify error-prone APIs and dangerous configurations
|
||||
|
||||
#### Expo (2)
|
||||
- **[expo-deployment](skills/expo-deployment/)** – Deploy Expo apps to production
|
||||
- **[upgrading-expo](skills/upgrading-expo/)** – Upgrade Expo SDK versions safely
|
||||
|
||||
#### Hugging Face (2)
|
||||
- **[hugging-face-cli](skills/hugging-face-cli/)** – HF Hub CLI for models, datasets, repos, and compute jobs
|
||||
- **[hugging-face-jobs](skills/hugging-face-jobs/)** – Run compute jobs and Python scripts on HF infrastructure
|
||||
|
||||
#### Other Official (16)
|
||||
- **[vercel-deploy-claimable](skills/vercel-deploy-claimable/)** – Deploy projects to Vercel
|
||||
- **[design-md](skills/design-md/)** – Create and manage DESIGN.md files (Google Stitch)
|
||||
- **[using-neon](skills/using-neon/)** – Best practices for Neon Serverless Postgres
|
||||
- **[n8n-code-python](skills/n8n-code-python/)** – Python in n8n Code nodes
|
||||
- **[n8n-mcp-tools-expert](skills/n8n-mcp-tools-expert/)** – n8n MCP tools guide
|
||||
- **[n8n-node-configuration](skills/n8n-node-configuration/)** – n8n node configuration
|
||||
- **[swiftui-expert-skill](skills/swiftui-expert-skill/)** – SwiftUI best practices
|
||||
- **[fal-audio](skills/fal-audio/)** – Text-to-speech and speech-to-text using fal.ai
|
||||
- **[fal-generate](skills/fal-generate/)** – Generate images and videos using fal.ai AI models
|
||||
- **[fal-image-edit](skills/fal-image-edit/)** – AI-powered image editing with style transfer
|
||||
- **[fal-platform](skills/fal-platform/)** – Platform APIs for model management and usage tracking
|
||||
- **[fal-upscale](skills/fal-upscale/)** – Upscale and enhance image/video resolution using AI
|
||||
- **[fal-workflow](skills/fal-workflow/)** – Generate workflow JSON files for chaining AI models
|
||||
- **[deep-research](skills/deep-research/)** – Gemini Deep Research Agent for autonomous research
|
||||
- **[imagen](skills/imagen/)** – Generate images using Google Gemini
|
||||
- **[readme](skills/readme/)** – Generate comprehensive project documentation
|
||||
|
||||
### Community Skills (34)
|
||||
|
||||
#### Context Engineering Suite (7)
|
||||
A complete suite for building sophisticated AI agents with advanced context management:
|
||||
|
||||
- **[context-fundamentals](skills/context-fundamentals/)** – Understand what context is, why it matters, and the anatomy of context in agent systems
|
||||
- **[context-degradation](skills/context-degradation/)** – Recognize patterns of context failure: lost-in-middle, poisoning, distraction, and clash
|
||||
- **[context-compression](skills/context-compression/)** – Design and evaluate compression strategies for long-running sessions
|
||||
- **[context-optimization](skills/context-optimization/)** – Apply compaction, masking, and caching strategies
|
||||
- **[multi-agent-patterns](skills/multi-agent-patterns/)** – Master orchestrator, peer-to-peer, and hierarchical multi-agent architectures
|
||||
- **[memory-systems](skills/memory-systems/)** – Design short-term, long-term, and graph-based memory architectures
|
||||
- **[evaluation](skills/evaluation/)** – Build evaluation frameworks for agent systems
|
||||
|
||||
#### Development Tools (8)
|
||||
- **[frontend-slides](skills/frontend-slides/)** – Generate animation-rich HTML presentations with visual style previews
|
||||
- **[linear-claude-skill](skills/linear-claude-skill/)** – Manage Linear issues, projects, and teams
|
||||
- **[skill-rails-upgrade](skills/skill-rails-upgrade/)** – Analyze Rails apps and provide upgrade assessments
|
||||
- **[terraform-skill](skills/terraform-skill/)** – Terraform infrastructure as code best practices
|
||||
- **[tool-design](skills/tool-design/)** – Build tools that agents can use effectively, including architectural reduction patterns
|
||||
- **[screenshots](skills/screenshots/)** – Generate marketing screenshots with Playwright
|
||||
- **[automate-whatsapp](skills/automate-whatsapp/)** – Build WhatsApp automations with workflows and agents
|
||||
- **[observe-whatsapp](skills/observe-whatsapp/)** – Debug WhatsApp delivery issues and run health checks
|
||||
|
||||
#### Platform & Framework Skills (19)
|
||||
- **[aws-skills](skills/aws-skills/)** – AWS development with infrastructure automation
|
||||
- **[ui-skills](skills/ui-skills/)** – Opinionated constraints for building interfaces
|
||||
- **[vexor](skills/vexor/)** – Vector-powered CLI for semantic file search
|
||||
- **[pypict-skill](skills/pypict-skill/)** – Pairwise test generation
|
||||
- **[makepad-skills](skills/makepad-skills/)** – Makepad UI development for Rust apps
|
||||
- **[threejs-skills](skills/threejs-skills/)** – Three.js 3D experiences
|
||||
- **[claude-scientific-skills](skills/claude-scientific-skills/)** – Scientific research skills
|
||||
- **[claude-win11-speckit-update-skill](skills/claude-win11-speckit-update-skill/)** – Windows 11 management
|
||||
- **[security-bluebook-builder](skills/security-bluebook-builder/)** – Security documentation
|
||||
- **[claude-ally-health](skills/claude-ally-health/)** – Health assistant
|
||||
- **[clarity-gate](skills/clarity-gate/)** – RAG quality verification
|
||||
- **[beautiful-prose](skills/beautiful-prose/)** – Writing style guide
|
||||
- **[claude-speed-reader](skills/claude-speed-reader/)** – Speed reading tool
|
||||
- **[skill-seekers](skills/skill-seekers/)** – Skill conversion tool
|
||||
- **[varlock-claude-skill](skills/varlock-claude-skill/)** – Secure environment variable management
|
||||
- **[superpowers-lab](skills/superpowers-lab/)** – Superpowers Lab integration
|
||||
- **[nanobanana-ppt-skills](skills/nanobanana-ppt-skills/)** – PowerPoint presentation skills
|
||||
- **[x-article-publisher-skill](skills/x-article-publisher-skill/)** – X/Twitter article publishing
|
||||
- **[ffuf-claude-skill](skills/ffuf-claude-skill/)** – Web fuzzing with ffuf
|
||||
|
||||
---
|
||||
|
||||
## 📦 Registry Update
|
||||
|
||||
- **Total Skills**: 614 (from 553)
|
||||
- **New Skills Added**: 61
|
||||
- **Catalog**: Fully regenerated with all new skills
|
||||
- **Sources**: All skills properly attributed in `docs/SOURCES.md`
|
||||
|
||||
## 🔧 Improvements
|
||||
|
||||
### Quality Assurance
|
||||
- All new skills validated for frontmatter compliance
|
||||
- "When to Use" sections added where missing
|
||||
- Source attribution maintained for all skills
|
||||
- Risk labels properly set
|
||||
|
||||
### Documentation
|
||||
- Updated README.md with correct skill count (614)
|
||||
- Updated package.json version to 4.3.0
|
||||
- Comprehensive release notes created
|
||||
|
||||
## 📊 Statistics
|
||||
|
||||
- **Skills from VoltAgent Repository**: 61
|
||||
- Official Team Skills: 27
|
||||
- Community Skills: 34
|
||||
- **Skills Analyzed**: 174 total from VoltAgent
|
||||
- **Skills Already Present**: 32 (skipped as duplicates)
|
||||
- **Skills with Similar Names**: 89 (analyzed, 12 implemented as complementary)
|
||||
|
||||
## 👥 Credits
|
||||
|
||||
A huge shoutout to our community contributors and the VoltAgent team:
|
||||
|
||||
- **VoltAgent/awesome-agent-skills** for curating an excellent collection
|
||||
- **Official Teams**: Sentry, Trail of Bits, Expo, Hugging Face, Vercel Labs, Google Labs, Neon, fal.ai
|
||||
- **Community Contributors**: zarazhangrui, wrsmith108, robzolkos, muratcankoylan, antonbabenko, and all other skill authors
|
||||
|
||||
---
|
||||
|
||||
_Upgrade now: `git pull origin main` to fetch the latest skills._
|
||||
@@ -1,186 +0,0 @@
|
||||
# Analisi delle 65 Skills con Nomi Simili
|
||||
|
||||
**Data**: 2026-01-30
|
||||
**Skills Analizzate**: 89 totali (di cui 49 già implementate)
|
||||
**Rimanenti da Analizzare**: 40 skills
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Delle 89 skills con nomi simili identificate inizialmente:
|
||||
- ✅ **49 già implementate** (dalle 24 convertite da HTML + 25 altre)
|
||||
- ❌ **2 duplicate** (già esistono nella repository)
|
||||
- ⚠️ **13 necessitano revisione** (hanno fonti valide, potrebbero essere nuove o duplicate)
|
||||
- ❌ **74 hanno fonti non valide** (URL non accessibili o SKILL.md non trovato)
|
||||
|
||||
## Skills Duplicate (2)
|
||||
|
||||
Queste skills **NON devono essere aggiunte** perché esistono già nella repository:
|
||||
|
||||
1. **`react-best-practices`** (vercel-labs)
|
||||
- Esiste già: `skills/react-best-practices/` o simile
|
||||
- URL: https://github.com/vercel-labs/agent-skills/tree/main/skills/react-best-practices
|
||||
|
||||
2. **`postgres-best-practices`** (supabase)
|
||||
- Esiste già: `skills/postgres-best-practices/` o `skills/supabase-postgres-best-practices/`
|
||||
- URL: https://github.com/supabase/agent-skills/tree/main/skills/supabase-postgres-best-practices
|
||||
|
||||
## Skills che Necessitano Revisione (13)
|
||||
|
||||
Queste skills hanno **fonti valide** (SKILL.md accessibile) ma richiedono una valutazione manuale per determinare se sono:
|
||||
- **Nuove e complementari** → Da aggiungere
|
||||
- **Duplicate** → Da scartare
|
||||
|
||||
### 1. Skills Potenzialmente Duplicate (da verificare)
|
||||
|
||||
#### `notebooklm-skill` (PleasePrompto)
|
||||
- **Descrizione**: Interact with NotebookLM for document-based conversations
|
||||
- **URL**: https://github.com/PleasePrompto/notebooklm-skill
|
||||
- **Raw URL**: https://github.com/PleasePrompto/notebooklm-skill/raw/master/SKILL.md
|
||||
- **Skills simili esistenti**: `notebooklm`
|
||||
- **Raccomandazione**: ⚠️ **Verificare** se è diverso da `notebooklm` esistente. Se è solo una versione alternativa, scartare.
|
||||
|
||||
#### `evaluation` (muratcankoylan)
|
||||
- **Descrizione**: Build evaluation frameworks for agent systems
|
||||
- **URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/evaluation
|
||||
- **Raw URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md
|
||||
- **Skills simili esistenti**: `agent-evaluation`, `llm-evaluation`
|
||||
- **Raccomandazione**: ⚠️ **Verificare** se è complementare o duplicato. Se copre solo evaluation generale, potrebbe essere duplicato.
|
||||
|
||||
#### `memory-systems` (muratcankoylan)
|
||||
- **Descrizione**: Design short-term, long-term, and graph-based memory architectures
|
||||
- **URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/memory-systems
|
||||
- **Raw URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md
|
||||
- **Skills simili esistenti**: `agent-memory-systems`
|
||||
- **Raccomandazione**: ⚠️ **Verificare** se è complementare o duplicato. Se è solo un nome alternativo, scartare.
|
||||
|
||||
#### `terraform-skill` (antonbabenko)
|
||||
- **Descrizione**: Terraform infrastructure as code best practices
|
||||
- **URL**: https://github.com/antonbabenko/terraform-skill
|
||||
- **Raw URL**: https://github.com/antonbabenko/terraform-skill/raw/master/SKILL.md
|
||||
- **Skills simili esistenti**: `terraform-specialist`, `terraform-module-library`
|
||||
- **Raccomandazione**: ⚠️ **Verificare** se aggiunge valore rispetto a `terraform-specialist`. Se è solo best practices generiche, potrebbe essere duplicato.
|
||||
|
||||
### 2. Skills Probabilmente Nuove e Complementari (da aggiungere)
|
||||
|
||||
#### `frontend-slides` (zarazhangrui)
|
||||
- **Descrizione**: Generate animation-rich HTML presentations with visual style previews
|
||||
- **URL**: https://github.com/zarazhangrui/frontend-slides
|
||||
- **Raw URL**: https://github.com/zarazhangrui/frontend-slides/raw/main/SKILL.md
|
||||
- **Skills simili esistenti**: `frontend-patterns`, `frontend-design`
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Focus specifico su presentazioni HTML animate, complementare a frontend-design.
|
||||
|
||||
#### `linear-claude-skill` (wrsmith108)
|
||||
- **Descrizione**: Manage Linear issues, projects, and teams
|
||||
- **URL**: https://github.com/wrsmith108/linear-claude-skill
|
||||
- **Raw URL**: https://github.com/wrsmith108/linear-claude-skill/raw/main/SKILL.md
|
||||
- **Skills simili esistenti**: Nessuna skill Linear esistente
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Skill completamente nuova per integrazione Linear.
|
||||
|
||||
#### `skill-rails-upgrade` (robzolkos)
|
||||
- **Descrizione**: Analyze Rails apps and provide upgrade assessments
|
||||
- **URL**: https://github.com/robzolkos/skill-rails-upgrade
|
||||
- **Raw URL**: https://github.com/robzolkos/skill-rails-upgrade/raw/master/SKILL.md
|
||||
- **Skills simili esistenti**: Nessuna skill Rails upgrade esistente
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Skill specifica per upgrade Rails, complementare a `ruby-pro`.
|
||||
|
||||
#### Context Engineering Skills (muratcankoylan) - 4 skills
|
||||
|
||||
Queste 4 skills fanno parte di una suite di Context Engineering e sembrano complementari:
|
||||
|
||||
##### `context-fundamentals`
|
||||
- **Descrizione**: Understand what context is, why it matters, and the anatomy of context in agent systems
|
||||
- **URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-fundamentals
|
||||
- **Raw URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Fondamentali di context engineering, complementare a `context-manager`.
|
||||
|
||||
##### `context-degradation`
|
||||
- **Descrizione**: Recognize patterns of context failure: lost-in-middle, poisoning, distraction, and clash
|
||||
- **URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-degradation
|
||||
- **Raw URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Pattern specifici di degradazione del context, complementare.
|
||||
|
||||
##### `context-compression`
|
||||
- **Descrizione**: Design and evaluate compression strategies for long-running sessions
|
||||
- **URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-compression
|
||||
- **Raw URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Strategie di compressione del context, complementare.
|
||||
|
||||
##### `context-optimization`
|
||||
- **Descrizione**: Apply compaction, masking, and caching strategies
|
||||
- **URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-optimization
|
||||
- **Raw URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Ottimizzazione del context, complementare.
|
||||
|
||||
#### `multi-agent-patterns` (muratcankoylan)
|
||||
- **Descrizione**: Master orchestrator, peer-to-peer, and hierarchical multi-agent architectures
|
||||
- **URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/multi-agent-patterns
|
||||
- **Raw URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md
|
||||
- **Skills simili esistenti**: `agent-manager-skill`, `computer-use-agents`
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Pattern architetturali multi-agent, complementare a `autonomous-agents`.
|
||||
|
||||
#### `tool-design` (muratcankoylan)
|
||||
- **Descrizione**: Build tools that agents can use effectively, including architectural reduction patterns
|
||||
- **URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/tool-design
|
||||
- **Raw URL**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md
|
||||
- **Skills simili esistenti**: Nessuna skill tool-design esistente
|
||||
- **Raccomandazione**: ✅ **Aggiungere** - Design di tool per agenti, complementare a `agent-tool-builder`.
|
||||
|
||||
## Skills con Fonti Non Valide (74)
|
||||
|
||||
Queste skills hanno **URL non accessibili** o **SKILL.md non trovato**. Non possono essere implementate senza accesso al contenuto.
|
||||
|
||||
### Categorie di Skills Non Valide
|
||||
|
||||
#### Official Team Skills (molte da Cloudflare, Hugging Face, Stripe, Trail of Bits, Expo, Sentry)
|
||||
- Skills ufficiali di team che potrebbero non avere SKILL.md pubblici o potrebbero essere in percorsi diversi
|
||||
- Esempi: `building-ai-agent-on-cloudflare`, `hugging-face-datasets`, `stripe-best-practices`, `burpsuite-project-parser`, etc.
|
||||
|
||||
#### Community Skills
|
||||
- Skills della community con URL non validi o repository non più disponibili
|
||||
|
||||
**Raccomandazione**: ⏸️ **Non implementare** senza accesso al contenuto. Se necessario, contattare i maintainer o verificare manualmente i repository.
|
||||
|
||||
## Raccomandazioni Finali
|
||||
|
||||
### ✅ Da Implementare (9 skills)
|
||||
|
||||
1. `frontend-slides` - Presentazioni HTML animate
|
||||
2. `linear-claude-skill` - Integrazione Linear
|
||||
3. `skill-rails-upgrade` - Upgrade Rails
|
||||
4. `context-fundamentals` - Fondamentali context engineering
|
||||
5. `context-degradation` - Pattern di degradazione context
|
||||
6. `context-compression` - Compressione context
|
||||
7. `context-optimization` - Ottimizzazione context
|
||||
8. `multi-agent-patterns` - Pattern multi-agent
|
||||
9. `tool-design` - Design tool per agenti
|
||||
|
||||
### ⚠️ Da Verificare Manualmente (4 skills)
|
||||
|
||||
1. `notebooklm-skill` - Verificare se diverso da `notebooklm` esistente
|
||||
2. `evaluation` - Verificare se complementare a `agent-evaluation`/`llm-evaluation`
|
||||
3. `memory-systems` - Verificare se diverso da `agent-memory-systems`
|
||||
4. `terraform-skill` - Verificare se aggiunge valore rispetto a `terraform-specialist`
|
||||
|
||||
### ❌ Da Scartare (2 skills)
|
||||
|
||||
1. `react-best-practices` - Duplicato
|
||||
2. `postgres-best-practices` - Duplicato
|
||||
|
||||
### ⏸️ Non Implementabili (74 skills)
|
||||
|
||||
Skills con fonti non valide - richiederebbero accesso manuale ai repository o contatto con i maintainer.
|
||||
|
||||
## Prossimi Passi
|
||||
|
||||
1. **Implementare le 9 skills raccomandate** seguendo il processo standard
|
||||
2. **Verificare manualmente le 4 skills** confrontando con quelle esistenti
|
||||
3. **Scartare le 2 duplicate**
|
||||
4. **Documentare le 74 skills non valide** per riferimento futuro
|
||||
|
||||
## Statistiche Finali
|
||||
|
||||
- **Total skills analizzate**: 89
|
||||
- **Già implementate**: 49
|
||||
- **Nuove da aggiungere**: 9-13 (dipende dalla verifica manuale)
|
||||
- **Duplicate**: 2
|
||||
- **Non implementabili**: 74
|
||||
@@ -1,158 +0,0 @@
|
||||
# Report Implementazione Skills con Nomi Simili
|
||||
|
||||
**Data**: 2026-01-30
|
||||
**Skills Implementate**: 12
|
||||
**Status**: ✅ Completato con Successo
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Successfully implemented **12 new skills** from the similar skills analysis:
|
||||
- 9 skills raccomandate come nuove e complementari
|
||||
- 3 skills verificate manualmente come complementari (evaluation, memory-systems, terraform-skill)
|
||||
- 1 skill duplicata scartata (notebooklm-skill - identica a notebooklm esistente)
|
||||
|
||||
## Skills Implementate
|
||||
|
||||
### 1. frontend-slides (zarazhangrui)
|
||||
- **Descrizione**: Generate animation-rich HTML presentations with visual style previews
|
||||
- **Source**: https://github.com/zarazhangrui/frontend-slides
|
||||
- **Categoria**: Community Skills
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
### 2. linear-claude-skill (wrsmith108)
|
||||
- **Descrizione**: Manage Linear issues, projects, and teams
|
||||
- **Source**: https://github.com/wrsmith108/linear-claude-skill
|
||||
- **Categoria**: Community Skills
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
### 3. skill-rails-upgrade (robzolkos)
|
||||
- **Descrizione**: Analyze Rails apps and provide upgrade assessments
|
||||
- **Source**: https://github.com/robzolkos/skill-rails-upgrade
|
||||
- **Categoria**: Community Skills
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
### 4-7. Context Engineering Skills (muratcankoylan)
|
||||
Quattro skills complementari per context engineering:
|
||||
|
||||
#### context-fundamentals
|
||||
- **Descrizione**: Understand what context is, why it matters, and the anatomy of context in agent systems
|
||||
- **Source**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
#### context-degradation
|
||||
- **Descrizione**: Recognize patterns of context failure: lost-in-middle, poisoning, distraction, and clash
|
||||
- **Source**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
#### context-compression
|
||||
- **Descrizione**: Design and evaluate compression strategies for long-running sessions
|
||||
- **Source**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
#### context-optimization
|
||||
- **Descrizione**: Apply compaction, masking, and caching strategies
|
||||
- **Source**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
### 8. multi-agent-patterns (muratcankoylan)
|
||||
- **Descrizione**: Master orchestrator, peer-to-peer, and hierarchical multi-agent architectures
|
||||
- **Source**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering
|
||||
- **Categoria**: Community Skills
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
### 9. tool-design (muratcankoylan)
|
||||
- **Descrizione**: Build tools that agents can use effectively, including architectural reduction patterns
|
||||
- **Source**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering
|
||||
- **Categoria**: Community Skills
|
||||
- **Status**: ✅ Implementata
|
||||
|
||||
### 10. evaluation (muratcankoylan) - Verificata
|
||||
- **Descrizione**: Build evaluation frameworks for agent systems
|
||||
- **Source**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering
|
||||
- **Categoria**: Community Skills
|
||||
- **Status**: ✅ Implementata (complementare a agent-evaluation e llm-evaluation)
|
||||
|
||||
### 11. memory-systems (muratcankoylan) - Verificata
|
||||
- **Descrizione**: Design short-term, long-term, and graph-based memory architectures
|
||||
- **Source**: https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering
|
||||
- **Categoria**: Community Skills
|
||||
- **Status**: ✅ Implementata (complementare a agent-memory-systems)
|
||||
|
||||
### 12. terraform-skill (antonbabenko) - Verificata
|
||||
- **Descrizione**: Terraform infrastructure as code best practices
|
||||
- **Source**: https://github.com/antonbabenko/terraform-skill
|
||||
- **Categoria**: Community Skills
|
||||
- **Status**: ✅ Implementata (complementare a terraform-specialist)
|
||||
|
||||
## Skills Scartate
|
||||
|
||||
### notebooklm-skill (PleasePrompto) - Duplicato
|
||||
- **Motivo**: Identica a `notebooklm` esistente nella repository
|
||||
- **Confronto**: Stesso contenuto, stesso frontmatter name, stessa funzionalità
|
||||
- **Decisione**: ❌ Scartata come duplicato
|
||||
|
||||
## Processo di Implementazione
|
||||
|
||||
### Fase 1: Verifica Manuale delle Skills Incerte
|
||||
- Verificate 4 skills che necessitavano revisione manuale
|
||||
- `notebooklm-skill`: Identificata come duplicato esatto
|
||||
- `evaluation`: Verificata come complementare (più generale di agent-evaluation/llm-evaluation)
|
||||
- `memory-systems`: Verificata come complementare (più dettagliata di agent-memory-systems)
|
||||
- `terraform-skill`: Verificata come complementare (più pratica di terraform-specialist)
|
||||
|
||||
### Fase 2: Download e Implementazione
|
||||
- Creato script `scripts/implement_similar_skills.py` per automatizzare il processo
|
||||
- Download di SKILL.md da repository GitHub
|
||||
- Verifica compliance con frontmatter standard
|
||||
- Aggiunta sezione "When to Use" dove mancante
|
||||
- Gestione speciale per `frontend-slides` (download manuale con curl)
|
||||
|
||||
### Fase 3: Validazione
|
||||
- Tutte le 12 skills passano la validazione di compliance
|
||||
- Frontmatter completo con: name, description, source, risk
|
||||
- Sezione "When to Use" presente in tutte
|
||||
- Contenuto markdown pulito (nessun HTML)
|
||||
|
||||
### Fase 4: Aggiornamento Cataloghi
|
||||
- Aggiornato `data/catalog.json`: 614 skills totali (da 602)
|
||||
- Aggiornato `data/skills_index.json`
|
||||
- Aggiornato `CATALOG.md`
|
||||
- Aggiornato `docs/SOURCES.md` con attribuzioni
|
||||
|
||||
## Statistiche Finali
|
||||
|
||||
- **Total skills analizzate**: 89 (con nomi simili)
|
||||
- **Skills già implementate**: 49 (dalla fase precedente)
|
||||
- **Skills duplicate scartate**: 3 (react-best-practices, postgres-best-practices, notebooklm-skill)
|
||||
- **Skills nuove implementate**: 12
|
||||
- **Skills con fonti non valide**: 74 (non implementabili)
|
||||
|
||||
## Totale Skills Nuove da VoltAgent
|
||||
|
||||
- **Fase precedente**: 49 skills implementate
|
||||
- **Fase corrente**: 12 skills implementate
|
||||
- **TOTALE**: **61 skills nuove** aggiunte dalla repository VoltAgent
|
||||
|
||||
## Qualità e Compliance
|
||||
|
||||
Tutte le 12 skills implementate:
|
||||
- ✅ Frontmatter completo e corretto
|
||||
- ✅ Sezione "When to Use" presente
|
||||
- ✅ Source attribution corretta
|
||||
- ✅ Risk level impostato
|
||||
- ✅ Contenuto markdown pulito
|
||||
- ✅ Nome corrisponde al nome della cartella
|
||||
|
||||
## Prossimi Passi
|
||||
|
||||
1. ✅ Tutte le skills implementate
|
||||
2. ✅ Cataloghi aggiornati
|
||||
3. ✅ Attribuzioni aggiunte
|
||||
4. ⏳ Pronto per commit e push (in attesa di approvazione utente)
|
||||
|
||||
## Note Tecniche
|
||||
|
||||
- `frontend-slides` ha richiesto download manuale con curl a causa di problemi con lo script Python
|
||||
- Tutte le altre skills sono state scaricate automaticamente dallo script
|
||||
- Le skills di Context Engineering (muratcankoylan) sono parte di una suite coerente
|
||||
- Le skills verificate manualmente sono risultate complementari, non duplicate
|
||||
@@ -1,215 +0,0 @@
|
||||
# VoltAgent Skills Sync Report
|
||||
|
||||
**Date**: 2026-01-30
|
||||
**Source Repository**: [VoltAgent/awesome-agent-skills](https://github.com/VoltAgent/awesome-agent-skills)
|
||||
**Target Repository**: antigravity-awesome-skills
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Successfully analyzed the VoltAgent/awesome-agent-skills repository and implemented **49 new validated skills** into the antigravity-awesome-skills collection.
|
||||
|
||||
### Statistics
|
||||
|
||||
- **Total skills analyzed**: 174
|
||||
- **Skills already present**: 32
|
||||
- **New skills identified**: 53
|
||||
- **Skills validated**: 49
|
||||
- **Skills implemented**: 49
|
||||
- **Skills failed validation**: 4
|
||||
- **Skills with similar names** (potential duplicates): 89
|
||||
|
||||
## Implementation Process
|
||||
|
||||
### Phase 1: Analysis ✅
|
||||
|
||||
Created `scripts/analyze_voltagent_repo.py` to:
|
||||
- Fetch and parse the VoltAgent README.md
|
||||
- Extract all skill references (format: `**[org/skill-name](url)**`)
|
||||
- Normalize skill names to kebab-case
|
||||
- Compare with existing skills in `data/catalog.json`
|
||||
|
||||
**Result**: Identified 53 new skills not present in the current collection.
|
||||
|
||||
### Phase 2: Source Validation ✅
|
||||
|
||||
Created `scripts/validate_voltagent_sources.py` to:
|
||||
- Verify GitHub URL accessibility
|
||||
- Check for SKILL.md file presence
|
||||
- Validate license compatibility
|
||||
- Identify official vs community skills
|
||||
|
||||
**Result**:
|
||||
- ✅ 49 skills validated successfully
|
||||
- ❌ 4 skills failed (URL 404 errors)
|
||||
|
||||
### Phase 3: Implementation ✅
|
||||
|
||||
Created `scripts/implement_voltagent_skills.py` to:
|
||||
- Download SKILL.md files from GitHub repositories
|
||||
- Ensure frontmatter compliance (name, description, source, risk)
|
||||
- Add "When to Use" sections where missing
|
||||
- Create minimal SKILL.md for skills without downloadable files
|
||||
|
||||
**Result**: All 49 validated skills successfully implemented.
|
||||
|
||||
### Phase 4: Catalog Update ✅
|
||||
|
||||
- Updated `data/skills_index.json`: 609 skills total
|
||||
- Updated `data/catalog.json`: 602 skills total
|
||||
- Updated `CATALOG.md`: Regenerated catalog documentation
|
||||
- Updated `docs/SOURCES.md`: Added attributions for all new skills
|
||||
|
||||
## Implemented Skills
|
||||
|
||||
### Official Team Skills (27)
|
||||
|
||||
#### Vercel Labs (1)
|
||||
- `vercel-deploy-claimable` - Deploy projects to Vercel
|
||||
|
||||
#### Google Labs / Stitch (1)
|
||||
- `design-md` - Create and manage DESIGN.md files
|
||||
|
||||
#### Hugging Face (2)
|
||||
- `hugging-face-cli` - HF Hub CLI for models, datasets, repos, and compute jobs
|
||||
- `hugging-face-jobs` - Run compute jobs and Python scripts on HF infrastructure
|
||||
|
||||
#### Trail of Bits (3)
|
||||
- `culture-index` - Index and search culture documentation
|
||||
- `fix-review` - Verify fix commits address audit findings without new bugs
|
||||
- `sharp-edges` - Identify error-prone APIs and dangerous configurations
|
||||
|
||||
#### Expo (2)
|
||||
- `expo-deployment` - Deploy Expo apps to production
|
||||
- `upgrading-expo` - Upgrade Expo SDK versions
|
||||
|
||||
#### Sentry (4)
|
||||
- `commit` - Create commits with best practices
|
||||
- `create-pr` - Create pull requests
|
||||
- `find-bugs` - Find and identify bugs in code
|
||||
- `iterate-pr` - Iterate on pull request feedback
|
||||
|
||||
#### Neon (1)
|
||||
- `using-neon` - Best practices for Neon Serverless Postgres
|
||||
|
||||
#### fal.ai Community (6)
|
||||
- `fal-audio` - Text-to-speech and speech-to-text using fal.ai audio models
|
||||
- `fal-generate` - Generate images and videos using fal.ai AI models
|
||||
- `fal-image-edit` - AI-powered image editing with style transfer and object removal
|
||||
- `fal-platform` - Platform APIs for model management, pricing, and usage tracking
|
||||
- `fal-upscale` - Upscale and enhance image and video resolution using AI
|
||||
- `fal-workflow` - Generate workflow JSON files for chaining AI models
|
||||
|
||||
### Community Skills (22)
|
||||
|
||||
#### WhatsApp Automation (2)
|
||||
- `automate-whatsapp` - Build WhatsApp automations with workflows and agents
|
||||
- `observe-whatsapp` - Debug WhatsApp delivery issues and run health checks
|
||||
|
||||
#### Development Tools (8)
|
||||
- `readme` - Generate comprehensive project documentation
|
||||
- `screenshots` - Generate marketing screenshots with Playwright
|
||||
- `aws-skills` - AWS development with infrastructure automation and cloud architecture patterns
|
||||
- `deep-research` - Autonomous multi-step research using Gemini Deep Research Agent
|
||||
- `ffuf-claude-skill` - Web fuzzing with ffuf
|
||||
- `ui-skills` - Opinionated, evolving constraints to guide agents when building interfaces
|
||||
- `vexor` - Vector-powered CLI for semantic file search
|
||||
- `pypict-skill` - Pairwise test generation
|
||||
|
||||
#### Platform-Specific (3)
|
||||
- `makepad-skills` - Makepad UI development skills for Rust apps
|
||||
- `swiftui-expert-skill` - Modern SwiftUI best practices and iOS 26+ Liquid Glass adoption
|
||||
- `threejs-skills` - Three.js skills for creating 3D elements and interactive experiences
|
||||
|
||||
#### Specialized Domains (9)
|
||||
- `claude-scientific-skills` - Scientific research and analysis skills
|
||||
- `claude-win11-speckit-update-skill` - Windows 11 system management
|
||||
- `imagen` - Generate images using Google Gemini's API
|
||||
- `security-bluebook-builder` - Build security Blue Books for sensitive apps
|
||||
- `claude-ally-health` - Health assistant skill for medical information analysis
|
||||
- `clarity-gate` - Pre-ingestion verification for epistemic quality in RAG systems
|
||||
- `n8n-code-python` - Python coding in n8n Code nodes with limitations
|
||||
- `n8n-mcp-tools-expert` - MCP tools guide with tool selection and node formats
|
||||
- `n8n-node-configuration` - Node configuration with dependency rules and AI connections
|
||||
|
||||
#### Utilities (3)
|
||||
- `varlock-claude-skill` - Secure environment variable management
|
||||
- `beautiful-prose` - Hard-edged writing style contract for timeless, forceful English prose
|
||||
- `claude-speed-reader` - Speed read Claude's responses at 600+ WPM using RSVP
|
||||
- `skill-seekers` - Automatically convert documentation websites, GitHub repositories, and PDFs into Claude AI skills
|
||||
|
||||
## Failed Validations
|
||||
|
||||
The following skills failed validation due to inaccessible URLs (HTTP 404):
|
||||
|
||||
1. `agents-sdk` (cloudflare) - URL not accessible
|
||||
2. `wrangler` (cloudflare) - URL not accessible
|
||||
3. `claudisms` (jeffersonwarrior) - URL not accessible
|
||||
4. `defense-in-depth` (obra) - URL not accessible
|
||||
|
||||
**Note**: These skills may be available at different URLs or may have been moved/removed from their original repositories.
|
||||
|
||||
## Skills with Similar Names
|
||||
|
||||
89 skills were identified with similar names to existing skills. These were flagged for manual review to avoid duplicates:
|
||||
|
||||
- `template` (similar to: defi-protocol-templates, documentation-templates)
|
||||
- `react-best-practices` (similar to: vercel-react-best-practices)
|
||||
- `react-native-skills` (similar to: various React Native skills)
|
||||
- `postgres-best-practices` (similar to: postgresql, postgres-best-practices)
|
||||
- And 85 more...
|
||||
|
||||
**Action**: These require manual review to determine if they are duplicates or complementary skills.
|
||||
|
||||
## Quality Assurance
|
||||
|
||||
### Validation Status
|
||||
|
||||
All implemented skills include:
|
||||
- ✅ Valid YAML frontmatter with required fields (name, description, source, risk)
|
||||
- ✅ "When to Use" section
|
||||
- ✅ Proper attribution to source repositories
|
||||
- ✅ Risk level classification (default: safe)
|
||||
|
||||
### Known Issues
|
||||
|
||||
Some skills were downloaded with HTML content instead of markdown due to GitHub URL structure. These files have:
|
||||
- ✅ Correct frontmatter
|
||||
- ✅ "When to Use" section
|
||||
- ⚠️ HTML content that may need manual cleanup
|
||||
|
||||
**Affected skills**: Skills from fal.ai community and some community repositories.
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
### Scripts Created
|
||||
- `scripts/analyze_voltagent_repo.py` - Analysis script
|
||||
- `scripts/validate_voltagent_sources.py` - Source validation script
|
||||
- `scripts/implement_voltagent_skills.py` - Implementation script
|
||||
|
||||
### Data Files Updated
|
||||
- `data/catalog.json` - Updated with new skills
|
||||
- `data/skills_index.json` - Updated index
|
||||
- `CATALOG.md` - Regenerated catalog
|
||||
- `docs/SOURCES.md` - Added attributions
|
||||
|
||||
### Analysis Files Generated
|
||||
- `voltagent_analysis.json` - Detailed analysis results
|
||||
- `voltagent_validation.json` - Validation results
|
||||
|
||||
### Skills Added
|
||||
49 new skill directories in `skills/`:
|
||||
- See "Implemented Skills" section above for complete list
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Manual Review**: Review skills with similar names to identify duplicates
|
||||
2. **Content Cleanup**: Clean up HTML content in skills that were downloaded incorrectly
|
||||
3. **Testing**: Test new skills to ensure they work correctly
|
||||
4. **Documentation**: Update any additional documentation as needed
|
||||
5. **Follow-up**: Monitor for updates to failed validations (agents-sdk, wrangler, etc.)
|
||||
|
||||
## Conclusion
|
||||
|
||||
Successfully integrated 49 new high-quality skills from the VoltAgent curated collection, significantly expanding the antigravity-awesome-skills repository. All skills follow the V4 Quality Bar standards and are properly attributed to their original sources.
|
||||
|
||||
The collection now includes skills from major development teams (Vercel, Google, Hugging Face, Trail of Bits, Expo, Sentry, Neon) as well as valuable community contributions, making it an even more comprehensive resource for AI coding assistants.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 50 KiB |
@@ -16,18 +16,23 @@ function resolveDir(p) {
|
||||
function parseArgs() {
|
||||
const a = process.argv.slice(2);
|
||||
let pathArg = null;
|
||||
let cursor = false, claude = false, gemini = false;
|
||||
let versionArg = null;
|
||||
let tagArg = null;
|
||||
let cursor = false, claude = false, gemini = false, codex = false;
|
||||
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (a[i] === '--help' || a[i] === '-h') return { help: true };
|
||||
if (a[i] === '--path' && a[i + 1]) { pathArg = a[++i]; continue; }
|
||||
if (a[i] === '--version' && a[i + 1]) { versionArg = a[++i]; continue; }
|
||||
if (a[i] === '--tag' && a[i + 1]) { tagArg = a[++i]; continue; }
|
||||
if (a[i] === '--cursor') { cursor = true; continue; }
|
||||
if (a[i] === '--claude') { claude = true; continue; }
|
||||
if (a[i] === '--gemini') { gemini = true; continue; }
|
||||
if (a[i] === '--codex') { codex = true; continue; }
|
||||
if (a[i] === 'install') continue;
|
||||
}
|
||||
|
||||
return { pathArg, cursor, claude, gemini };
|
||||
return { pathArg, versionArg, tagArg, cursor, claude, gemini, codex };
|
||||
}
|
||||
|
||||
function defaultDir(opts) {
|
||||
@@ -35,6 +40,11 @@ function defaultDir(opts) {
|
||||
if (opts.cursor) return path.join(HOME, '.cursor', 'skills');
|
||||
if (opts.claude) return path.join(HOME, '.claude', 'skills');
|
||||
if (opts.gemini) return path.join(HOME, '.gemini', 'skills');
|
||||
if (opts.codex) {
|
||||
const codexHome = process.env.CODEX_HOME;
|
||||
if (codexHome) return path.join(codexHome, 'skills');
|
||||
return path.join(HOME, '.codex', 'skills');
|
||||
}
|
||||
return path.join(HOME, '.agent', 'skills');
|
||||
}
|
||||
|
||||
@@ -50,11 +60,15 @@ Options:
|
||||
--cursor Install to ~/.cursor/skills (Cursor)
|
||||
--claude Install to ~/.claude/skills (Claude Code)
|
||||
--gemini Install to ~/.gemini/skills (Gemini CLI)
|
||||
--codex Install to ~/.codex/skills (Codex CLI)
|
||||
--path <dir> Install to <dir> (default: ~/.agent/skills)
|
||||
--version <ver> After clone, checkout tag v<ver> (e.g. 4.6.0 -> v4.6.0)
|
||||
--tag <tag> After clone, checkout this tag (e.g. v4.6.0)
|
||||
|
||||
Examples:
|
||||
npx antigravity-awesome-skills
|
||||
npx antigravity-awesome-skills --cursor
|
||||
npx antigravity-awesome-skills --version 4.6.0
|
||||
npx antigravity-awesome-skills --path ./my-skills
|
||||
`);
|
||||
}
|
||||
@@ -66,6 +80,8 @@ function run(cmd, args, opts = {}) {
|
||||
|
||||
function main() {
|
||||
const opts = parseArgs();
|
||||
const { tagArg, versionArg } = opts;
|
||||
|
||||
if (opts.help) {
|
||||
printHelp();
|
||||
return;
|
||||
@@ -106,6 +122,13 @@ function main() {
|
||||
run('git', ['clone', REPO, target]);
|
||||
}
|
||||
|
||||
const ref = tagArg || (versionArg ? (versionArg.startsWith('v') ? versionArg : `v${versionArg}`) : null);
|
||||
if (ref) {
|
||||
console.log(`Checking out ${ref}…`);
|
||||
process.chdir(target);
|
||||
run('git', ['checkout', ref]);
|
||||
}
|
||||
|
||||
console.log(`\nInstalled to ${target}`);
|
||||
console.log('Pick a bundle in docs/BUNDLES.md and use @skill-name in your AI assistant.');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generatedAt": "2026-01-30T08:15:03.985Z",
|
||||
"generatedAt": "2026-02-03T08:46:32.394Z",
|
||||
"aliases": {
|
||||
"accessibility-compliance-audit": "accessibility-compliance-accessibility-audit",
|
||||
"active directory attacks": "active-directory-attacks",
|
||||
@@ -7,6 +7,7 @@
|
||||
"agent-orchestration-optimize": "agent-orchestration-multi-agent-optimize",
|
||||
"api fuzzing for bug bounty": "api-fuzzing-bug-bounty",
|
||||
"api-testing-mock": "api-testing-observability-api-mock",
|
||||
"templates": "app-builder/templates",
|
||||
"application-performance-optimization": "application-performance-performance-optimization",
|
||||
"aws penetration testing": "aws-penetration-testing",
|
||||
"backend-development-feature": "backend-development-feature-development",
|
||||
@@ -45,6 +46,7 @@
|
||||
"deployment-validation-validate": "deployment-validation-config-validate",
|
||||
"distributed-debugging-trace": "distributed-debugging-debug-trace",
|
||||
"documentation-generation-generate": "documentation-generation-doc-generate",
|
||||
"docx": "docx-official",
|
||||
"error-debugging-analysis": "error-debugging-error-analysis",
|
||||
"error-debugging-review": "error-debugging-multi-agent-review",
|
||||
"error-diagnostics-analysis": "error-diagnostics-error-analysis",
|
||||
@@ -59,6 +61,16 @@
|
||||
"frontend-mobile-scaffold": "frontend-mobile-development-component-scaffold",
|
||||
"frontend-mobile-scan": "frontend-mobile-security-xss-scan",
|
||||
"full-stack-feature": "full-stack-orchestration-full-stack-feature",
|
||||
"2d-games": "game-development/2d-games",
|
||||
"3d-games": "game-development/3d-games",
|
||||
"game-art": "game-development/game-art",
|
||||
"game-audio": "game-development/game-audio",
|
||||
"game-design": "game-development/game-design",
|
||||
"mobile-games": "game-development/mobile-games",
|
||||
"multiplayer": "game-development/multiplayer",
|
||||
"pc-games": "game-development/pc-games",
|
||||
"vr-ar": "game-development/vr-ar",
|
||||
"web-games": "game-development/web-games",
|
||||
"git-pr-workflow": "git-pr-workflows-git-workflow",
|
||||
"html injection testing": "html-injection-testing",
|
||||
"idor vulnerability testing": "idor-testing",
|
||||
@@ -79,11 +91,13 @@
|
||||
"observability-monitoring-setup": "observability-monitoring-monitor-setup",
|
||||
"observability-monitoring-implement": "observability-monitoring-slo-implement",
|
||||
"obsidian-clipper-creator": "obsidian-clipper-template-creator",
|
||||
"pdf": "pdf-official",
|
||||
"pentest checklist": "pentest-checklist",
|
||||
"pentest commands": "pentest-commands",
|
||||
"performance-testing-ai": "performance-testing-review-ai-review",
|
||||
"performance-testing-agent": "performance-testing-review-multi-agent-review",
|
||||
"supabase-postgres-best-practices": "postgres-best-practices",
|
||||
"pptx": "pptx-official",
|
||||
"privilege escalation methods": "privilege-escalation-methods",
|
||||
"python-development-scaffold": "python-development-python-scaffold",
|
||||
"vercel-react-best-practices": "react-best-practices",
|
||||
@@ -107,6 +121,7 @@
|
||||
"windows privilege escalation": "windows-privilege-escalation",
|
||||
"wireshark network traffic analysis": "wireshark-analysis",
|
||||
"wordpress penetration testing": "wordpress-penetration-testing",
|
||||
"xlsx": "xlsx-official",
|
||||
"cross-site scripting and html injection testing": "xss-html-injection"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generatedAt": "2026-01-30T08:15:03.985Z",
|
||||
"generatedAt": "2026-02-03T08:46:32.394Z",
|
||||
"bundles": {
|
||||
"core-dev": {
|
||||
"description": "Core development skills across languages, frameworks, and backend/frontend fundamentals.",
|
||||
@@ -45,6 +45,9 @@
|
||||
"firebase",
|
||||
"firecrawl-scraper",
|
||||
"flutter-expert",
|
||||
"fp-ts-errors",
|
||||
"fp-ts-pragmatic",
|
||||
"fp-ts-react",
|
||||
"frontend-design",
|
||||
"frontend-dev-guidelines",
|
||||
"frontend-developer",
|
||||
@@ -52,6 +55,7 @@
|
||||
"frontend-mobile-security-xss-scan",
|
||||
"frontend-security-coder",
|
||||
"frontend-slides",
|
||||
"game-development/mobile-games",
|
||||
"go-concurrency-patterns",
|
||||
"golang-pro",
|
||||
"graphql",
|
||||
@@ -109,6 +113,7 @@
|
||||
"shopify-apps",
|
||||
"shopify-development",
|
||||
"slack-bot-builder",
|
||||
"stitch-ui-design",
|
||||
"swiftui-expert-skill",
|
||||
"systems-programming-rust-project",
|
||||
"tavily-web",
|
||||
@@ -276,6 +281,7 @@
|
||||
"database-optimizer",
|
||||
"dbt-transformation-patterns",
|
||||
"firebase",
|
||||
"fp-ts-react",
|
||||
"frontend-dev-guidelines",
|
||||
"gdpr-data-handling",
|
||||
"graphql",
|
||||
@@ -314,7 +320,6 @@
|
||||
"unity-ecs-patterns",
|
||||
"using-neon",
|
||||
"vector-database-engineer",
|
||||
"xlsx",
|
||||
"xlsx-official"
|
||||
]
|
||||
},
|
||||
@@ -352,6 +357,7 @@
|
||||
"error-diagnostics-error-trace",
|
||||
"expo-deployment",
|
||||
"flutter-expert",
|
||||
"game-development/game-art",
|
||||
"git-pr-workflows-git-workflow",
|
||||
"gitlab-ci-patterns",
|
||||
"gitops-workflow",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"generatedAt": "2026-01-30T08:15:03.985Z",
|
||||
"total": 614,
|
||||
"generatedAt": "2026-02-03T08:46:32.394Z",
|
||||
"total": 626,
|
||||
"skills": [
|
||||
{
|
||||
"id": "3d-web-experience",
|
||||
@@ -760,6 +760,31 @@
|
||||
],
|
||||
"path": "skills/app-builder/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "app-builder/templates",
|
||||
"name": "templates",
|
||||
"description": "Project scaffolding templates for new applications. Use when creating new projects from scratch. Contains 12 templates for various tech stacks.",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"app",
|
||||
"builder/templates"
|
||||
],
|
||||
"triggers": [
|
||||
"app",
|
||||
"builder/templates",
|
||||
"scaffolding",
|
||||
"new",
|
||||
"applications",
|
||||
"creating",
|
||||
"scratch",
|
||||
"contains",
|
||||
"12",
|
||||
"various",
|
||||
"tech",
|
||||
"stacks"
|
||||
],
|
||||
"path": "skills/app-builder/templates/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "app-store-optimization",
|
||||
"name": "app-store-optimization",
|
||||
@@ -4778,30 +4803,6 @@
|
||||
],
|
||||
"path": "skills/documentation-templates/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "docx",
|
||||
"name": "docx",
|
||||
"description": "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",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"docx"
|
||||
],
|
||||
"triggers": [
|
||||
"docx",
|
||||
"document",
|
||||
"creation",
|
||||
"editing",
|
||||
"analysis",
|
||||
"tracked",
|
||||
"changes",
|
||||
"comments",
|
||||
"formatting",
|
||||
"preservation",
|
||||
"text",
|
||||
"extraction"
|
||||
],
|
||||
"path": "skills/docx/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "docx-official",
|
||||
"name": "docx",
|
||||
@@ -5873,6 +5874,84 @@
|
||||
],
|
||||
"path": "skills/form-cro/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "fp-ts-errors",
|
||||
"name": "fp-ts-errors",
|
||||
"description": "Handle errors as values using fp-ts Either and TaskEither for cleaner, more predictable TypeScript code. Use when implementing error handling patterns with fp-ts.",
|
||||
"category": "development",
|
||||
"tags": [
|
||||
"fp",
|
||||
"ts",
|
||||
"errors"
|
||||
],
|
||||
"triggers": [
|
||||
"fp",
|
||||
"ts",
|
||||
"errors",
|
||||
"handle",
|
||||
"values",
|
||||
"either",
|
||||
"taskeither",
|
||||
"cleaner",
|
||||
"predictable",
|
||||
"typescript",
|
||||
"code",
|
||||
"implementing"
|
||||
],
|
||||
"path": "skills/fp-ts-errors/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "fp-ts-pragmatic",
|
||||
"name": "fp-ts-pragmatic",
|
||||
"description": "A practical, jargon-free guide to fp-ts functional programming - the 80/20 approach that gets results without the academic overhead. Use when writing TypeScript with fp-ts library.",
|
||||
"category": "development",
|
||||
"tags": [
|
||||
"fp",
|
||||
"ts",
|
||||
"pragmatic"
|
||||
],
|
||||
"triggers": [
|
||||
"fp",
|
||||
"ts",
|
||||
"pragmatic",
|
||||
"practical",
|
||||
"jargon",
|
||||
"free",
|
||||
"functional",
|
||||
"programming",
|
||||
"80",
|
||||
"20",
|
||||
"approach",
|
||||
"gets"
|
||||
],
|
||||
"path": "skills/fp-ts-pragmatic/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "fp-ts-react",
|
||||
"name": "fp-ts-react",
|
||||
"description": "Practical patterns for using fp-ts with React - hooks, state, forms, data fetching. Use when building React apps with functional programming patterns. Works with React 18/19, Next.js 14/15.",
|
||||
"category": "data-ai",
|
||||
"tags": [
|
||||
"fp",
|
||||
"ts",
|
||||
"react"
|
||||
],
|
||||
"triggers": [
|
||||
"fp",
|
||||
"ts",
|
||||
"react",
|
||||
"practical",
|
||||
"hooks",
|
||||
"state",
|
||||
"forms",
|
||||
"data",
|
||||
"fetching",
|
||||
"building",
|
||||
"apps",
|
||||
"functional"
|
||||
],
|
||||
"path": "skills/fp-ts-react/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "framework-migration-code-migrate",
|
||||
"name": "framework-migration-code-migrate",
|
||||
@@ -6194,6 +6273,245 @@
|
||||
],
|
||||
"path": "skills/game-development/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/2d-games",
|
||||
"name": "2d-games",
|
||||
"description": "2D game development principles. Sprites, tilemaps, physics, camera.",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/2d",
|
||||
"games"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/2d",
|
||||
"games",
|
||||
"2d",
|
||||
"development",
|
||||
"principles",
|
||||
"sprites",
|
||||
"tilemaps",
|
||||
"physics",
|
||||
"camera"
|
||||
],
|
||||
"path": "skills/game-development/2d-games/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/3d-games",
|
||||
"name": "3d-games",
|
||||
"description": "3D game development principles. Rendering, shaders, physics, cameras.",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/3d",
|
||||
"games"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/3d",
|
||||
"games",
|
||||
"3d",
|
||||
"development",
|
||||
"principles",
|
||||
"rendering",
|
||||
"shaders",
|
||||
"physics",
|
||||
"cameras"
|
||||
],
|
||||
"path": "skills/game-development/3d-games/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/game-art",
|
||||
"name": "game-art",
|
||||
"description": "Game art principles. Visual style selection, asset pipeline, animation workflow.",
|
||||
"category": "infrastructure",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/game",
|
||||
"art"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/game",
|
||||
"art",
|
||||
"principles",
|
||||
"visual",
|
||||
"style",
|
||||
"selection",
|
||||
"asset",
|
||||
"pipeline",
|
||||
"animation"
|
||||
],
|
||||
"path": "skills/game-development/game-art/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/game-audio",
|
||||
"name": "game-audio",
|
||||
"description": "Game audio principles. Sound design, music integration, adaptive audio systems.",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/game",
|
||||
"audio"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/game",
|
||||
"audio",
|
||||
"principles",
|
||||
"sound",
|
||||
"music",
|
||||
"integration",
|
||||
"adaptive"
|
||||
],
|
||||
"path": "skills/game-development/game-audio/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/game-design",
|
||||
"name": "game-design",
|
||||
"description": "Game design principles. GDD structure, balancing, player psychology, progression.",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/game"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/game",
|
||||
"principles",
|
||||
"gdd",
|
||||
"structure",
|
||||
"balancing",
|
||||
"player",
|
||||
"psychology",
|
||||
"progression"
|
||||
],
|
||||
"path": "skills/game-development/game-design/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/mobile-games",
|
||||
"name": "mobile-games",
|
||||
"description": "Mobile game development principles. Touch input, battery, performance, app stores.",
|
||||
"category": "development",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/mobile",
|
||||
"games"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/mobile",
|
||||
"games",
|
||||
"mobile",
|
||||
"development",
|
||||
"principles",
|
||||
"touch",
|
||||
"input",
|
||||
"battery",
|
||||
"performance",
|
||||
"app",
|
||||
"stores"
|
||||
],
|
||||
"path": "skills/game-development/mobile-games/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/multiplayer",
|
||||
"name": "multiplayer",
|
||||
"description": "Multiplayer game development principles. Architecture, networking, synchronization.",
|
||||
"category": "architecture",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/multiplayer"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/multiplayer",
|
||||
"multiplayer",
|
||||
"development",
|
||||
"principles",
|
||||
"architecture",
|
||||
"networking",
|
||||
"synchronization"
|
||||
],
|
||||
"path": "skills/game-development/multiplayer/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/pc-games",
|
||||
"name": "pc-games",
|
||||
"description": "PC and console game development principles. Engine selection, platform features, optimization strategies.",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/pc",
|
||||
"games"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/pc",
|
||||
"games",
|
||||
"pc",
|
||||
"console",
|
||||
"development",
|
||||
"principles",
|
||||
"engine",
|
||||
"selection",
|
||||
"platform",
|
||||
"features",
|
||||
"optimization"
|
||||
],
|
||||
"path": "skills/game-development/pc-games/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/vr-ar",
|
||||
"name": "vr-ar",
|
||||
"description": "VR/AR development principles. Comfort, interaction, performance requirements.",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/vr",
|
||||
"ar"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/vr",
|
||||
"ar",
|
||||
"vr",
|
||||
"development",
|
||||
"principles",
|
||||
"comfort",
|
||||
"interaction",
|
||||
"performance",
|
||||
"requirements"
|
||||
],
|
||||
"path": "skills/game-development/vr-ar/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "game-development/web-games",
|
||||
"name": "web-games",
|
||||
"description": "Web browser game development principles. Framework selection, WebGPU, optimization, PWA.",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"game",
|
||||
"development/web",
|
||||
"games"
|
||||
],
|
||||
"triggers": [
|
||||
"game",
|
||||
"development/web",
|
||||
"games",
|
||||
"web",
|
||||
"browser",
|
||||
"development",
|
||||
"principles",
|
||||
"framework",
|
||||
"selection",
|
||||
"webgpu",
|
||||
"optimization",
|
||||
"pwa"
|
||||
],
|
||||
"path": "skills/game-development/web-games/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "gcp-cloud-run",
|
||||
"name": "gcp-cloud-run",
|
||||
@@ -9526,30 +9844,6 @@
|
||||
],
|
||||
"path": "skills/pci-compliance/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "pdf",
|
||||
"name": "pdf",
|
||||
"description": "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.",
|
||||
"category": "workflow",
|
||||
"tags": [
|
||||
"pdf"
|
||||
],
|
||||
"triggers": [
|
||||
"pdf",
|
||||
"manipulation",
|
||||
"toolkit",
|
||||
"extracting",
|
||||
"text",
|
||||
"tables",
|
||||
"creating",
|
||||
"new",
|
||||
"pdfs",
|
||||
"merging",
|
||||
"splitting",
|
||||
"documents"
|
||||
],
|
||||
"path": "skills/pdf/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "pdf-official",
|
||||
"name": "pdf",
|
||||
@@ -10008,30 +10302,6 @@
|
||||
],
|
||||
"path": "skills/powershell-windows/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "pptx",
|
||||
"name": "pptx",
|
||||
"description": "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",
|
||||
"category": "general",
|
||||
"tags": [
|
||||
"pptx"
|
||||
],
|
||||
"triggers": [
|
||||
"pptx",
|
||||
"presentation",
|
||||
"creation",
|
||||
"editing",
|
||||
"analysis",
|
||||
"claude",
|
||||
"work",
|
||||
"presentations",
|
||||
"files",
|
||||
"creating",
|
||||
"new",
|
||||
"modifying"
|
||||
],
|
||||
"path": "skills/pptx/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "pptx-official",
|
||||
"name": "pptx",
|
||||
@@ -10592,6 +10862,30 @@
|
||||
],
|
||||
"path": "skills/quant-analyst/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "radix-ui-design-system",
|
||||
"name": "radix-ui-design-system",
|
||||
"description": "Build accessible design systems with Radix UI primitives. Headless component customization, theming strategies, and compound component patterns for production-grade UI libraries.",
|
||||
"category": "architecture",
|
||||
"tags": [
|
||||
"radix",
|
||||
"ui"
|
||||
],
|
||||
"triggers": [
|
||||
"radix",
|
||||
"ui",
|
||||
"accessible",
|
||||
"primitives",
|
||||
"headless",
|
||||
"component",
|
||||
"customization",
|
||||
"theming",
|
||||
"compound",
|
||||
"grade",
|
||||
"libraries"
|
||||
],
|
||||
"path": "skills/radix-ui-design-system/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "rag-engineer",
|
||||
"name": "rag-engineer",
|
||||
@@ -12822,6 +13116,31 @@
|
||||
],
|
||||
"path": "skills/startup-metrics-framework/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "stitch-ui-design",
|
||||
"name": "stitch-ui-design",
|
||||
"description": "Expert guide for creating effective prompts for Google Stitch AI UI design tool. Use when user wants to design UI/UX in Stitch, create app interfaces, generate mobile/web designs, or needs help crafting Stitch prompts. Covers prompt structure, specificity techniques, iteration strategies, and design-to-code workflows for Stitch by Google.",
|
||||
"category": "data-ai",
|
||||
"tags": [
|
||||
"stitch",
|
||||
"ui"
|
||||
],
|
||||
"triggers": [
|
||||
"stitch",
|
||||
"ui",
|
||||
"creating",
|
||||
"effective",
|
||||
"prompts",
|
||||
"google",
|
||||
"ai",
|
||||
"user",
|
||||
"wants",
|
||||
"ux",
|
||||
"app",
|
||||
"interfaces"
|
||||
],
|
||||
"path": "skills/stitch-ui-design/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "stride-analysis-patterns",
|
||||
"name": "stride-analysis-patterns",
|
||||
@@ -14844,30 +15163,6 @@
|
||||
],
|
||||
"path": "skills/x-article-publisher-skill/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "xlsx",
|
||||
"name": "xlsx",
|
||||
"description": "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",
|
||||
"category": "data-ai",
|
||||
"tags": [
|
||||
"xlsx"
|
||||
],
|
||||
"triggers": [
|
||||
"xlsx",
|
||||
"spreadsheet",
|
||||
"creation",
|
||||
"editing",
|
||||
"analysis",
|
||||
"formulas",
|
||||
"formatting",
|
||||
"data",
|
||||
"visualization",
|
||||
"claude",
|
||||
"work",
|
||||
"spreadsheets"
|
||||
],
|
||||
"path": "skills/xlsx/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "xlsx-official",
|
||||
"name": "xlsx",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antigravity-awesome-skills",
|
||||
"version": "4.2.0",
|
||||
"version": "4.6.0",
|
||||
"dependencies": {
|
||||
"yaml": "^2.8.2"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
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.
|
||||
|
||||
### Do I need to install all 560+ skills?
|
||||
### Do I need to install all 626+ 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`.
|
||||
It's like having a library - all books are there, but you only read the ones you need.
|
||||
@@ -62,7 +62,11 @@ _Always check the Risk label and review the code._
|
||||
|
||||
### Where should I install the skills?
|
||||
|
||||
The universal path that works with most tools is `.agent/skills/`:
|
||||
The universal path that works with most tools is `.agent/skills/`.
|
||||
|
||||
**Using npx:** `npx antigravity-awesome-skills` (or `npx github:sickn33/antigravity-awesome-skills` if you get a 404).
|
||||
|
||||
**Using git clone:**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skills
|
||||
@@ -72,6 +76,7 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .agent/skill
|
||||
|
||||
- Claude Code: `.claude/skills/`
|
||||
- Gemini CLI: `.gemini/skills/`
|
||||
- Codex CLI: `.codex/skills/`
|
||||
- Cursor: `.cursor/skills/` or project root
|
||||
|
||||
### Does this work with Windows?
|
||||
|
||||
@@ -15,9 +15,11 @@ AI Agents (like **Claude Code**, **Gemini**, **Cursor**) are smart, but they lac
|
||||
|
||||
## ⚡️ Quick Start: The "Starter Packs"
|
||||
|
||||
Don't panic about the 560+ skills. You don't need them all at once.
|
||||
Don't panic about the 626+ skills. You don't need them all at once.
|
||||
We have curated **Starter Packs** to get you running immediately.
|
||||
|
||||
You **install the full repo once** (npx or clone); Starter Packs are curated lists to help you **pick which skills to use** by role (e.g. Web Wizard, Hacker Pack)—they are not a different way to install.
|
||||
|
||||
### 1. Install the Repo
|
||||
|
||||
**Option A — npx (easiest):**
|
||||
@@ -26,7 +28,9 @@ We have curated **Starter Packs** to get you running immediately.
|
||||
npx antigravity-awesome-skills
|
||||
```
|
||||
|
||||
This clones to `~/.agent/skills` by default. Use `--cursor`, `--claude`, or `--gemini` to install for a specific tool, or `--path <dir>` for a custom location. Run `npx antigravity-awesome-skills --help` for details.
|
||||
This clones to `~/.agent/skills` by default. Use `--cursor`, `--claude`, `--gemini`, or `--codex` to install for a specific tool, or `--path <dir>` for a custom location. Run `npx antigravity-awesome-skills --help` for details.
|
||||
|
||||
If you see a 404 error, use: `npx github:sickn33/antigravity-awesome-skills`
|
||||
|
||||
**Option B — git clone:**
|
||||
|
||||
@@ -78,6 +82,7 @@ Once installed, just talk to your AI naturally.
|
||||
| :-------------- | :-------------- | :---------------- |
|
||||
| **Claude Code** | ✅ Full Support | `.claude/skills/` |
|
||||
| **Gemini CLI** | ✅ Full Support | `.gemini/skills/` |
|
||||
| **Codex CLI** | ✅ Full Support | `.codex/skills/` |
|
||||
| **Antigravity** | ✅ Native | `.agent/skills/` |
|
||||
| **Cursor** | ✅ Native | `.cursor/skills/` |
|
||||
| **Copilot** | ⚠️ Text Only | Manual copy-paste |
|
||||
@@ -98,8 +103,8 @@ _Check the [Skill Catalog](../CATALOG.md) for the full list._
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
**Q: Do I need to install all 560 skills?**
|
||||
A: You clone the whole repo, but your AI only _reads_ the ones you ask for (or that are relevant). It's lightweight!
|
||||
**Q: Do I need to install all 626 skills?**
|
||||
A: You clone the whole repo once; your AI only _reads_ the skills you invoke (or that are relevant), so it stays lightweight. **Starter Packs** in [BUNDLES.md](BUNDLES.md) are curated lists to help you discover the right skills for your role—they don't change how you install.
|
||||
|
||||
**Q: Can I make my own skills?**
|
||||
A: Yes! Use the **@skill-creator** skill to build your own.
|
||||
|
||||
@@ -21,6 +21,7 @@ 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."
|
||||
Accepted headings: `## When to Use`, `## Use this skill when`, `## When to Use This Skill`.
|
||||
|
||||
### 3. Safety & Risk Classification
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ Some skills include additional metadata:
|
||||
---
|
||||
name: my-skill-name
|
||||
description: "Brief description"
|
||||
risk: "safe" # safe | risk | official
|
||||
risk: "safe" # none | safe | critical | offensive (see QUALITY_BAR.md)
|
||||
source: "community"
|
||||
tags: ["react", "typescript"]
|
||||
---
|
||||
|
||||
@@ -72,6 +72,14 @@ The following skills were added from the curated collection at [VoltAgent/awesom
|
||||
- **memory-systems** - [muratcankoylan](https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering)
|
||||
- **terraform-skill** - [antonbabenko](https://github.com/antonbabenko/terraform-skill)
|
||||
|
||||
## Skills from whatiskadudoing/fp-ts-skills (v4.4.0)
|
||||
|
||||
| Skill | Original Source | License | Notes |
|
||||
| :---- | :-------------- | :------ | :---- |
|
||||
| `fp-ts-pragmatic` | [whatiskadudoing/fp-ts-skills](https://github.com/whatiskadudoing/fp-ts-skills) | Compatible | Pragmatic fp-ts guide – pipe, Option, Either, TaskEither |
|
||||
| `fp-ts-react` | [whatiskadudoing/fp-ts-skills](https://github.com/whatiskadudoing/fp-ts-skills) | Compatible | fp-ts with React 18/19 and Next.js |
|
||||
| `fp-ts-errors` | [whatiskadudoing/fp-ts-skills](https://github.com/whatiskadudoing/fp-ts-skills) | Compatible | Type-safe error handling with Either and TaskEither |
|
||||
|
||||
## License Policy
|
||||
|
||||
- **Code**: All original code in this repository is **MIT**.
|
||||
|
||||
@@ -73,7 +73,7 @@ Một số skill bao gồm thêm siêu dữ liệu bổ sung:
|
||||
---
|
||||
name: my-skill-name
|
||||
description: "Mô tả ngắn"
|
||||
risk: "safe" # safe | risk | official
|
||||
risk: "safe" # none | safe | critical | offensive (xem QUALITY_BAR.md)
|
||||
source: "community"
|
||||
tags: ["react", "typescript"]
|
||||
---
|
||||
|
||||
@@ -149,12 +149,39 @@ function readSkill(skillDir, skillId) {
|
||||
|
||||
function listSkillIds(skillsDir) {
|
||||
return fs.readdirSync(skillsDir)
|
||||
.filter(entry => !entry.startsWith('.') && fs.statSync(path.join(skillsDir, entry)).isDirectory())
|
||||
.filter(entry => {
|
||||
if (entry.startsWith('.')) return false;
|
||||
const dirPath = path.join(skillsDir, entry);
|
||||
if (!fs.statSync(dirPath).isDirectory()) return false;
|
||||
const skillPath = path.join(dirPath, 'SKILL.md');
|
||||
return fs.existsSync(skillPath);
|
||||
})
|
||||
.sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively list all skill directory paths under skillsDir (relative paths).
|
||||
* Matches generate_index.py behavior so catalog includes nested skills (e.g. game-development/2d-games).
|
||||
*/
|
||||
function listSkillIdsRecursive(skillsDir, baseDir = skillsDir, acc = []) {
|
||||
const entries = fs.readdirSync(baseDir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
if (entry.name.startsWith('.')) continue;
|
||||
if (!entry.isDirectory()) continue;
|
||||
const dirPath = path.join(baseDir, entry.name);
|
||||
const skillPath = path.join(dirPath, 'SKILL.md');
|
||||
const relPath = path.relative(skillsDir, dirPath);
|
||||
if (fs.existsSync(skillPath)) {
|
||||
acc.push(relPath);
|
||||
}
|
||||
listSkillIdsRecursive(skillsDir, dirPath, acc);
|
||||
}
|
||||
return acc.sort();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
listSkillIds,
|
||||
listSkillIdsRecursive,
|
||||
parseFrontmatter,
|
||||
parseInlineList,
|
||||
readSkill,
|
||||
|
||||
13
package.json
13
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "antigravity-awesome-skills",
|
||||
"version": "4.3.0",
|
||||
"description": "614+ agentic skills for Claude Code, Gemini CLI, Cursor, Antigravity & more. Installer CLI.",
|
||||
"version": "4.7.0",
|
||||
"description": "626+ agentic skills for Claude Code, Gemini CLI, Cursor, Antigravity & more. Installer CLI.",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"validate": "python3 scripts/validate_skills.py",
|
||||
@@ -10,17 +10,18 @@
|
||||
"readme": "python3 scripts/update_readme.py",
|
||||
"chain": "npm run validate && npm run index && npm run readme",
|
||||
"catalog": "node scripts/build-catalog.js",
|
||||
"build": "npm run chain && npm run catalog"
|
||||
"build": "npm run chain && npm run catalog",
|
||||
"test": "node scripts/tests/validate_skills_headings.test.js && python3 scripts/tests/test_validate_skills_headings.py"
|
||||
},
|
||||
"dependencies": {
|
||||
"devDependencies": {
|
||||
"yaml": "^2.8.2"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sickn33/antigravity-awesome-skills.git"
|
||||
"url": "git+https://github.com/sickn33/antigravity-awesome-skills.git"
|
||||
},
|
||||
"bin": {
|
||||
"antigravity-awesome-skills": "./bin/install.js"
|
||||
"antigravity-awesome-skills": "bin/install.js"
|
||||
},
|
||||
"files": [
|
||||
"bin"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# Python dependencies for scripts (validate_skills.py, generate_index.py, update_readme.py)
|
||||
pyyaml>=5.4,<7
|
||||
@@ -1,215 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Analyze remaining similar skills to determine if they are truly new
|
||||
and worth adding to the repository.
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Tuple
|
||||
from urllib.parse import urlparse
|
||||
from urllib.request import urlopen, Request
|
||||
from urllib.error import URLError, HTTPError
|
||||
|
||||
def normalize_skill_name(name: str) -> str:
|
||||
"""Normalize skill name to kebab-case."""
|
||||
# Remove special chars, convert to lowercase, replace spaces/hyphens
|
||||
name = re.sub(r'[^\w\s-]', '', name.lower())
|
||||
name = re.sub(r'[\s_]+', '-', name)
|
||||
name = re.sub(r'-+', '-', name)
|
||||
return name.strip('-')
|
||||
|
||||
def check_url_accessible(url: str) -> bool:
|
||||
"""Check if URL is accessible."""
|
||||
try:
|
||||
req = Request(url, method='HEAD')
|
||||
with urlopen(req, timeout=10) as response:
|
||||
return response.status == 200
|
||||
except (URLError, HTTPError, Exception):
|
||||
return False
|
||||
|
||||
def get_repo_base_url(github_url: str) -> str:
|
||||
"""Extract base GitHub repository URL."""
|
||||
# Handle various GitHub URL formats
|
||||
patterns = [
|
||||
r'https://github\.com/([^/]+/[^/]+)',
|
||||
r'github\.com/([^/]+/[^/]+)',
|
||||
]
|
||||
|
||||
for pattern in patterns:
|
||||
match = re.search(pattern, github_url)
|
||||
if match:
|
||||
return f"https://github.com/{match.group(1)}"
|
||||
return None
|
||||
|
||||
def check_skill_file_exists(repo_url: str, skill_path: str = None) -> Tuple[bool, str]:
|
||||
"""Check if SKILL.md exists in the repository."""
|
||||
base_url = get_repo_base_url(repo_url)
|
||||
if not base_url:
|
||||
return False, None
|
||||
|
||||
# Common paths to check
|
||||
paths_to_check = [
|
||||
f"{base_url}/raw/main/{skill_path}/SKILL.md" if skill_path else f"{base_url}/raw/main/SKILL.md",
|
||||
f"{base_url}/raw/main/skills/{skill_path}/SKILL.md" if skill_path else None,
|
||||
f"{base_url}/raw/master/{skill_path}/SKILL.md" if skill_path else f"{base_url}/raw/master/SKILL.md",
|
||||
f"{base_url}/blob/main/{skill_path}/SKILL.md" if skill_path else f"{base_url}/blob/main/SKILL.md",
|
||||
]
|
||||
|
||||
for path in paths_to_check:
|
||||
if path and check_url_accessible(path):
|
||||
return True, path
|
||||
|
||||
return False, None
|
||||
|
||||
def analyze_similarity(skill_name: str, similar_skills: List[str], existing_skills: Dict) -> Dict:
|
||||
"""Analyze how similar a skill is to existing ones."""
|
||||
analysis = {
|
||||
'is_duplicate': False,
|
||||
'is_complementary': False,
|
||||
'similarity_score': 0.0,
|
||||
'closest_match': None,
|
||||
'reasoning': []
|
||||
}
|
||||
|
||||
skill_lower = skill_name.lower()
|
||||
|
||||
# Check for exact or near-exact matches
|
||||
for existing_name, existing_data in existing_skills.items():
|
||||
existing_lower = existing_name.lower()
|
||||
|
||||
# Exact match
|
||||
if skill_lower == existing_lower:
|
||||
analysis['is_duplicate'] = True
|
||||
analysis['closest_match'] = existing_name
|
||||
analysis['reasoning'].append(f"Exact match with existing skill: {existing_name}")
|
||||
return analysis
|
||||
|
||||
# Check if one contains the other
|
||||
if skill_lower in existing_lower or existing_lower in skill_lower:
|
||||
if abs(len(skill_lower) - len(existing_lower)) <= 3:
|
||||
analysis['is_duplicate'] = True
|
||||
analysis['closest_match'] = existing_name
|
||||
analysis['similarity_score'] = 0.9
|
||||
analysis['reasoning'].append(f"Near-exact match: '{skill_name}' vs '{existing_name}'")
|
||||
return analysis
|
||||
|
||||
# Check similarity with similar skills list
|
||||
for similar in similar_skills:
|
||||
if similar.lower() in existing_skills:
|
||||
existing_data = existing_skills[similar.lower()]
|
||||
# If the similar skill exists, this might be a duplicate
|
||||
analysis['similarity_score'] = 0.7
|
||||
analysis['closest_match'] = similar
|
||||
analysis['reasoning'].append(f"Similar to existing skill: {similar}")
|
||||
|
||||
# Determine if complementary
|
||||
if analysis['similarity_score'] < 0.5:
|
||||
analysis['is_complementary'] = True
|
||||
analysis['reasoning'].append("Low similarity - likely complementary skill")
|
||||
|
||||
return analysis
|
||||
|
||||
def main():
|
||||
base_dir = Path(__file__).parent.parent
|
||||
|
||||
# Load remaining similar skills
|
||||
remaining_file = base_dir / "remaining_similar_skills.json"
|
||||
if not remaining_file.exists():
|
||||
print("❌ remaining_similar_skills.json not found. Run the analysis first.")
|
||||
return
|
||||
|
||||
with open(remaining_file, 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Load existing skills
|
||||
catalog_file = base_dir / "data" / "catalog.json"
|
||||
with open(catalog_file, 'r') as f:
|
||||
catalog = json.load(f)
|
||||
existing_skills = {s['name'].lower(): s for s in catalog.get('skills', [])}
|
||||
|
||||
print(f"🔍 Analyzing {len(data['skills'])} remaining similar skills...\n")
|
||||
|
||||
results = {
|
||||
'truly_new': [],
|
||||
'duplicates': [],
|
||||
'complementary': [],
|
||||
'needs_review': [],
|
||||
'invalid_sources': []
|
||||
}
|
||||
|
||||
for skill in data['skills']:
|
||||
skill_name = skill['name']
|
||||
print(f"Analyzing: {skill_name}")
|
||||
|
||||
# Skip if already exists
|
||||
if skill['exists_in_catalog'] or skill['folder_exists']:
|
||||
results['duplicates'].append({
|
||||
'name': skill_name,
|
||||
'reason': 'Already exists in repository',
|
||||
'url': skill['url']
|
||||
})
|
||||
continue
|
||||
|
||||
# Check source accessibility
|
||||
exists, raw_url = check_skill_file_exists(skill['url'], skill.get('skill_part'))
|
||||
if not exists:
|
||||
results['invalid_sources'].append({
|
||||
'name': skill_name,
|
||||
'url': skill['url'],
|
||||
'reason': 'SKILL.md not found or URL inaccessible'
|
||||
})
|
||||
continue
|
||||
|
||||
# Analyze similarity
|
||||
similarity_analysis = analyze_similarity(
|
||||
skill_name,
|
||||
skill['similar_to'],
|
||||
existing_skills
|
||||
)
|
||||
|
||||
skill_result = {
|
||||
'name': skill_name,
|
||||
'url': skill['url'],
|
||||
'raw_url': raw_url,
|
||||
'description': skill['description'],
|
||||
'org': skill['org'],
|
||||
'category': skill['category'],
|
||||
'similar_to': skill['similar_to'],
|
||||
'similarity_analysis': similarity_analysis
|
||||
}
|
||||
|
||||
if similarity_analysis['is_duplicate']:
|
||||
results['duplicates'].append(skill_result)
|
||||
elif similarity_analysis['is_complementary']:
|
||||
results['complementary'].append(skill_result)
|
||||
else:
|
||||
results['needs_review'].append(skill_result)
|
||||
|
||||
# Generate report
|
||||
report = {
|
||||
'summary': {
|
||||
'total_analyzed': len(data['skills']),
|
||||
'truly_new': len(results['complementary']),
|
||||
'duplicates': len(results['duplicates']),
|
||||
'needs_review': len(results['needs_review']),
|
||||
'invalid_sources': len(results['invalid_sources'])
|
||||
},
|
||||
'results': results
|
||||
}
|
||||
|
||||
output_file = base_dir / "similar_skills_analysis.json"
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump(report, f, indent=2)
|
||||
|
||||
print(f"\n✅ Analysis complete!")
|
||||
print(f"📊 Summary:")
|
||||
print(f" - Truly new (complementary): {len(results['complementary'])}")
|
||||
print(f" - Duplicates: {len(results['duplicates'])}")
|
||||
print(f" - Needs review: {len(results['needs_review'])}")
|
||||
print(f" - Invalid sources: {len(results['invalid_sources'])}")
|
||||
print(f"\n📄 Full report saved to: {output_file}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,7 +1,7 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const {
|
||||
listSkillIds,
|
||||
listSkillIdsRecursive,
|
||||
readSkill,
|
||||
tokenize,
|
||||
unique,
|
||||
@@ -297,8 +297,8 @@ function renderCatalogMarkdown(catalog) {
|
||||
}
|
||||
|
||||
function buildCatalog() {
|
||||
const skillIds = listSkillIds(SKILLS_DIR);
|
||||
const skills = skillIds.map(skillId => readSkill(SKILLS_DIR, skillId));
|
||||
const skillRelPaths = listSkillIdsRecursive(SKILLS_DIR);
|
||||
const skills = skillRelPaths.map(relPath => readSkill(SKILLS_DIR, relPath));
|
||||
const catalogSkills = [];
|
||||
|
||||
for (const skill of skills) {
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Count uncommitted skills by checking git status.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
def run_git_command(cmd):
|
||||
"""Run git command and return output."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
cmd.split(),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=Path(__file__).parent.parent
|
||||
)
|
||||
return result.stdout.strip().split('\n') if result.stdout.strip() else []
|
||||
except Exception as e:
|
||||
print(f"Error running git command: {e}")
|
||||
return []
|
||||
|
||||
def main():
|
||||
base_dir = Path(__file__).parent.parent
|
||||
|
||||
# Get all uncommitted files
|
||||
untracked = run_git_command("git ls-files --others --exclude-standard")
|
||||
modified = run_git_command("git diff --name-only HEAD")
|
||||
staged = run_git_command("git diff --cached --name-only")
|
||||
|
||||
# Also check status
|
||||
status_output = run_git_command("git status --porcelain")
|
||||
|
||||
print("Git status output:")
|
||||
for line in status_output[:20]: # First 20 lines
|
||||
print(f" {line}")
|
||||
print()
|
||||
|
||||
# Filter for skill files
|
||||
skill_files = []
|
||||
for file_list in [untracked, modified, staged]:
|
||||
for file in file_list:
|
||||
if '/skills/' in file and file.endswith('SKILL.md'):
|
||||
skill_name = file.split('/skills/')[1].split('/SKILL.md')[0]
|
||||
if skill_name not in [s['name'] for s in skill_files]:
|
||||
skill_files.append({
|
||||
'name': skill_name,
|
||||
'file': file,
|
||||
'status': 'untracked' if file in untracked else ('staged' if file in staged else 'modified')
|
||||
})
|
||||
|
||||
# Load catalog to verify
|
||||
catalog_file = base_dir / "data" / "catalog.json"
|
||||
with open(catalog_file, 'r') as f:
|
||||
catalog = json.load(f)
|
||||
|
||||
catalog_skills = {s['name']: s for s in catalog.get('skills', [])}
|
||||
|
||||
print("=" * 70)
|
||||
print("SKILLS NON COMMITTATE")
|
||||
print("=" * 70)
|
||||
print(f"\nTotale skills trovate: {len(skill_files)}")
|
||||
print(f"Totale skills nel catalog: {catalog.get('total', 0)}")
|
||||
print()
|
||||
|
||||
# Group by status
|
||||
untracked_skills = [s for s in skill_files if s['status'] == 'untracked']
|
||||
modified_skills = [s for s in skill_files if s['status'] == 'modified']
|
||||
staged_skills = [s for s in skill_files if s['status'] == 'staged']
|
||||
|
||||
print(f"📝 Skills non tracciate (nuove): {len(untracked_skills)}")
|
||||
print(f"📝 Skills modificate: {len(modified_skills)}")
|
||||
print(f"📝 Skills staged: {len(staged_skills)}")
|
||||
print()
|
||||
|
||||
if untracked_skills:
|
||||
print("Nuove skills (non tracciate):")
|
||||
for skill in sorted(untracked_skills, key=lambda x: x['name']):
|
||||
in_catalog = skill['name'] in catalog_skills
|
||||
print(f" ✅ {skill['name']} {'(in catalog)' if in_catalog else '(NOT in catalog)'}")
|
||||
|
||||
if modified_skills:
|
||||
print("\nSkills modificate:")
|
||||
for skill in sorted(modified_skills, key=lambda x: x['name']):
|
||||
print(f" 📝 {skill['name']}")
|
||||
|
||||
if staged_skills:
|
||||
print("\nSkills staged:")
|
||||
for skill in sorted(staged_skills, key=lambda x: x['name']):
|
||||
print(f" 📦 {skill['name']}")
|
||||
|
||||
# Check for VoltAgent skills specifically
|
||||
print("\n" + "=" * 70)
|
||||
print("VERIFICA SKILLS DA VOLTAGENT")
|
||||
print("=" * 70)
|
||||
|
||||
voltagent_skills_phase1 = [
|
||||
'commit', 'create-pr', 'find-bugs', 'iterate-pr',
|
||||
'culture-index', 'fix-review', 'sharp-edges',
|
||||
'expo-deployment', 'upgrading-expo',
|
||||
'using-neon', 'vercel-deploy-claimable', 'design-md',
|
||||
'hugging-face-cli', 'hugging-face-jobs',
|
||||
'automate-whatsapp', 'observe-whatsapp', 'readme', 'screenshots',
|
||||
'deep-research', 'imagen', 'swiftui-expert-skill',
|
||||
'n8n-code-python', 'n8n-mcp-tools-expert', 'n8n-node-configuration'
|
||||
]
|
||||
|
||||
voltagent_skills_phase2 = [
|
||||
'frontend-slides', 'linear-claude-skill', 'skill-rails-upgrade',
|
||||
'context-fundamentals', 'context-degradation', 'context-compression',
|
||||
'context-optimization', 'multi-agent-patterns', 'tool-design',
|
||||
'evaluation', 'memory-systems', 'terraform-skill'
|
||||
]
|
||||
|
||||
all_voltagent = voltagent_skills_phase1 + voltagent_skills_phase2
|
||||
|
||||
uncommitted_voltagent = []
|
||||
for skill_name in all_voltagent:
|
||||
skill_file = base_dir / "skills" / skill_name / "SKILL.md"
|
||||
if skill_file.exists():
|
||||
# Check if it's uncommitted
|
||||
if skill_file.relative_to(base_dir).as_posix() in untracked:
|
||||
uncommitted_voltagent.append(skill_name)
|
||||
elif skill_file.relative_to(base_dir).as_posix() in modified:
|
||||
uncommitted_voltagent.append(skill_name)
|
||||
elif skill_file.relative_to(base_dir).as_posix() in staged:
|
||||
uncommitted_voltagent.append(skill_name)
|
||||
|
||||
print(f"\nSkills da VoltAgent non committate: {len(uncommitted_voltagent)}")
|
||||
print(f" Fase 1 (49 skills): {len([s for s in voltagent_skills_phase1 if s in uncommitted_voltagent])}")
|
||||
print(f" Fase 2 (12 skills): {len([s for s in voltagent_skills_phase2 if s in uncommitted_voltagent])}")
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("RIEPILOGO FINALE")
|
||||
print("=" * 70)
|
||||
print(f"Totale skills non committate: {len(skill_files)}")
|
||||
print(f"Skills da VoltAgent non committate: {len(uncommitted_voltagent)}")
|
||||
print(f"Altre skills non committate: {len(skill_files) - len(uncommitted_voltagent)}")
|
||||
|
||||
return {
|
||||
'total_uncommitted': len(skill_files),
|
||||
'voltagent_uncommitted': len(uncommitted_voltagent),
|
||||
'voltagent_phase1': len([s for s in voltagent_skills_phase1 if s in uncommitted_voltagent]),
|
||||
'voltagent_phase2': len([s for s in voltagent_skills_phase2 if s in uncommitted_voltagent])
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,271 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Implement the 12 new skills from similar skills analysis.
|
||||
9 recommended + 3 verified (evaluation, memory-systems, terraform-skill)
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from urllib.request import urlopen, Request
|
||||
from urllib.error import URLError, HTTPError
|
||||
from typing import Dict, Optional
|
||||
|
||||
def normalize_skill_name(name: str) -> str:
|
||||
"""Normalize skill name to kebab-case."""
|
||||
name = re.sub(r'[^a-z0-9-]', '-', name.lower())
|
||||
name = re.sub(r'-+', '-', name)
|
||||
return name.strip('-')
|
||||
|
||||
def download_file(url: str) -> Optional[str]:
|
||||
"""Download content from URL."""
|
||||
try:
|
||||
req = Request(url)
|
||||
req.add_header('User-Agent', 'Mozilla/5.0 (compatible; AntigravitySkillsDownloader/1.0)')
|
||||
with urlopen(req, timeout=15) as response:
|
||||
return response.read().decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f" ❌ Error downloading {url}: {e}")
|
||||
return None
|
||||
|
||||
def parse_frontmatter(content: str) -> Optional[Dict]:
|
||||
"""Parse YAML frontmatter."""
|
||||
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 ensure_frontmatter_compliance(content: str, skill_name: str, source_url: str, description: str) -> str:
|
||||
"""Ensure SKILL.md has compliant frontmatter."""
|
||||
metadata = parse_frontmatter(content)
|
||||
|
||||
if not metadata:
|
||||
# No frontmatter, add it
|
||||
frontmatter = f"""---
|
||||
name: {skill_name}
|
||||
description: {description}
|
||||
source: {source_url}
|
||||
risk: safe
|
||||
---
|
||||
|
||||
"""
|
||||
return frontmatter + content
|
||||
|
||||
# Update existing frontmatter
|
||||
metadata['name'] = skill_name
|
||||
metadata['description'] = description
|
||||
metadata['source'] = source_url
|
||||
if 'risk' not in metadata:
|
||||
metadata['risk'] = 'safe'
|
||||
|
||||
# Rebuild frontmatter
|
||||
frontmatter_lines = ['---']
|
||||
for key, value in metadata.items():
|
||||
if isinstance(value, str) and (' ' in value or ':' in value):
|
||||
frontmatter_lines.append(f'{key}: "{value}"')
|
||||
else:
|
||||
frontmatter_lines.append(f'{key}: {value}')
|
||||
frontmatter_lines.append('---\n')
|
||||
|
||||
# Replace frontmatter in content
|
||||
content_without_fm = re.sub(r'^---\s*\n.*?\n---\s*\n', '', content, flags=re.DOTALL)
|
||||
return '\n'.join(frontmatter_lines) + content_without_fm
|
||||
|
||||
def ensure_when_to_use_section(content: str, description: str) -> str:
|
||||
"""Ensure 'When to Use' section exists."""
|
||||
if re.search(r'##\s+When\s+to\s+Use', content, re.IGNORECASE):
|
||||
return content
|
||||
|
||||
# Add section after frontmatter
|
||||
when_to_use = f"""
|
||||
## When to Use This Skill
|
||||
|
||||
{description}
|
||||
|
||||
Use this skill when working with {description.lower()}.
|
||||
"""
|
||||
|
||||
# Insert after frontmatter
|
||||
content = re.sub(r'(---\s*\n.*?\n---\s*\n)', r'\1' + when_to_use, content, flags=re.DOTALL)
|
||||
return content
|
||||
|
||||
def main():
|
||||
base_dir = Path(__file__).parent.parent
|
||||
|
||||
# Load similar skills analysis
|
||||
analysis_file = base_dir / "similar_skills_analysis.json"
|
||||
with open(analysis_file, 'r') as f:
|
||||
analysis = json.load(f)
|
||||
|
||||
# Skills to implement: 9 recommended + 3 verified
|
||||
skills_to_implement = [
|
||||
# 9 Recommended
|
||||
{
|
||||
'name': 'frontend-slides',
|
||||
'url': 'https://github.com/zarazhangrui/frontend-slides',
|
||||
'raw_url': 'https://github.com/zarazhangrui/frontend-slides/raw/main/SKILL.md',
|
||||
'description': 'Generate animation-rich HTML presentations with visual style previews',
|
||||
'org': 'zarazhangrui',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'linear-claude-skill',
|
||||
'url': 'https://github.com/wrsmith108/linear-claude-skill',
|
||||
'raw_url': 'https://github.com/wrsmith108/linear-claude-skill/raw/main/SKILL.md',
|
||||
'description': 'Manage Linear issues, projects, and teams',
|
||||
'org': 'wrsmith108',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'skill-rails-upgrade',
|
||||
'url': 'https://github.com/robzolkos/skill-rails-upgrade',
|
||||
'raw_url': 'https://github.com/robzolkos/skill-rails-upgrade/raw/master/SKILL.md',
|
||||
'description': 'Analyze Rails apps and provide upgrade assessments',
|
||||
'org': 'robzolkos',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'context-fundamentals',
|
||||
'url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-fundamentals',
|
||||
'raw_url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/skills/context-fundamentals/SKILL.md',
|
||||
'description': 'Understand what context is, why it matters, and the anatomy of context in agent systems',
|
||||
'org': 'muratcankoylan',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'context-degradation',
|
||||
'url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-degradation',
|
||||
'raw_url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/skills/context-degradation/SKILL.md',
|
||||
'description': 'Recognize patterns of context failure: lost-in-middle, poisoning, distraction, and clash',
|
||||
'org': 'muratcankoylan',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'context-compression',
|
||||
'url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-compression',
|
||||
'raw_url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/skills/context-compression/SKILL.md',
|
||||
'description': 'Design and evaluate compression strategies for long-running sessions',
|
||||
'org': 'muratcankoylan',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'context-optimization',
|
||||
'url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-optimization',
|
||||
'raw_url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/skills/context-optimization/SKILL.md',
|
||||
'description': 'Apply compaction, masking, and caching strategies',
|
||||
'org': 'muratcankoylan',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'multi-agent-patterns',
|
||||
'url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/multi-agent-patterns',
|
||||
'raw_url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/skills/multi-agent-patterns/SKILL.md',
|
||||
'description': 'Master orchestrator, peer-to-peer, and hierarchical multi-agent architectures',
|
||||
'org': 'muratcankoylan',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'tool-design',
|
||||
'url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/tool-design',
|
||||
'raw_url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/skills/tool-design/SKILL.md',
|
||||
'description': 'Build tools that agents can use effectively, including architectural reduction patterns',
|
||||
'org': 'muratcankoylan',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
# 3 Verified (notebooklm-skill is duplicate, skip it)
|
||||
{
|
||||
'name': 'evaluation',
|
||||
'url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/evaluation',
|
||||
'raw_url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/skills/evaluation/SKILL.md',
|
||||
'description': 'Build evaluation frameworks for agent systems',
|
||||
'org': 'muratcankoylan',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'memory-systems',
|
||||
'url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/memory-systems',
|
||||
'raw_url': 'https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/skills/memory-systems/SKILL.md',
|
||||
'description': 'Design short-term, long-term, and graph-based memory architectures',
|
||||
'org': 'muratcankoylan',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
{
|
||||
'name': 'terraform-skill',
|
||||
'url': 'https://github.com/antonbabenko/terraform-skill',
|
||||
'raw_url': 'https://github.com/antonbabenko/terraform-skill/raw/master/SKILL.md',
|
||||
'description': 'Terraform infrastructure as code best practices',
|
||||
'org': 'antonbabenko',
|
||||
'category': 'Community Skills'
|
||||
},
|
||||
]
|
||||
|
||||
print(f"🚀 Implementing {len(skills_to_implement)} new skills...\n")
|
||||
|
||||
results = {
|
||||
'success': [],
|
||||
'failed': []
|
||||
}
|
||||
|
||||
for skill in skills_to_implement:
|
||||
skill_name = skill['name']
|
||||
raw_url = skill['raw_url']
|
||||
source_url = skill['url']
|
||||
description = skill['description']
|
||||
|
||||
print(f"📦 Processing: {skill_name}")
|
||||
|
||||
# Download SKILL.md
|
||||
content = download_file(raw_url)
|
||||
if not content:
|
||||
print(f" ❌ Failed to download")
|
||||
results['failed'].append(skill_name)
|
||||
continue
|
||||
|
||||
# Check if it's HTML (shouldn't be, but just in case)
|
||||
if '<!DOCTYPE html>' in content or ('<html>' in content.lower() and content.count('<html>') > 1):
|
||||
print(f" ⚠️ Received HTML instead of markdown, trying alternative URL")
|
||||
# Try alternative raw URL
|
||||
alt_url = raw_url.replace('/raw/main/', '/raw/master/') if '/raw/main/' in raw_url else raw_url.replace('/raw/master/', '/raw/main/')
|
||||
alt_content = download_file(alt_url)
|
||||
if alt_content and not ('<!DOCTYPE html>' in alt_content or '<html>' in alt_content.lower()):
|
||||
content = alt_content
|
||||
print(f" ✅ Got markdown from alternative URL")
|
||||
else:
|
||||
print(f" ❌ Still HTML, skipping")
|
||||
results['failed'].append(skill_name)
|
||||
continue
|
||||
|
||||
# Ensure compliance
|
||||
content = ensure_frontmatter_compliance(content, skill_name, source_url, description)
|
||||
content = ensure_when_to_use_section(content, description)
|
||||
|
||||
# Create skill directory
|
||||
skill_dir = base_dir / "skills" / skill_name
|
||||
skill_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Write SKILL.md
|
||||
skill_file = skill_dir / "SKILL.md"
|
||||
skill_file.write_text(content, encoding='utf-8')
|
||||
|
||||
print(f" ✅ Created: {skill_file}")
|
||||
results['success'].append(skill_name)
|
||||
|
||||
print(f"\n✅ Implementation complete!")
|
||||
print(f" Success: {len(results['success'])}")
|
||||
print(f" Failed: {len(results['failed'])}")
|
||||
|
||||
if results['failed']:
|
||||
print(f"\n❌ Failed skills: {', '.join(results['failed'])}")
|
||||
|
||||
return results
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -8,6 +8,8 @@ const SKILLS_DIR = path.join(ROOT, 'skills');
|
||||
const ALLOWED_FIELDS = new Set([
|
||||
'name',
|
||||
'description',
|
||||
'risk',
|
||||
'source',
|
||||
'license',
|
||||
'compatibility',
|
||||
'metadata',
|
||||
|
||||
@@ -21,8 +21,12 @@ python3 scripts/generate_index.py
|
||||
echo "Running update_readme.py..."
|
||||
python3 scripts/update_readme.py
|
||||
|
||||
# 2. Stats Consistency Check
|
||||
echo -e "\n${YELLOW}Step 2: verifying Stats Consistency...${NC}"
|
||||
# 2. Catalog (required for CI)
|
||||
echo -e "\n${YELLOW}Step 2: Build catalog...${NC}"
|
||||
npm run catalog
|
||||
|
||||
# 3. Stats Consistency Check
|
||||
echo -e "\n${YELLOW}Step 3: Verifying Stats Consistency...${NC}"
|
||||
JSON_COUNT=$(python3 -c "import json; print(len(json.load(open('skills_index.json'))))")
|
||||
echo "Skills in Registry (JSON): $JSON_COUNT"
|
||||
|
||||
@@ -36,8 +40,14 @@ if [[ "$README_CONTENT" != *"$JSON_COUNT high-performance"* ]]; then
|
||||
fi
|
||||
echo -e "${GREEN}✅ Stats Consistent.${NC}"
|
||||
|
||||
# 3. Contributor Check
|
||||
echo -e "\n${YELLOW}Step 3: Contributor Check${NC}"
|
||||
# 4. Version check (package.json is source of truth for npm)
|
||||
echo -e "\n${YELLOW}Step 4: Version check${NC}"
|
||||
PKG_VERSION=$(node -p "require('./package.json').version")
|
||||
echo "package.json version: $PKG_VERSION"
|
||||
echo "Ensure this version is bumped before 'npm publish' (npm forbids republishing the same version)."
|
||||
|
||||
# 5. Contributor Check
|
||||
echo -e "\n${YELLOW}Step 5: Contributor Check${NC}"
|
||||
echo "Recent commits by author (check against README 'Repo Contributors'):"
|
||||
git shortlog -sn --since="1 month ago" --all --no-merges | head -n 10
|
||||
|
||||
@@ -52,4 +62,5 @@ if [ "$CONFIRM_CONTRIB" != "yes" ]; then
|
||||
fi
|
||||
|
||||
echo -e "\n${GREEN}✅ Release Cycle Checks Passed. You may now commit and push.${NC}"
|
||||
echo -e "${YELLOW}After tagging a release: run \`npm publish\` from repo root (or use GitHub Release + NPM_TOKEN for CI).${NC}"
|
||||
exit 0
|
||||
|
||||
18
scripts/tests/test_validate_skills_headings.py
Normal file
18
scripts/tests/test_validate_skills_headings.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
|
||||
from validate_skills import has_when_to_use_section
|
||||
|
||||
SAMPLES = [
|
||||
("## When to Use", True),
|
||||
("## Use this skill when", True),
|
||||
("## When to Use This Skill", True),
|
||||
("## Overview", False),
|
||||
]
|
||||
|
||||
for heading, expected in SAMPLES:
|
||||
content = f"\n{heading}\n- item\n"
|
||||
assert has_when_to_use_section(content) is expected, heading
|
||||
|
||||
print("ok")
|
||||
16
scripts/tests/validate_skills_headings.test.js
Normal file
16
scripts/tests/validate_skills_headings.test.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const assert = require('assert');
|
||||
const { hasUseSection } = require('../validate-skills');
|
||||
|
||||
const samples = [
|
||||
['## When to Use', true],
|
||||
['## Use this skill when', true],
|
||||
['## When to Use This Skill', true],
|
||||
['## Overview', false],
|
||||
];
|
||||
|
||||
for (const [heading, expected] of samples) {
|
||||
const content = `\n${heading}\n- item\n`;
|
||||
assert.strictEqual(hasUseSection(content), expected, heading);
|
||||
}
|
||||
|
||||
console.log('ok');
|
||||
@@ -36,7 +36,7 @@ def update_readme():
|
||||
|
||||
# 3. Update Intro Text Count
|
||||
content = re.sub(
|
||||
r"(library of \*\*)\d+( high-performance skills\*\*)",
|
||||
r"(library of \*\*)\d+( high-performance agentic skills\*\*)",
|
||||
rf"\g<1>{total_skills}\g<2>",
|
||||
content,
|
||||
)
|
||||
|
||||
@@ -32,12 +32,24 @@ const MAX_SKILL_LINES = 500;
|
||||
const ALLOWED_FIELDS = new Set([
|
||||
'name',
|
||||
'description',
|
||||
'risk',
|
||||
'source',
|
||||
'license',
|
||||
'compatibility',
|
||||
'metadata',
|
||||
'allowed-tools',
|
||||
]);
|
||||
|
||||
const USE_SECTION_PATTERNS = [
|
||||
/^##\s+When\s+to\s+Use/im,
|
||||
/^##\s+Use\s+this\s+skill\s+when/im,
|
||||
/^##\s+When\s+to\s+Use\s+This\s+Skill/im,
|
||||
];
|
||||
|
||||
function hasUseSection(content) {
|
||||
return USE_SECTION_PATTERNS.some(pattern => pattern.test(content));
|
||||
}
|
||||
|
||||
function isPlainObject(value) {
|
||||
return value && typeof value === 'object' && !Array.isArray(value);
|
||||
}
|
||||
@@ -99,172 +111,183 @@ function addStrictSectionErrors(label, missing, baselineSet) {
|
||||
}
|
||||
}
|
||||
|
||||
const skillIds = listSkillIds(SKILLS_DIR);
|
||||
const baseline = loadBaseline();
|
||||
const baselineUse = new Set(baseline.useSection || []);
|
||||
const baselineDoNotUse = new Set(baseline.doNotUseSection || []);
|
||||
const baselineInstructions = new Set(baseline.instructionsSection || []);
|
||||
const baselineLongFile = new Set(baseline.longFile || []);
|
||||
function run() {
|
||||
const skillIds = listSkillIds(SKILLS_DIR);
|
||||
const baseline = loadBaseline();
|
||||
const baselineUse = new Set(baseline.useSection || []);
|
||||
const baselineDoNotUse = new Set(baseline.doNotUseSection || []);
|
||||
const baselineInstructions = new Set(baseline.instructionsSection || []);
|
||||
const baselineLongFile = new Set(baseline.longFile || []);
|
||||
|
||||
for (const skillId of skillIds) {
|
||||
const skillPath = path.join(SKILLS_DIR, skillId, 'SKILL.md');
|
||||
for (const skillId of skillIds) {
|
||||
const skillPath = path.join(SKILLS_DIR, skillId, 'SKILL.md');
|
||||
|
||||
if (!fs.existsSync(skillPath)) {
|
||||
addError(`Missing SKILL.md: ${skillId}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(skillPath, 'utf8');
|
||||
const { data, errors: fmErrors, hasFrontmatter } = parseFrontmatter(content);
|
||||
const lineCount = content.split(/\r?\n/).length;
|
||||
|
||||
if (!hasFrontmatter) {
|
||||
addError(`Missing frontmatter: ${skillId}`);
|
||||
}
|
||||
|
||||
if (fmErrors && fmErrors.length) {
|
||||
fmErrors.forEach(error => addError(`Frontmatter parse error (${skillId}): ${error}`));
|
||||
}
|
||||
|
||||
if (!NAME_PATTERN.test(skillId)) {
|
||||
addError(`Folder name must match ${NAME_PATTERN}: ${skillId}`);
|
||||
}
|
||||
|
||||
if (data.name !== undefined) {
|
||||
const nameError = validateStringField('name', data.name, { min: 1, max: MAX_NAME_LENGTH });
|
||||
if (nameError) {
|
||||
addError(`${nameError} (${skillId})`);
|
||||
} else {
|
||||
const nameValue = String(data.name).trim();
|
||||
if (!NAME_PATTERN.test(nameValue)) {
|
||||
addError(`name must match ${NAME_PATTERN}: ${skillId}`);
|
||||
}
|
||||
if (nameValue !== skillId) {
|
||||
addError(`name must match folder name: ${skillId} -> ${nameValue}`);
|
||||
}
|
||||
if (!fs.existsSync(skillPath)) {
|
||||
addError(`Missing SKILL.md: ${skillId}`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const descError = data.description === undefined
|
||||
? 'description is required.'
|
||||
: validateStringField('description', data.description, { min: 1, max: MAX_DESCRIPTION_LENGTH });
|
||||
if (descError) {
|
||||
addError(`${descError} (${skillId})`);
|
||||
}
|
||||
const content = fs.readFileSync(skillPath, 'utf8');
|
||||
const { data, errors: fmErrors, hasFrontmatter } = parseFrontmatter(content);
|
||||
const lineCount = content.split(/\r?\n/).length;
|
||||
|
||||
if (data.license !== undefined) {
|
||||
const licenseError = validateStringField('license', data.license, { min: 1, max: 128 });
|
||||
if (licenseError) {
|
||||
addError(`${licenseError} (${skillId})`);
|
||||
if (!hasFrontmatter) {
|
||||
addError(`Missing frontmatter: ${skillId}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.compatibility !== undefined) {
|
||||
const compatibilityError = validateStringField(
|
||||
'compatibility',
|
||||
data.compatibility,
|
||||
{ min: 1, max: MAX_COMPATIBILITY_LENGTH },
|
||||
);
|
||||
if (compatibilityError) {
|
||||
addError(`${compatibilityError} (${skillId})`);
|
||||
if (fmErrors && fmErrors.length) {
|
||||
fmErrors.forEach(error => addError(`Frontmatter parse error (${skillId}): ${error}`));
|
||||
}
|
||||
}
|
||||
|
||||
if (data['allowed-tools'] !== undefined) {
|
||||
if (typeof data['allowed-tools'] !== 'string') {
|
||||
addError(`allowed-tools must be a space-delimited string. (${skillId})`);
|
||||
} else if (!data['allowed-tools'].trim()) {
|
||||
addError(`allowed-tools cannot be empty. (${skillId})`);
|
||||
if (!NAME_PATTERN.test(skillId)) {
|
||||
addError(`Folder name must match ${NAME_PATTERN}: ${skillId}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.metadata !== undefined) {
|
||||
if (!isPlainObject(data.metadata)) {
|
||||
addError(`metadata must be a string map/object. (${skillId})`);
|
||||
} else {
|
||||
for (const [key, value] of Object.entries(data.metadata)) {
|
||||
if (typeof value !== 'string') {
|
||||
addError(`metadata.${key} must be a string. (${skillId})`);
|
||||
if (data.name !== undefined) {
|
||||
const nameError = validateStringField('name', data.name, { min: 1, max: MAX_NAME_LENGTH });
|
||||
if (nameError) {
|
||||
addError(`${nameError} (${skillId})`);
|
||||
} else {
|
||||
const nameValue = String(data.name).trim();
|
||||
if (!NAME_PATTERN.test(nameValue)) {
|
||||
addError(`name must match ${NAME_PATTERN}: ${skillId}`);
|
||||
}
|
||||
if (nameValue !== skillId) {
|
||||
addError(`name must match folder name: ${skillId} -> ${nameValue}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data && Object.keys(data).length) {
|
||||
const unknownFields = Object.keys(data).filter(key => !ALLOWED_FIELDS.has(key));
|
||||
if (unknownFields.length) {
|
||||
unknownFieldSkills.push(skillId);
|
||||
addError(`Unknown frontmatter fields (${skillId}): ${unknownFields.join(', ')}`);
|
||||
const descError = data.description === undefined
|
||||
? 'description is required.'
|
||||
: validateStringField('description', data.description, { min: 1, max: MAX_DESCRIPTION_LENGTH });
|
||||
if (descError) {
|
||||
addError(`${descError} (${skillId})`);
|
||||
}
|
||||
|
||||
if (data.license !== undefined) {
|
||||
const licenseError = validateStringField('license', data.license, { min: 1, max: 128 });
|
||||
if (licenseError) {
|
||||
addError(`${licenseError} (${skillId})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.compatibility !== undefined) {
|
||||
const compatibilityError = validateStringField(
|
||||
'compatibility',
|
||||
data.compatibility,
|
||||
{ min: 1, max: MAX_COMPATIBILITY_LENGTH },
|
||||
);
|
||||
if (compatibilityError) {
|
||||
addError(`${compatibilityError} (${skillId})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (data['allowed-tools'] !== undefined) {
|
||||
if (typeof data['allowed-tools'] !== 'string') {
|
||||
addError(`allowed-tools must be a space-delimited string. (${skillId})`);
|
||||
} else if (!data['allowed-tools'].trim()) {
|
||||
addError(`allowed-tools cannot be empty. (${skillId})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.metadata !== undefined) {
|
||||
if (!isPlainObject(data.metadata)) {
|
||||
addError(`metadata must be a string map/object. (${skillId})`);
|
||||
} else {
|
||||
for (const [key, value] of Object.entries(data.metadata)) {
|
||||
if (typeof value !== 'string') {
|
||||
addError(`metadata.${key} must be a string. (${skillId})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data && Object.keys(data).length) {
|
||||
const unknownFields = Object.keys(data).filter(key => !ALLOWED_FIELDS.has(key));
|
||||
if (unknownFields.length) {
|
||||
unknownFieldSkills.push(skillId);
|
||||
addError(`Unknown frontmatter fields (${skillId}): ${unknownFields.join(', ')}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (lineCount > MAX_SKILL_LINES) {
|
||||
longFiles.push(skillId);
|
||||
}
|
||||
|
||||
if (!hasUseSection(content)) {
|
||||
missingUseSection.push(skillId);
|
||||
}
|
||||
|
||||
if (!content.includes('## Do not use')) {
|
||||
missingDoNotUseSection.push(skillId);
|
||||
}
|
||||
|
||||
if (!content.includes('## Instructions')) {
|
||||
missingInstructionsSection.push(skillId);
|
||||
}
|
||||
}
|
||||
|
||||
if (lineCount > MAX_SKILL_LINES) {
|
||||
longFiles.push(skillId);
|
||||
if (missingUseSection.length) {
|
||||
addWarning(`Missing "Use this skill when" section: ${missingUseSection.length} skills (examples: ${missingUseSection.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
|
||||
if (!content.includes('## Use this skill when')) {
|
||||
missingUseSection.push(skillId);
|
||||
if (missingDoNotUseSection.length) {
|
||||
addWarning(`Missing "Do not use" section: ${missingDoNotUseSection.length} skills (examples: ${missingDoNotUseSection.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
|
||||
if (!content.includes('## Do not use')) {
|
||||
missingDoNotUseSection.push(skillId);
|
||||
if (missingInstructionsSection.length) {
|
||||
addWarning(`Missing "Instructions" section: ${missingInstructionsSection.length} skills (examples: ${missingInstructionsSection.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
|
||||
if (!content.includes('## Instructions')) {
|
||||
missingInstructionsSection.push(skillId);
|
||||
if (longFiles.length) {
|
||||
addWarning(`SKILL.md over ${MAX_SKILL_LINES} lines: ${longFiles.length} skills (examples: ${longFiles.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingUseSection.length) {
|
||||
addWarning(`Missing "Use this skill when" section: ${missingUseSection.length} skills (examples: ${missingUseSection.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
|
||||
if (missingDoNotUseSection.length) {
|
||||
addWarning(`Missing "Do not use" section: ${missingDoNotUseSection.length} skills (examples: ${missingDoNotUseSection.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
|
||||
if (missingInstructionsSection.length) {
|
||||
addWarning(`Missing "Instructions" section: ${missingInstructionsSection.length} skills (examples: ${missingInstructionsSection.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
|
||||
if (longFiles.length) {
|
||||
addWarning(`SKILL.md over ${MAX_SKILL_LINES} lines: ${longFiles.length} skills (examples: ${longFiles.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
|
||||
if (unknownFieldSkills.length) {
|
||||
addWarning(`Unknown frontmatter fields detected: ${unknownFieldSkills.length} skills (examples: ${unknownFieldSkills.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
|
||||
addStrictSectionErrors('Use this skill when', missingUseSection, baselineUse);
|
||||
addStrictSectionErrors('Do not use', missingDoNotUseSection, baselineDoNotUse);
|
||||
addStrictSectionErrors('Instructions', missingInstructionsSection, baselineInstructions);
|
||||
addStrictSectionErrors(`SKILL.md line count <= ${MAX_SKILL_LINES}`, longFiles, baselineLongFile);
|
||||
|
||||
if (writeBaseline) {
|
||||
const baselineData = {
|
||||
generatedAt: new Date().toISOString(),
|
||||
useSection: [...missingUseSection].sort(),
|
||||
doNotUseSection: [...missingDoNotUseSection].sort(),
|
||||
instructionsSection: [...missingInstructionsSection].sort(),
|
||||
longFile: [...longFiles].sort(),
|
||||
};
|
||||
fs.writeFileSync(BASELINE_PATH, JSON.stringify(baselineData, null, 2));
|
||||
console.log(`Baseline written to ${BASELINE_PATH}`);
|
||||
}
|
||||
|
||||
if (warnings.length) {
|
||||
console.warn('Warnings:');
|
||||
for (const warning of warnings) {
|
||||
console.warn(`- ${warning}`);
|
||||
if (unknownFieldSkills.length) {
|
||||
addWarning(`Unknown frontmatter fields detected: ${unknownFieldSkills.length} skills (examples: ${unknownFieldSkills.slice(0, 5).join(', ')})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
console.error('\nErrors:');
|
||||
for (const error of errors) {
|
||||
console.error(`- ${error}`);
|
||||
addStrictSectionErrors('Use this skill when', missingUseSection, baselineUse);
|
||||
addStrictSectionErrors('Do not use', missingDoNotUseSection, baselineDoNotUse);
|
||||
addStrictSectionErrors('Instructions', missingInstructionsSection, baselineInstructions);
|
||||
addStrictSectionErrors(`SKILL.md line count <= ${MAX_SKILL_LINES}`, longFiles, baselineLongFile);
|
||||
|
||||
if (writeBaseline) {
|
||||
const baselineData = {
|
||||
generatedAt: new Date().toISOString(),
|
||||
useSection: [...missingUseSection].sort(),
|
||||
doNotUseSection: [...missingDoNotUseSection].sort(),
|
||||
instructionsSection: [...missingInstructionsSection].sort(),
|
||||
longFile: [...longFiles].sort(),
|
||||
};
|
||||
fs.writeFileSync(BASELINE_PATH, JSON.stringify(baselineData, null, 2));
|
||||
console.log(`Baseline written to ${BASELINE_PATH}`);
|
||||
}
|
||||
process.exit(1);
|
||||
|
||||
if (warnings.length) {
|
||||
console.warn('Warnings:');
|
||||
for (const warning of warnings) {
|
||||
console.warn(`- ${warning}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
console.error('\nErrors:');
|
||||
for (const error of errors) {
|
||||
console.error(`- ${error}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Validation passed for ${skillIds.length} skills.`);
|
||||
}
|
||||
|
||||
console.log(`Validation passed for ${skillIds.length} skills.`);
|
||||
if (require.main === module) {
|
||||
run();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
hasUseSection,
|
||||
run,
|
||||
};
|
||||
|
||||
@@ -3,6 +3,15 @@ import re
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
WHEN_TO_USE_PATTERNS = [
|
||||
re.compile(r"^##\s+When\s+to\s+Use", re.MULTILINE | re.IGNORECASE),
|
||||
re.compile(r"^##\s+Use\s+this\s+skill\s+when", re.MULTILINE | re.IGNORECASE),
|
||||
re.compile(r"^##\s+When\s+to\s+Use\s+This\s+Skill", re.MULTILINE | re.IGNORECASE),
|
||||
]
|
||||
|
||||
def has_when_to_use_section(content):
|
||||
return any(pattern.search(content) for pattern in WHEN_TO_USE_PATTERNS)
|
||||
|
||||
def parse_frontmatter(content):
|
||||
"""
|
||||
Simple frontmatter parser using regex to avoid external dependencies.
|
||||
@@ -30,7 +39,6 @@ def validate_skills(skills_dir, strict_mode=False):
|
||||
|
||||
# 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"]
|
||||
|
||||
@@ -80,7 +88,7 @@ def validate_skills(skills_dir, strict_mode=False):
|
||||
else: warnings.append(msg)
|
||||
|
||||
# 3. Content Checks (Triggers)
|
||||
if not trigger_section_pattern.search(content):
|
||||
if not has_when_to_use_section(content):
|
||||
msg = f"⚠️ {rel_path}: Missing '## When to Use' section"
|
||||
if strict_mode: errors.append(msg.replace("⚠️", "❌"))
|
||||
else: warnings.append(msg)
|
||||
|
||||
@@ -1,703 +0,0 @@
|
||||
{
|
||||
"summary": {
|
||||
"total_analyzed": 89,
|
||||
"truly_new": 0,
|
||||
"duplicates": 2,
|
||||
"needs_review": 13,
|
||||
"invalid_sources": 74
|
||||
},
|
||||
"results": {
|
||||
"truly_new": [],
|
||||
"duplicates": [
|
||||
{
|
||||
"name": "react-best-practices",
|
||||
"reason": "Already exists in repository",
|
||||
"url": "https://github.com/vercel-labs/agent-skills/tree/main/skills/react-best-practices"
|
||||
},
|
||||
{
|
||||
"name": "postgres-best-practices",
|
||||
"reason": "Already exists in repository",
|
||||
"url": "https://github.com/supabase/agent-skills/tree/main/skills/supabase-postgres-best-practices"
|
||||
}
|
||||
],
|
||||
"complementary": [],
|
||||
"needs_review": [
|
||||
{
|
||||
"name": "frontend-slides",
|
||||
"url": "https://github.com/zarazhangrui/frontend-slides",
|
||||
"raw_url": "https://github.com/zarazhangrui/frontend-slides/raw/main/SKILL.md",
|
||||
"description": "Generate animation-rich HTML presentations with visual style previews",
|
||||
"org": "zarazhangrui",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"frontend-patterns",
|
||||
"frontend-design"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "frontend-design",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: frontend-patterns",
|
||||
"Similar to existing skill: frontend-design"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "notebooklm-skill",
|
||||
"url": "https://github.com/PleasePrompto/notebooklm-skill",
|
||||
"raw_url": "https://github.com/PleasePrompto/notebooklm-skill/raw/master/SKILL.md",
|
||||
"description": "Interact with NotebookLM for document-based conversations",
|
||||
"org": "PleasePrompto",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"notebooklm",
|
||||
"slo-implementation"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "slo-implementation",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: notebooklm",
|
||||
"Similar to existing skill: slo-implementation"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linear-claude-skill",
|
||||
"url": "https://github.com/wrsmith108/linear-claude-skill",
|
||||
"raw_url": "https://github.com/wrsmith108/linear-claude-skill/raw/main/SKILL.md",
|
||||
"description": "Manage Linear issues, projects, and teams",
|
||||
"org": "wrsmith108",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"api-design-principles",
|
||||
"seo-content-auditor"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "seo-content-auditor",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: api-design-principles",
|
||||
"Similar to existing skill: seo-content-auditor"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "skill-rails-upgrade",
|
||||
"url": "https://github.com/robzolkos/skill-rails-upgrade",
|
||||
"raw_url": "https://github.com/robzolkos/skill-rails-upgrade/raw/master/SKILL.md",
|
||||
"description": "Analyze Rails apps and provide upgrade assessments",
|
||||
"org": "robzolkos",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"api-design-principles"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "api-design-principles",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: api-design-principles"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "terraform-skill",
|
||||
"url": "https://github.com/antonbabenko/terraform-skill",
|
||||
"raw_url": "https://github.com/antonbabenko/terraform-skill/raw/master/SKILL.md",
|
||||
"description": "Terraform infrastructure as code best practices",
|
||||
"org": "antonbabenko",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"internal-comms",
|
||||
"skill-creator",
|
||||
"slack-gif-creator"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "slack-gif-creator",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: internal-comms",
|
||||
"Similar to existing skill: skill-creator",
|
||||
"Similar to existing skill: slack-gif-creator"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "context-fundamentals",
|
||||
"url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-fundamentals",
|
||||
"raw_url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md",
|
||||
"description": "Understand what context is, why it matters, and the anatomy of context in agent systems",
|
||||
"org": "muratcankoylan",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"salesforce-development"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "salesforce-development",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: salesforce-development"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "context-degradation",
|
||||
"url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-degradation",
|
||||
"raw_url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md",
|
||||
"description": "Recognize patterns of context failure: lost-in-middle, poisoning, distraction, and clash",
|
||||
"org": "muratcankoylan",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"design-orchestration",
|
||||
"production-code-audit",
|
||||
"react-modernization",
|
||||
"saga-orchestration",
|
||||
"screen-reader-testing",
|
||||
"seo-content-auditor",
|
||||
"vector-index-tuning"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "vector-index-tuning",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: design-orchestration",
|
||||
"Similar to existing skill: production-code-audit",
|
||||
"Similar to existing skill: react-modernization",
|
||||
"Similar to existing skill: saga-orchestration",
|
||||
"Similar to existing skill: screen-reader-testing",
|
||||
"Similar to existing skill: seo-content-auditor",
|
||||
"Similar to existing skill: vector-index-tuning"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "context-compression",
|
||||
"url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-compression",
|
||||
"raw_url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md",
|
||||
"description": "Design and evaluate compression strategies for long-running sessions",
|
||||
"org": "muratcankoylan",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"incident-responder",
|
||||
"monorepo-architect",
|
||||
"postmortem-writing",
|
||||
"projection-patterns",
|
||||
"scroll-experience",
|
||||
"service-mesh-expert"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "service-mesh-expert",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: incident-responder",
|
||||
"Similar to existing skill: monorepo-architect",
|
||||
"Similar to existing skill: postmortem-writing",
|
||||
"Similar to existing skill: projection-patterns",
|
||||
"Similar to existing skill: scroll-experience",
|
||||
"Similar to existing skill: service-mesh-expert"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "context-optimization",
|
||||
"url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/context-optimization",
|
||||
"raw_url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md",
|
||||
"description": "Apply compaction, masking, and caching strategies",
|
||||
"org": "muratcankoylan",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"app-store-optimization",
|
||||
"monorepo-architect",
|
||||
"react-modernization"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "react-modernization",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: app-store-optimization",
|
||||
"Similar to existing skill: monorepo-architect",
|
||||
"Similar to existing skill: react-modernization"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "multi-agent-patterns",
|
||||
"url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/multi-agent-patterns",
|
||||
"raw_url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md",
|
||||
"description": "Master orchestrator, peer-to-peer, and hierarchical multi-agent architectures",
|
||||
"org": "muratcankoylan",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"agent-manager-skill",
|
||||
"computer-use-agents",
|
||||
"gitlab-ci-patterns",
|
||||
"rag-implementation"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "rag-implementation",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: agent-manager-skill",
|
||||
"Similar to existing skill: computer-use-agents",
|
||||
"Similar to existing skill: gitlab-ci-patterns",
|
||||
"Similar to existing skill: rag-implementation"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "memory-systems",
|
||||
"url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/memory-systems",
|
||||
"raw_url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md",
|
||||
"description": "Design short-term, long-term, and graph-based memory architectures",
|
||||
"org": "muratcankoylan",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"agent-memory-systems"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "agent-memory-systems",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: agent-memory-systems"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tool-design",
|
||||
"url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/tool-design",
|
||||
"raw_url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md",
|
||||
"description": "Build tools that agents can use effectively, including architectural reduction patterns",
|
||||
"org": "muratcankoylan",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"mobile-design"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "mobile-design",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: mobile-design"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "evaluation",
|
||||
"url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/tree/main/skills/evaluation",
|
||||
"raw_url": "https://github.com/muratcankoylan/Agent-Skills-for-Context-Engineering/raw/main/SKILL.md",
|
||||
"description": "Build evaluation frameworks for agent systems",
|
||||
"org": "muratcankoylan",
|
||||
"category": "Community Skills",
|
||||
"similar_to": [
|
||||
"agent-evaluation",
|
||||
"llm-evaluation"
|
||||
],
|
||||
"similarity_analysis": {
|
||||
"is_duplicate": false,
|
||||
"is_complementary": false,
|
||||
"similarity_score": 0.7,
|
||||
"closest_match": "llm-evaluation",
|
||||
"reasoning": [
|
||||
"Similar to existing skill: agent-evaluation",
|
||||
"Similar to existing skill: llm-evaluation"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"invalid_sources": [
|
||||
{
|
||||
"name": "template",
|
||||
"url": "https://github.com/anthropics/skills/tree/main/template",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "react-native-skills",
|
||||
"url": "https://github.com/vercel-labs/agent-skills/tree/main/skills/react-native-skills",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "building-ai-agent-on-cloudflare",
|
||||
"url": "https://github.com/cloudflare/skills/tree/main/building-ai-agent-on-cloudflare",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "building-mcp-server-on-cloudflare",
|
||||
"url": "https://github.com/cloudflare/skills/tree/main/building-mcp-server-on-cloudflare",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "commands",
|
||||
"url": "https://github.com/cloudflare/skills/tree/main/commands",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "durable-objects",
|
||||
"url": "https://github.com/cloudflare/skills/tree/main/durable-objects",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "web-perf",
|
||||
"url": "https://github.com/cloudflare/skills/tree/main/web-perf",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "react-components",
|
||||
"url": "https://github.com/google-labs-code/stitch-skills/tree/main/skills/react-components",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "hugging-face-datasets",
|
||||
"url": "https://github.com/huggingface/skills/tree/main/skills/hugging-face-datasets",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "hugging-face-evaluation",
|
||||
"url": "https://github.com/huggingface/skills/tree/main/skills/hugging-face-evaluation",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "hugging-face-model-trainer",
|
||||
"url": "https://github.com/huggingface/skills/tree/main/skills/hugging-face-model-trainer",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "hugging-face-paper-publisher",
|
||||
"url": "https://github.com/huggingface/skills/tree/main/skills/hugging-face-paper-publisher",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "hugging-face-tool-builder",
|
||||
"url": "https://github.com/huggingface/skills/tree/main/skills/hugging-face-tool-builder",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "hugging-face-trackio",
|
||||
"url": "https://github.com/huggingface/skills/tree/main/skills/hugging-face-trackio",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "stripe-best-practices",
|
||||
"url": "https://github.com/stripe/ai/tree/main/skills/stripe-best-practices",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "upgrade-stripe",
|
||||
"url": "https://github.com/stripe/ai/tree/main/skills/upgrade-stripe",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "ask-questions-if-underspecified",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/ask-questions-if-underspecified",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "audit-context-building",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/audit-context-building",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "building-secure-contracts",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/building-secure-contracts",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "burpsuite-project-parser",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/burpsuite-project-parser",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "claude-in-chrome-troubleshooting",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/claude-in-chrome-troubleshooting",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "constant-time-analysis",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/constant-time-analysis",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "differential-review",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/differential-review",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "dwarf-expert",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/dwarf-expert",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "entry-point-analyzer",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/entry-point-analyzer",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "firebase-apk-scanner",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/firebase-apk-scanner",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "insecure-defaults",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/insecure-defaults",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "modern-python",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/modern-python",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "property-based-testing",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/property-based-testing",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "semgrep-rule-creator",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/semgrep-rule-creator",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "semgrep-rule-variant-creator",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/semgrep-rule-variant-creator",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "spec-to-code-compliance",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/spec-to-code-compliance",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "static-analysis",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/static-analysis",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "testing-handbook-skills",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/testing-handbook-skills",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "variant-analysis",
|
||||
"url": "https://github.com/trailofbits/skills/tree/main/plugins/variant-analysis",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "expo-app-design",
|
||||
"url": "https://github.com/expo/skills/tree/main/plugins/expo-app-design",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "agents-md",
|
||||
"url": "https://github.com/getsentry/skills/tree/main/plugins/sentry-skills/skills/agents-md",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "claude-settings-audit",
|
||||
"url": "https://github.com/getsentry/skills/tree/main/plugins/sentry-skills/skills/claude-settings-audit",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "code-review",
|
||||
"url": "https://github.com/getsentry/skills/tree/main/plugins/sentry-skills/skills/code-review",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "best-practices",
|
||||
"url": "https://github.com/better-auth/skills/tree/main/better-auth/best-practices",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "commands",
|
||||
"url": "https://github.com/better-auth/skills/tree/main/better-auth/commands",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "create-auth",
|
||||
"url": "https://github.com/better-auth/skills/tree/main/better-auth/create-auth",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "tinybird-best-practices",
|
||||
"url": "https://github.com/tinybirdco/tinybird-agent-skills/tree/main/skills/tinybird-best-practices",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "cloudflare-skill",
|
||||
"url": "https://github.com/dmmulroy/cloudflare-skill/tree/main/skill/cloudflare",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "remotion",
|
||||
"url": "https://github.com/remotion-dev/skills/tree/main/skills/remotion",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "marketingskills",
|
||||
"url": "https://github.com/coreyhaines31/marketingskills",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "content-research-writer",
|
||||
"url": "https://github.com/ComposioHQ/awesome-claude-skills/tree/master/content-research-writer",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "competitive-ads-extractor",
|
||||
"url": "https://github.com/ComposioHQ/awesome-claude-skills/tree/master/competitive-ads-extractor",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "notion-skills-for-claude",
|
||||
"url": "https://www.notion.so/notiondevs/Notion-Skills-for-Claude-28da4445d27180c7af1df7d8615723d0",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "integrate-whatsapp",
|
||||
"url": "https://github.com/gokapso/agent-skills/tree/master/skills/integrate-whatsapp",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "sharing-skills",
|
||||
"url": "https://github.com/obra/superpowers/blob/main/skills/sharing-skills/SKILL.md",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "meeting-insights-analyzer",
|
||||
"url": "https://github.com/ComposioHQ/awesome-claude-skills/tree/master/meeting-insights-analyzer",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "image-enhancer",
|
||||
"url": "https://github.com/ComposioHQ/awesome-claude-skills/tree/master/image-enhancer",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "rootly-incident-responder",
|
||||
"url": "https://github.com/Rootly-AI-Labs/Rootly-MCP-server/blob/main/examples/skills/rootly-incident-responder.md",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "ios-simulator-skill",
|
||||
"url": "https://github.com/conorluddy/ios-simulator-skill",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "postgres",
|
||||
"url": "https://github.com/sanjay3290/ai-skills/tree/main/skills/postgres",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "ui-ux-pro-max-skill",
|
||||
"url": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "changelog-generator",
|
||||
"url": "https://github.com/ComposioHQ/awesome-claude-skills/tree/master/changelog-generator",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "root-cause-tracing",
|
||||
"url": "https://github.com/obra/superpowers/blob/main/skills/root-cause-tracing/SKILL.md",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "testing-skills-with-subagents",
|
||||
"url": "https://github.com/obra/superpowers/blob/main/skills/testing-skills-with-subagents/SKILL.md",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "testing-anti-patterns",
|
||||
"url": "https://github.com/obra/superpowers/blob/main/skills/testing-anti-patterns/SKILL.md",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "condition-based-waiting",
|
||||
"url": "https://github.com/obra/superpowers/blob/main/skills/condition-based-waiting/SKILL.md",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "commands",
|
||||
"url": "https://github.com/obra/superpowers/tree/main/skills/commands",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "dev-agent-skills",
|
||||
"url": "https://github.com/fvadicamo/dev-agent-skills",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "claude-bootstrap",
|
||||
"url": "https://github.com/alinaqi/claude-bootstrap",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "recursive-decomposition-skill",
|
||||
"url": "https://github.com/massimodeluisa/recursive-decomposition-skill",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "react-native-best-practices",
|
||||
"url": "https://github.com/callstackincubator/agent-skills/blob/main/skills/react-native-best-practices/SKILL.md",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "swift-patterns-skill",
|
||||
"url": "https://github.com/efremidze/swift-patterns-skill/tree/main/swift-patterns",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "ai-research-skills",
|
||||
"url": "https://github.com/zechenzhangAGI/AI-research-SKILLs",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "n8n-code-javascript",
|
||||
"url": "https://github.com/czlonkowski/n8n-skills/tree/main/skills/n8n-code-javascript",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "n8n-expression-syntax",
|
||||
"url": "https://github.com/czlonkowski/n8n-skills/tree/main/skills/n8n-expression-syntax",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "n8n-validation-expert",
|
||||
"url": "https://github.com/czlonkowski/n8n-skills/tree/main/skills/n8n-validation-expert",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "n8n-workflow-patterns",
|
||||
"url": "https://github.com/czlonkowski/n8n-skills/tree/main/skills/n8n-workflow-patterns",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
},
|
||||
{
|
||||
"name": "materials-simulation-skills",
|
||||
"url": "https://github.com/HeshamFS/materials-simulation-skills",
|
||||
"reason": "SKILL.md not found or URL inaccessible"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
22
skills/SPDD/1-research.md
Normal file
22
skills/SPDD/1-research.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# ROLE: Codebase Research Agent
|
||||
Sua única missão é documentar e explicar a base de código como ela existe hoje.
|
||||
|
||||
## CRITICAL RULES:
|
||||
- NÃO sugira melhorias, refatorações ou mudanças arquiteturais.
|
||||
- NÃO realize análise de causa raiz ou proponha melhorias futuras.
|
||||
- APENAS descreva o que existe, onde existe e como os componentes interagem.
|
||||
- Você é um cartógrafo técnico criando um mapa do sistema atual.
|
||||
|
||||
## STEPS TO FOLLOW:
|
||||
1. **Initial Analysis:** Leia os arquivos mencionados pelo usuário integralmente (SEM limit/offset).
|
||||
2. **Decomposition:** Decompunha a dúvida do usuário em áreas de pesquisa (ex: Rotas, Banco, UI).
|
||||
3. **Execution:** - Localize onde os arquivos e componentes vivem.
|
||||
- Analise COMO o código atual funciona (sem criticar).
|
||||
- Encontre exemplos de padrões existentes para referência.
|
||||
4. **Project State:**
|
||||
- Se projeto NOVO: Pesquise e liste a melhor estrutura de pastas e bibliotecas padrão de mercado para a stack.
|
||||
- Se projeto EXISTENTE: Identifique dívidas técnicas ou padrões que devem ser respeitados.
|
||||
|
||||
## OUTPUT:
|
||||
- Gere o arquivo `docs/prds/prd_current_task.md` com YAML frontmatter (date, topic, tags, status).
|
||||
- **Ação Obrigatória:** Termine com: "Pesquisa concluída. Por favor, dê um `/clear` e carregue `.agente/2-spec.md` para o planejamento."
|
||||
20
skills/SPDD/2-spec.md
Normal file
20
skills/SPDD/2-spec.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# ROLE: Implementation Planning Agent
|
||||
Você deve criar planos de implementação detalhados e ser cético quanto a requisitos vagos.
|
||||
|
||||
## CRITICAL RULES:
|
||||
- Não escreva o plano de uma vez; valide a estrutura das fases com o usuário.
|
||||
- Cada decisão técnica deve ser tomada antes de finalizar o plano.
|
||||
- O plano deve ser acionável e completo, sem "perguntas abertas".
|
||||
|
||||
## STEPS TO FOLLOW:
|
||||
1. **Context Check:** Leia o `docs/prds/prd_current_task.md` gerado anteriormente.
|
||||
2. **Phasing:** Divida o trabalho em fases incrementais e testáveis.
|
||||
3. **Detailing:** Para cada arquivo afetado, defina:
|
||||
- **Path exato.**
|
||||
- **Ação:** (CRIAR | MODIFICAR | DELETAR).
|
||||
- **Lógica:** Snippets de pseudocódigo ou referências de implementação.
|
||||
4. **Success Criteria:** Defina "Automated Verification" (scripts/testes) e "Manual Verification" (UI/UX).
|
||||
|
||||
## OUTPUT:
|
||||
- Gere o arquivo `docs/specs/spec_current_task.md` seguindo o template de fases.
|
||||
- **Ação Obrigatória:** Termine com: "Spec finalizada. Por favor, dê um `/clear` e carregue `.agente/3-implementation.md` para execução."
|
||||
20
skills/SPDD/3-implementation.md
Normal file
20
skills/SPDD/3-implementation.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# ROLE: Implementation Execution Agent
|
||||
Você deve implementar um plano técnico aprovado com precisão cirúrgica.
|
||||
|
||||
## CRITICAL RULES:
|
||||
- Siga a intenção do plano enquanto se adapta à realidade encontrada.
|
||||
- Implemente uma fase COMPLETAMENTE antes de passar para a próxima.
|
||||
- **STOP & THINK:** Se encontrar um erro na Spec ou um mismatch no código, PARE e reporte. Não tente adivinhar.
|
||||
|
||||
## STEPS TO FOLLOW:
|
||||
1. **Sanity Check:** Leia a Spec e o Ticket original. Verifique se o ambiente está limpo.
|
||||
2. **Execution:** Codifique seguindo os padrões de Clean Code e os snippets da Spec.
|
||||
3. **Verification:**
|
||||
- Após cada fase, execute os comandos de "Automated Verification" descritos na Spec.
|
||||
- PAUSE para confirmação manual do usuário após cada fase concluída.
|
||||
4. **Progress:** Atualize os checkboxes (- [x]) no arquivo de Spec conforme avança.
|
||||
|
||||
## OUTPUT:
|
||||
- Código fonte implementado.
|
||||
- Relatório de conclusão de fase com resultados de testes.
|
||||
- **Ação Final:** Pergunte se o usuário deseja realizar testes de regressão ou seguir para a próxima task.
|
||||
@@ -292,7 +292,7 @@ jobs:
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
tag_name: ${{ steps.version.outputs.tag }}
|
||||
body_path: RELEASE_NOTES.md
|
||||
body_path: CHANGELOG.md
|
||||
generate_release_notes: true
|
||||
```
|
||||
|
||||
@@ -368,7 +368,7 @@ repo = "repo"
|
||||
git cliff -o CHANGELOG.md
|
||||
|
||||
# Generate for specific range
|
||||
git cliff v1.0.0..v2.0.0 -o RELEASE_NOTES.md
|
||||
git cliff v1.0.0..v2.0.0 -o CHANGELOG.md
|
||||
|
||||
# Preview without writing
|
||||
git cliff --unreleased --dry-run
|
||||
|
||||
856
skills/fp-ts-errors/SKILL.md
Normal file
856
skills/fp-ts-errors/SKILL.md
Normal file
@@ -0,0 +1,856 @@
|
||||
---
|
||||
name: fp-ts-errors
|
||||
description: Handle errors as values using fp-ts Either and TaskEither for cleaner, more predictable TypeScript code. Use when implementing error handling patterns with fp-ts.
|
||||
risk: safe
|
||||
source: https://github.com/whatiskadudoing/fp-ts-skills
|
||||
---
|
||||
|
||||
# Practical Error Handling with fp-ts
|
||||
|
||||
This skill teaches you how to handle errors without try/catch spaghetti. No academic jargon - just practical patterns for real problems.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- When you want type-safe error handling in TypeScript
|
||||
- When replacing try/catch with Either and TaskEither patterns
|
||||
- When building APIs or services that need explicit error types
|
||||
- When accumulating multiple validation errors
|
||||
|
||||
The core idea: **Errors are just data**. Instead of throwing them into the void and hoping someone catches them, return them as values that TypeScript can track.
|
||||
|
||||
---
|
||||
|
||||
## 1. Stop Throwing Everywhere
|
||||
|
||||
### The Problem with Exceptions
|
||||
|
||||
Exceptions are invisible in your types. They break the contract between functions.
|
||||
|
||||
```typescript
|
||||
// What this function signature promises:
|
||||
function getUser(id: string): User
|
||||
|
||||
// What it actually does:
|
||||
function getUser(id: string): User {
|
||||
if (!id) throw new Error('ID required')
|
||||
const user = db.find(id)
|
||||
if (!user) throw new Error('User not found')
|
||||
return user
|
||||
}
|
||||
|
||||
// The caller has no idea this can fail
|
||||
const user = getUser(id) // Might explode!
|
||||
```
|
||||
|
||||
You end up with code like this:
|
||||
|
||||
```typescript
|
||||
// MESSY: try/catch everywhere
|
||||
function processOrder(orderId: string) {
|
||||
let order
|
||||
try {
|
||||
order = getOrder(orderId)
|
||||
} catch (e) {
|
||||
console.error('Failed to get order')
|
||||
return null
|
||||
}
|
||||
|
||||
let user
|
||||
try {
|
||||
user = getUser(order.userId)
|
||||
} catch (e) {
|
||||
console.error('Failed to get user')
|
||||
return null
|
||||
}
|
||||
|
||||
let payment
|
||||
try {
|
||||
payment = chargeCard(user.cardId, order.total)
|
||||
} catch (e) {
|
||||
console.error('Payment failed')
|
||||
return null
|
||||
}
|
||||
|
||||
return { order, user, payment }
|
||||
}
|
||||
```
|
||||
|
||||
### The Solution: Return Errors as Values
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Now TypeScript KNOWS this can fail
|
||||
function getUser(id: string): E.Either<string, User> {
|
||||
if (!id) return E.left('ID required')
|
||||
const user = db.find(id)
|
||||
if (!user) return E.left('User not found')
|
||||
return E.right(user)
|
||||
}
|
||||
|
||||
// The caller is forced to handle both cases
|
||||
const result = getUser(id)
|
||||
// result is Either<string, User> - error OR success, never both
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. The Result Pattern (Either)
|
||||
|
||||
`Either<E, A>` is simple: it holds either an error (`E`) or a value (`A`).
|
||||
|
||||
- `Left` = error case
|
||||
- `Right` = success case (think "right" as in "correct")
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
|
||||
// Creating values
|
||||
const success = E.right(42) // Right(42)
|
||||
const failure = E.left('Oops') // Left('Oops')
|
||||
|
||||
// Checking what you have
|
||||
if (E.isRight(result)) {
|
||||
console.log(result.right) // The success value
|
||||
} else {
|
||||
console.log(result.left) // The error
|
||||
}
|
||||
|
||||
// Better: pattern match with fold
|
||||
const message = pipe(
|
||||
result,
|
||||
E.fold(
|
||||
(error) => `Failed: ${error}`,
|
||||
(value) => `Got: ${value}`
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Converting Throwing Code to Either
|
||||
|
||||
```typescript
|
||||
// Wrap any throwing function with tryCatch
|
||||
const parseJSON = (json: string): E.Either<Error, unknown> =>
|
||||
E.tryCatch(
|
||||
() => JSON.parse(json),
|
||||
(e) => (e instanceof Error ? e : new Error(String(e)))
|
||||
)
|
||||
|
||||
parseJSON('{"valid": true}') // Right({ valid: true })
|
||||
parseJSON('not json') // Left(SyntaxError: ...)
|
||||
|
||||
// For functions you'll reuse, use tryCatchK
|
||||
const safeParseJSON = E.tryCatchK(
|
||||
JSON.parse,
|
||||
(e) => (e instanceof Error ? e : new Error(String(e)))
|
||||
)
|
||||
```
|
||||
|
||||
### Common Either Operations
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Transform the success value
|
||||
const doubled = pipe(
|
||||
E.right(21),
|
||||
E.map(n => n * 2)
|
||||
) // Right(42)
|
||||
|
||||
// Transform the error
|
||||
const betterError = pipe(
|
||||
E.left('bad'),
|
||||
E.mapLeft(e => `Error: ${e}`)
|
||||
) // Left('Error: bad')
|
||||
|
||||
// Provide a default for errors
|
||||
const value = pipe(
|
||||
E.left('failed'),
|
||||
E.getOrElse(() => 0)
|
||||
) // 0
|
||||
|
||||
// Convert nullable to Either
|
||||
const fromNullable = E.fromNullable('not found')
|
||||
fromNullable(user) // Right(user) if exists, Left('not found') if null/undefined
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Chaining Operations That Might Fail
|
||||
|
||||
The real power comes from chaining. Each step can fail, but you write it as a clean pipeline.
|
||||
|
||||
### Before: Nested Try/Catch Hell
|
||||
|
||||
```typescript
|
||||
// MESSY: Each step can fail, nested try/catch everywhere
|
||||
function processUserOrder(userId: string, productId: string): Result | null {
|
||||
let user
|
||||
try {
|
||||
user = getUser(userId)
|
||||
} catch (e) {
|
||||
logError('User fetch failed', e)
|
||||
return null
|
||||
}
|
||||
|
||||
if (!user.isActive) {
|
||||
logError('User not active')
|
||||
return null
|
||||
}
|
||||
|
||||
let product
|
||||
try {
|
||||
product = getProduct(productId)
|
||||
} catch (e) {
|
||||
logError('Product fetch failed', e)
|
||||
return null
|
||||
}
|
||||
|
||||
if (product.stock < 1) {
|
||||
logError('Out of stock')
|
||||
return null
|
||||
}
|
||||
|
||||
let order
|
||||
try {
|
||||
order = createOrder(user, product)
|
||||
} catch (e) {
|
||||
logError('Order creation failed', e)
|
||||
return null
|
||||
}
|
||||
|
||||
return order
|
||||
}
|
||||
```
|
||||
|
||||
### After: Clean Chain with Either
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Each function returns Either<Error, T>
|
||||
const getUser = (id: string): E.Either<string, User> => { ... }
|
||||
const getProduct = (id: string): E.Either<string, Product> => { ... }
|
||||
const createOrder = (user: User, product: Product): E.Either<string, Order> => { ... }
|
||||
|
||||
// Chain them together - first error stops the chain
|
||||
const processUserOrder = (userId: string, productId: string): E.Either<string, Order> =>
|
||||
pipe(
|
||||
getUser(userId),
|
||||
E.filterOrElse(
|
||||
user => user.isActive,
|
||||
() => 'User not active'
|
||||
),
|
||||
E.chain(user =>
|
||||
pipe(
|
||||
getProduct(productId),
|
||||
E.filterOrElse(
|
||||
product => product.stock >= 1,
|
||||
() => 'Out of stock'
|
||||
),
|
||||
E.chain(product => createOrder(user, product))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
// Or use Do notation for cleaner access to intermediate values
|
||||
const processUserOrder = (userId: string, productId: string): E.Either<string, Order> =>
|
||||
pipe(
|
||||
E.Do,
|
||||
E.bind('user', () => getUser(userId)),
|
||||
E.filterOrElse(
|
||||
({ user }) => user.isActive,
|
||||
() => 'User not active'
|
||||
),
|
||||
E.bind('product', () => getProduct(productId)),
|
||||
E.filterOrElse(
|
||||
({ product }) => product.stock >= 1,
|
||||
() => 'Out of stock'
|
||||
),
|
||||
E.chain(({ user, product }) => createOrder(user, product))
|
||||
)
|
||||
```
|
||||
|
||||
### Different Error Types? Use chainW
|
||||
|
||||
```typescript
|
||||
type ValidationError = { type: 'validation'; message: string }
|
||||
type DbError = { type: 'db'; message: string }
|
||||
|
||||
const validateInput = (id: string): E.Either<ValidationError, string> => { ... }
|
||||
const fetchFromDb = (id: string): E.Either<DbError, User> => { ... }
|
||||
|
||||
// chainW (W = "wider") automatically unions the error types
|
||||
const process = (id: string): E.Either<ValidationError | DbError, User> =>
|
||||
pipe(
|
||||
validateInput(id),
|
||||
E.chainW(validId => fetchFromDb(validId))
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Collecting Multiple Errors
|
||||
|
||||
Sometimes you want ALL errors, not just the first one. Form validation is the classic example.
|
||||
|
||||
### Before: Collecting Errors Manually
|
||||
|
||||
```typescript
|
||||
// MESSY: Manual error accumulation
|
||||
function validateForm(form: FormData): { valid: boolean; errors: string[] } {
|
||||
const errors: string[] = []
|
||||
|
||||
if (!form.email) {
|
||||
errors.push('Email required')
|
||||
} else if (!form.email.includes('@')) {
|
||||
errors.push('Invalid email')
|
||||
}
|
||||
|
||||
if (!form.password) {
|
||||
errors.push('Password required')
|
||||
} else if (form.password.length < 8) {
|
||||
errors.push('Password too short')
|
||||
}
|
||||
|
||||
if (!form.age) {
|
||||
errors.push('Age required')
|
||||
} else if (form.age < 18) {
|
||||
errors.push('Must be 18+')
|
||||
}
|
||||
|
||||
return { valid: errors.length === 0, errors }
|
||||
}
|
||||
```
|
||||
|
||||
### After: Validation with Error Accumulation
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import * as NEA from 'fp-ts/NonEmptyArray'
|
||||
import { sequenceS } from 'fp-ts/Apply'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Errors as a NonEmptyArray (always at least one)
|
||||
type Errors = NEA.NonEmptyArray<string>
|
||||
|
||||
// Create the applicative that accumulates errors
|
||||
const validation = E.getApplicativeValidation(NEA.getSemigroup<string>())
|
||||
|
||||
// Validators that return Either<Errors, T>
|
||||
const validateEmail = (email: string): E.Either<Errors, string> =>
|
||||
!email ? E.left(NEA.of('Email required'))
|
||||
: !email.includes('@') ? E.left(NEA.of('Invalid email'))
|
||||
: E.right(email)
|
||||
|
||||
const validatePassword = (password: string): E.Either<Errors, string> =>
|
||||
!password ? E.left(NEA.of('Password required'))
|
||||
: password.length < 8 ? E.left(NEA.of('Password too short'))
|
||||
: E.right(password)
|
||||
|
||||
const validateAge = (age: number | undefined): E.Either<Errors, number> =>
|
||||
age === undefined ? E.left(NEA.of('Age required'))
|
||||
: age < 18 ? E.left(NEA.of('Must be 18+'))
|
||||
: E.right(age)
|
||||
|
||||
// Combine all validations - collects ALL errors
|
||||
const validateForm = (form: FormData) =>
|
||||
sequenceS(validation)({
|
||||
email: validateEmail(form.email),
|
||||
password: validatePassword(form.password),
|
||||
age: validateAge(form.age)
|
||||
})
|
||||
|
||||
// Usage
|
||||
validateForm({ email: '', password: '123', age: 15 })
|
||||
// Left(['Email required', 'Password too short', 'Must be 18+'])
|
||||
|
||||
validateForm({ email: 'a@b.com', password: 'longpassword', age: 25 })
|
||||
// Right({ email: 'a@b.com', password: 'longpassword', age: 25 })
|
||||
```
|
||||
|
||||
### Field-Level Errors for Forms
|
||||
|
||||
```typescript
|
||||
interface FieldError {
|
||||
field: string
|
||||
message: string
|
||||
}
|
||||
|
||||
type FormErrors = NEA.NonEmptyArray<FieldError>
|
||||
|
||||
const fieldError = (field: string, message: string): FormErrors =>
|
||||
NEA.of({ field, message })
|
||||
|
||||
const formValidation = E.getApplicativeValidation(NEA.getSemigroup<FieldError>())
|
||||
|
||||
// Now errors know which field they belong to
|
||||
const validateEmail = (email: string): E.Either<FormErrors, string> =>
|
||||
!email ? E.left(fieldError('email', 'Required'))
|
||||
: !email.includes('@') ? E.left(fieldError('email', 'Invalid format'))
|
||||
: E.right(email)
|
||||
|
||||
// Easy to display in UI
|
||||
const getFieldError = (errors: FormErrors, field: string): string | undefined =>
|
||||
errors.find(e => e.field === field)?.message
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Async Operations (TaskEither)
|
||||
|
||||
For async operations that can fail, use `TaskEither`. It's like `Either` but for promises.
|
||||
|
||||
- `TaskEither<E, A>` = a function that returns `Promise<Either<E, A>>`
|
||||
- Lazy: nothing runs until you execute it
|
||||
|
||||
```typescript
|
||||
import * as TE from 'fp-ts/TaskEither'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Wrap any async operation
|
||||
const fetchUser = (id: string): TE.TaskEither<Error, User> =>
|
||||
TE.tryCatch(
|
||||
() => fetch(`/api/users/${id}`).then(r => r.json()),
|
||||
(e) => (e instanceof Error ? e : new Error(String(e)))
|
||||
)
|
||||
|
||||
// Chain async operations - just like Either
|
||||
const getUserPosts = (userId: string): TE.TaskEither<Error, Post[]> =>
|
||||
pipe(
|
||||
fetchUser(userId),
|
||||
TE.chain(user => fetchPosts(user.id))
|
||||
)
|
||||
|
||||
// Execute when ready
|
||||
const result = await getUserPosts('123')() // Returns Either<Error, Post[]>
|
||||
```
|
||||
|
||||
### Before: Promise Chain with Error Handling
|
||||
|
||||
```typescript
|
||||
// MESSY: try/catch mixed with promise chains
|
||||
async function loadDashboard(userId: string) {
|
||||
try {
|
||||
const user = await fetchUser(userId)
|
||||
if (!user) throw new Error('User not found')
|
||||
|
||||
let posts, notifications, settings
|
||||
try {
|
||||
[posts, notifications, settings] = await Promise.all([
|
||||
fetchPosts(user.id),
|
||||
fetchNotifications(user.id),
|
||||
fetchSettings(user.id)
|
||||
])
|
||||
} catch (e) {
|
||||
// Which one failed? Who knows!
|
||||
console.error('Failed to load data', e)
|
||||
return null
|
||||
}
|
||||
|
||||
return { user, posts, notifications, settings }
|
||||
} catch (e) {
|
||||
console.error('Failed to load user', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### After: Clean TaskEither Pipeline
|
||||
|
||||
```typescript
|
||||
import * as TE from 'fp-ts/TaskEither'
|
||||
import { sequenceS } from 'fp-ts/Apply'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
const loadDashboard = (userId: string) =>
|
||||
pipe(
|
||||
fetchUser(userId),
|
||||
TE.chain(user =>
|
||||
pipe(
|
||||
// Parallel fetch with sequenceS
|
||||
sequenceS(TE.ApplyPar)({
|
||||
posts: fetchPosts(user.id),
|
||||
notifications: fetchNotifications(user.id),
|
||||
settings: fetchSettings(user.id)
|
||||
}),
|
||||
TE.map(data => ({ user, ...data }))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
// Execute and handle both cases
|
||||
pipe(
|
||||
loadDashboard('123'),
|
||||
TE.fold(
|
||||
(error) => T.of(renderError(error)),
|
||||
(data) => T.of(renderDashboard(data))
|
||||
)
|
||||
)()
|
||||
```
|
||||
|
||||
### Retry Failed Operations
|
||||
|
||||
```typescript
|
||||
import * as T from 'fp-ts/Task'
|
||||
import * as TE from 'fp-ts/TaskEither'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
const retry = <E, A>(
|
||||
task: TE.TaskEither<E, A>,
|
||||
attempts: number,
|
||||
delayMs: number
|
||||
): TE.TaskEither<E, A> =>
|
||||
pipe(
|
||||
task,
|
||||
TE.orElse((error) =>
|
||||
attempts > 1
|
||||
? pipe(
|
||||
T.delay(delayMs)(T.of(undefined)),
|
||||
T.chain(() => retry(task, attempts - 1, delayMs * 2))
|
||||
)
|
||||
: TE.left(error)
|
||||
)
|
||||
)
|
||||
|
||||
// Retry up to 3 times with exponential backoff
|
||||
const fetchWithRetry = retry(fetchUser('123'), 3, 1000)
|
||||
```
|
||||
|
||||
### Fallback to Alternative
|
||||
|
||||
```typescript
|
||||
// Try cache first, fall back to API
|
||||
const getUserData = (id: string) =>
|
||||
pipe(
|
||||
fetchFromCache(id),
|
||||
TE.orElse(() => fetchFromApi(id)),
|
||||
TE.orElse(() => TE.right(defaultUser)) // Last resort default
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Converting Between Patterns
|
||||
|
||||
Real codebases have throwing functions, nullable values, and promises. Here's how to work with them.
|
||||
|
||||
### From Nullable to Either
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import * as O from 'fp-ts/Option'
|
||||
|
||||
// Direct conversion
|
||||
const user = users.find(u => u.id === id) // User | undefined
|
||||
const result = E.fromNullable('User not found')(user)
|
||||
|
||||
// From Option
|
||||
const maybeUser: O.Option<User> = O.fromNullable(user)
|
||||
const eitherUser = pipe(
|
||||
maybeUser,
|
||||
E.fromOption(() => 'User not found')
|
||||
)
|
||||
```
|
||||
|
||||
### From Throwing Function to Either
|
||||
|
||||
```typescript
|
||||
// Wrap at the boundary
|
||||
const safeParse = <T>(schema: ZodSchema<T>) => (data: unknown): E.Either<ZodError, T> =>
|
||||
E.tryCatch(
|
||||
() => schema.parse(data),
|
||||
(e) => e as ZodError
|
||||
)
|
||||
|
||||
// Use throughout your code
|
||||
const parseUser = safeParse(UserSchema)
|
||||
const result = parseUser(rawData) // Either<ZodError, User>
|
||||
```
|
||||
|
||||
### From Promise to TaskEither
|
||||
|
||||
```typescript
|
||||
import * as TE from 'fp-ts/TaskEither'
|
||||
|
||||
// Wrap external async functions
|
||||
const fetchJson = <T>(url: string): TE.TaskEither<Error, T> =>
|
||||
TE.tryCatch(
|
||||
() => fetch(url).then(r => r.json()),
|
||||
(e) => new Error(`Fetch failed: ${e}`)
|
||||
)
|
||||
|
||||
// Wrap axios, prisma, any async library
|
||||
const getUserFromDb = (id: string): TE.TaskEither<DbError, User> =>
|
||||
TE.tryCatch(
|
||||
() => prisma.user.findUniqueOrThrow({ where: { id } }),
|
||||
(e) => ({ code: 'DB_ERROR', cause: e })
|
||||
)
|
||||
```
|
||||
|
||||
### Back to Promise (Escape Hatch)
|
||||
|
||||
Sometimes you need a plain Promise for external APIs.
|
||||
|
||||
```typescript
|
||||
import * as TE from 'fp-ts/TaskEither'
|
||||
import * as E from 'fp-ts/Either'
|
||||
|
||||
const myTaskEither: TE.TaskEither<Error, User> = fetchUser('123')
|
||||
|
||||
// Option 1: Get the Either (preserves both cases)
|
||||
const either: E.Either<Error, User> = await myTaskEither()
|
||||
|
||||
// Option 2: Throw on error (for legacy code)
|
||||
const toThrowingPromise = <E, A>(te: TE.TaskEither<E, A>): Promise<A> =>
|
||||
te().then(E.fold(
|
||||
(error) => Promise.reject(error),
|
||||
(value) => Promise.resolve(value)
|
||||
))
|
||||
|
||||
const user = await toThrowingPromise(fetchUser('123')) // Throws if Left
|
||||
|
||||
// Option 3: Default on error
|
||||
const user = await pipe(
|
||||
fetchUser('123'),
|
||||
TE.getOrElse(() => T.of(defaultUser))
|
||||
)()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real Scenarios
|
||||
|
||||
### Parse User Input Safely
|
||||
|
||||
```typescript
|
||||
interface ParsedInput {
|
||||
id: number
|
||||
name: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
const parseInput = (raw: unknown): E.Either<string, ParsedInput> =>
|
||||
pipe(
|
||||
E.Do,
|
||||
E.bind('obj', () =>
|
||||
typeof raw === 'object' && raw !== null
|
||||
? E.right(raw as Record<string, unknown>)
|
||||
: E.left('Input must be an object')
|
||||
),
|
||||
E.bind('id', ({ obj }) =>
|
||||
typeof obj.id === 'number'
|
||||
? E.right(obj.id)
|
||||
: E.left('id must be a number')
|
||||
),
|
||||
E.bind('name', ({ obj }) =>
|
||||
typeof obj.name === 'string' && obj.name.length > 0
|
||||
? E.right(obj.name)
|
||||
: E.left('name must be a non-empty string')
|
||||
),
|
||||
E.bind('tags', ({ obj }) =>
|
||||
Array.isArray(obj.tags) && obj.tags.every(t => typeof t === 'string')
|
||||
? E.right(obj.tags as string[])
|
||||
: E.left('tags must be an array of strings')
|
||||
),
|
||||
E.map(({ id, name, tags }) => ({ id, name, tags }))
|
||||
)
|
||||
|
||||
// Usage
|
||||
parseInput({ id: 1, name: 'test', tags: ['a', 'b'] })
|
||||
// Right({ id: 1, name: 'test', tags: ['a', 'b'] })
|
||||
|
||||
parseInput({ id: 'wrong', name: '', tags: null })
|
||||
// Left('id must be a number')
|
||||
```
|
||||
|
||||
### API Call with Full Error Handling
|
||||
|
||||
```typescript
|
||||
interface ApiError {
|
||||
code: string
|
||||
message: string
|
||||
status?: number
|
||||
}
|
||||
|
||||
const createApiError = (message: string, code = 'UNKNOWN', status?: number): ApiError =>
|
||||
({ code, message, status })
|
||||
|
||||
const fetchWithErrorHandling = <T>(url: string): TE.TaskEither<ApiError, T> =>
|
||||
pipe(
|
||||
TE.tryCatch(
|
||||
() => fetch(url),
|
||||
() => createApiError('Network error', 'NETWORK')
|
||||
),
|
||||
TE.chain(response =>
|
||||
response.ok
|
||||
? TE.tryCatch(
|
||||
() => response.json() as Promise<T>,
|
||||
() => createApiError('Invalid JSON', 'PARSE')
|
||||
)
|
||||
: TE.left(createApiError(
|
||||
`HTTP ${response.status}`,
|
||||
response.status === 404 ? 'NOT_FOUND' : 'HTTP_ERROR',
|
||||
response.status
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
// Usage with pattern matching on error codes
|
||||
const handleUserFetch = (userId: string) =>
|
||||
pipe(
|
||||
fetchWithErrorHandling<User>(`/api/users/${userId}`),
|
||||
TE.fold(
|
||||
(error) => {
|
||||
switch (error.code) {
|
||||
case 'NOT_FOUND': return T.of(showNotFoundPage())
|
||||
case 'NETWORK': return T.of(showOfflineMessage())
|
||||
default: return T.of(showGenericError(error.message))
|
||||
}
|
||||
},
|
||||
(user) => T.of(showUserProfile(user))
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Process List Where Some Items Might Fail
|
||||
|
||||
```typescript
|
||||
import * as A from 'fp-ts/Array'
|
||||
import * as E from 'fp-ts/Either'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
interface ProcessResult<T> {
|
||||
successes: T[]
|
||||
failures: Array<{ item: unknown; error: string }>
|
||||
}
|
||||
|
||||
// Process all, collect successes and failures separately
|
||||
const processAllCollectErrors = <T, R>(
|
||||
items: T[],
|
||||
process: (item: T) => E.Either<string, R>
|
||||
): ProcessResult<R> => {
|
||||
const results = items.map((item, index) =>
|
||||
pipe(
|
||||
process(item),
|
||||
E.mapLeft(error => ({ item, error, index }))
|
||||
)
|
||||
)
|
||||
|
||||
return {
|
||||
successes: pipe(results, A.filterMap(E.toOption)),
|
||||
failures: pipe(
|
||||
results,
|
||||
A.filterMap(r => E.isLeft(r) ? O.some(r.left) : O.none)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
const parseNumbers = (inputs: string[]) =>
|
||||
processAllCollectErrors(inputs, input => {
|
||||
const n = parseInt(input, 10)
|
||||
return isNaN(n) ? E.left(`Invalid number: ${input}`) : E.right(n)
|
||||
})
|
||||
|
||||
parseNumbers(['1', 'abc', '3', 'def'])
|
||||
// {
|
||||
// successes: [1, 3],
|
||||
// failures: [
|
||||
// { item: 'abc', error: 'Invalid number: abc', index: 1 },
|
||||
// { item: 'def', error: 'Invalid number: def', index: 3 }
|
||||
// ]
|
||||
// }
|
||||
```
|
||||
|
||||
### Bulk Operations with Partial Success
|
||||
|
||||
```typescript
|
||||
import * as TE from 'fp-ts/TaskEither'
|
||||
import * as T from 'fp-ts/Task'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
interface BulkResult<T> {
|
||||
succeeded: T[]
|
||||
failed: Array<{ id: string; error: string }>
|
||||
}
|
||||
|
||||
const bulkProcess = <T>(
|
||||
ids: string[],
|
||||
process: (id: string) => TE.TaskEither<string, T>
|
||||
): T.Task<BulkResult<T>> =>
|
||||
pipe(
|
||||
ids,
|
||||
A.map(id =>
|
||||
pipe(
|
||||
process(id),
|
||||
TE.fold(
|
||||
(error) => T.of({ type: 'failed' as const, id, error }),
|
||||
(result) => T.of({ type: 'succeeded' as const, result })
|
||||
)
|
||||
)
|
||||
),
|
||||
T.sequenceArray,
|
||||
T.map(results => ({
|
||||
succeeded: results
|
||||
.filter((r): r is { type: 'succeeded'; result: T } => r.type === 'succeeded')
|
||||
.map(r => r.result),
|
||||
failed: results
|
||||
.filter((r): r is { type: 'failed'; id: string; error: string } => r.type === 'failed')
|
||||
.map(({ id, error }) => ({ id, error }))
|
||||
}))
|
||||
)
|
||||
|
||||
// Usage
|
||||
const deleteUsers = (userIds: string[]) =>
|
||||
bulkProcess(userIds, id =>
|
||||
pipe(
|
||||
deleteUser(id),
|
||||
TE.mapLeft(e => e.message)
|
||||
)
|
||||
)
|
||||
|
||||
// All operations run, you get a report of what worked and what didn't
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Pattern | Use When | Example |
|
||||
|---------|----------|---------|
|
||||
| `E.right(value)` | Creating a success | `E.right(42)` |
|
||||
| `E.left(error)` | Creating a failure | `E.left('not found')` |
|
||||
| `E.tryCatch(fn, onError)` | Wrapping throwing code | `E.tryCatch(() => JSON.parse(s), toError)` |
|
||||
| `E.fromNullable(error)` | Converting nullable | `E.fromNullable('missing')(maybeValue)` |
|
||||
| `E.map(fn)` | Transform success | `pipe(result, E.map(x => x * 2))` |
|
||||
| `E.mapLeft(fn)` | Transform error | `pipe(result, E.mapLeft(addContext))` |
|
||||
| `E.chain(fn)` | Chain operations | `pipe(getA(), E.chain(a => getB(a.id)))` |
|
||||
| `E.chainW(fn)` | Chain with different error type | `pipe(validate(), E.chainW(save))` |
|
||||
| `E.fold(onError, onSuccess)` | Handle both cases | `E.fold(showError, showData)` |
|
||||
| `E.getOrElse(onError)` | Extract with default | `E.getOrElse(() => 0)` |
|
||||
| `E.filterOrElse(pred, onFalse)` | Validate with error | `E.filterOrElse(x => x > 0, () => 'must be positive')` |
|
||||
| `sequenceS(validation)({...})` | Collect all errors | Form validation |
|
||||
|
||||
### TaskEither Equivalents
|
||||
|
||||
All Either operations have TaskEither equivalents:
|
||||
- `TE.right`, `TE.left`, `TE.tryCatch`
|
||||
- `TE.map`, `TE.mapLeft`, `TE.chain`, `TE.chainW`
|
||||
- `TE.fold`, `TE.getOrElse`, `TE.filterOrElse`
|
||||
- `TE.orElse` for fallbacks
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
1. **Return errors as values** - Use Either/TaskEither instead of throwing
|
||||
2. **Chain with confidence** - `chain` stops at first error automatically
|
||||
3. **Collect all errors when needed** - Use validation applicative for forms
|
||||
4. **Wrap at boundaries** - Convert throwing/Promise code at the edges
|
||||
5. **Match at the end** - Use `fold` to handle both cases when you're ready to act
|
||||
|
||||
The payoff: TypeScript tracks your errors, no more forgotten try/catch, clear control flow, and composable error handling.
|
||||
598
skills/fp-ts-pragmatic/SKILL.md
Normal file
598
skills/fp-ts-pragmatic/SKILL.md
Normal file
@@ -0,0 +1,598 @@
|
||||
---
|
||||
name: fp-ts-pragmatic
|
||||
description: A practical, jargon-free guide to fp-ts functional programming - the 80/20 approach that gets results without the academic overhead. Use when writing TypeScript with fp-ts library.
|
||||
risk: safe
|
||||
source: https://github.com/whatiskadudoing/fp-ts-skills
|
||||
---
|
||||
|
||||
# Pragmatic Functional Programming
|
||||
|
||||
**Read this first.** This guide cuts through the academic jargon and shows you what actually matters. No category theory. No abstract nonsense. Just patterns that make your code better.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- When starting with fp-ts and need practical guidance
|
||||
- When writing TypeScript code that handles nullable values, errors, or async operations
|
||||
- When you want cleaner, more maintainable functional code without the academic overhead
|
||||
- When refactoring imperative code to functional style
|
||||
|
||||
## The Golden Rule
|
||||
|
||||
> **If functional programming makes your code harder to read, don't use it.**
|
||||
|
||||
FP is a tool, not a religion. Use it when it helps. Skip it when it doesn't.
|
||||
|
||||
---
|
||||
|
||||
## The 80/20 of FP
|
||||
|
||||
These five patterns give you most of the benefits. Master these before exploring anything else.
|
||||
|
||||
### 1. Pipe: Chain Operations Clearly
|
||||
|
||||
Instead of nesting function calls or creating intermediate variables, chain operations in reading order.
|
||||
|
||||
```typescript
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Before: Hard to read (inside-out)
|
||||
const result = format(validate(parse(input)))
|
||||
|
||||
// Before: Too many variables
|
||||
const parsed = parse(input)
|
||||
const validated = validate(parsed)
|
||||
const result = format(validated)
|
||||
|
||||
// After: Clear, linear flow
|
||||
const result = pipe(
|
||||
input,
|
||||
parse,
|
||||
validate,
|
||||
format
|
||||
)
|
||||
```
|
||||
|
||||
**When to use pipe:**
|
||||
- 3+ transformations on the same data
|
||||
- You find yourself naming throwaway variables
|
||||
- Logic reads better top-to-bottom
|
||||
|
||||
**When to skip pipe:**
|
||||
- Just 1-2 operations (direct call is fine)
|
||||
- The operations don't naturally chain
|
||||
|
||||
### 2. Option: Handle Missing Values Without null Checks
|
||||
|
||||
Stop writing `if (x !== null && x !== undefined)` everywhere.
|
||||
|
||||
```typescript
|
||||
import * as O from 'fp-ts/Option'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Before: Defensive null checking
|
||||
function getUserCity(user: User | null): string {
|
||||
if (user === null) return 'Unknown'
|
||||
if (user.address === null) return 'Unknown'
|
||||
if (user.address.city === null) return 'Unknown'
|
||||
return user.address.city
|
||||
}
|
||||
|
||||
// After: Chain through potential missing values
|
||||
const getUserCity = (user: User | null): string =>
|
||||
pipe(
|
||||
O.fromNullable(user),
|
||||
O.flatMap(u => O.fromNullable(u.address)),
|
||||
O.flatMap(a => O.fromNullable(a.city)),
|
||||
O.getOrElse(() => 'Unknown')
|
||||
)
|
||||
```
|
||||
|
||||
**Plain language translation:**
|
||||
- `O.fromNullable(x)` = "wrap this value, treating null/undefined as 'nothing'"
|
||||
- `O.flatMap(fn)` = "if we have something, apply this function"
|
||||
- `O.getOrElse(() => default)` = "unwrap, or use this default if nothing"
|
||||
|
||||
### 3. Either: Make Errors Explicit
|
||||
|
||||
Stop throwing exceptions for expected failures. Return errors as values.
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Before: Hidden failure mode
|
||||
function parseAge(input: string): number {
|
||||
const age = parseInt(input, 10)
|
||||
if (isNaN(age)) throw new Error('Invalid age')
|
||||
if (age < 0) throw new Error('Age cannot be negative')
|
||||
return age
|
||||
}
|
||||
|
||||
// After: Errors are visible in the type
|
||||
function parseAge(input: string): E.Either<string, number> {
|
||||
const age = parseInt(input, 10)
|
||||
if (isNaN(age)) return E.left('Invalid age')
|
||||
if (age < 0) return E.left('Age cannot be negative')
|
||||
return E.right(age)
|
||||
}
|
||||
|
||||
// Using it
|
||||
const result = parseAge(userInput)
|
||||
if (E.isRight(result)) {
|
||||
console.log(`Age is ${result.right}`)
|
||||
} else {
|
||||
console.log(`Error: ${result.left}`)
|
||||
}
|
||||
```
|
||||
|
||||
**Plain language translation:**
|
||||
- `E.right(value)` = "success with this value"
|
||||
- `E.left(error)` = "failure with this error"
|
||||
- `E.isRight(x)` = "did it succeed?"
|
||||
|
||||
### 4. Map: Transform Without Unpacking
|
||||
|
||||
Transform values inside containers without extracting them first.
|
||||
|
||||
```typescript
|
||||
import * as O from 'fp-ts/Option'
|
||||
import * as E from 'fp-ts/Either'
|
||||
import * as A from 'fp-ts/Array'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Transform inside Option
|
||||
const maybeUser: O.Option<User> = O.some({ name: 'Alice', age: 30 })
|
||||
const maybeName: O.Option<string> = pipe(
|
||||
maybeUser,
|
||||
O.map(user => user.name)
|
||||
)
|
||||
|
||||
// Transform inside Either
|
||||
const result: E.Either<Error, number> = E.right(5)
|
||||
const doubled: E.Either<Error, number> = pipe(
|
||||
result,
|
||||
E.map(n => n * 2)
|
||||
)
|
||||
|
||||
// Transform arrays (same concept!)
|
||||
const numbers = [1, 2, 3]
|
||||
const doubled = pipe(
|
||||
numbers,
|
||||
A.map(n => n * 2)
|
||||
)
|
||||
```
|
||||
|
||||
### 5. FlatMap: Chain Operations That Might Fail
|
||||
|
||||
When each step might fail, chain them together.
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
const parseJSON = (s: string): E.Either<string, unknown> =>
|
||||
E.tryCatch(() => JSON.parse(s), () => 'Invalid JSON')
|
||||
|
||||
const extractEmail = (data: unknown): E.Either<string, string> => {
|
||||
if (typeof data === 'object' && data !== null && 'email' in data) {
|
||||
return E.right((data as { email: string }).email)
|
||||
}
|
||||
return E.left('No email field')
|
||||
}
|
||||
|
||||
const validateEmail = (email: string): E.Either<string, string> =>
|
||||
email.includes('@') ? E.right(email) : E.left('Invalid email format')
|
||||
|
||||
// Chain all steps - if any fails, the whole thing fails
|
||||
const getValidEmail = (input: string): E.Either<string, string> =>
|
||||
pipe(
|
||||
parseJSON(input),
|
||||
E.flatMap(extractEmail),
|
||||
E.flatMap(validateEmail)
|
||||
)
|
||||
|
||||
// Success path: Right('user@example.com')
|
||||
// Any failure: Left('specific error message')
|
||||
```
|
||||
|
||||
**Plain language:** `flatMap` means "if this succeeded, try the next thing"
|
||||
|
||||
---
|
||||
|
||||
## When NOT to Use FP
|
||||
|
||||
Functional programming is not always the answer. Here's when to keep it simple.
|
||||
|
||||
### Simple Null Checks
|
||||
|
||||
```typescript
|
||||
// Just use optional chaining - it's built into the language
|
||||
const city = user?.address?.city ?? 'Unknown'
|
||||
|
||||
// DON'T overcomplicate it
|
||||
const city = pipe(
|
||||
O.fromNullable(user),
|
||||
O.flatMap(u => O.fromNullable(u.address)),
|
||||
O.flatMap(a => O.fromNullable(a.city)),
|
||||
O.getOrElse(() => 'Unknown')
|
||||
)
|
||||
```
|
||||
|
||||
### Simple Loops
|
||||
|
||||
```typescript
|
||||
// A for loop is fine when you need early exit or complex logic
|
||||
function findFirst(items: Item[], predicate: (i: Item) => boolean): Item | null {
|
||||
for (const item of items) {
|
||||
if (predicate(item)) return item
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// DON'T force FP when it doesn't help
|
||||
const result = pipe(
|
||||
items,
|
||||
A.findFirst(predicate),
|
||||
O.toNullable
|
||||
)
|
||||
```
|
||||
|
||||
### Performance-Critical Code
|
||||
|
||||
```typescript
|
||||
// For hot paths, imperative is faster (no intermediate arrays)
|
||||
function sumLarge(numbers: number[]): number {
|
||||
let sum = 0
|
||||
for (let i = 0; i < numbers.length; i++) {
|
||||
sum += numbers[i]
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// fp-ts creates intermediate structures
|
||||
const sum = pipe(numbers, A.reduce(0, (acc, n) => acc + n))
|
||||
```
|
||||
|
||||
### When Your Team Doesn't Know FP
|
||||
|
||||
If you're the only one who can read the code, it's not good code.
|
||||
|
||||
```typescript
|
||||
// If your team knows this pattern
|
||||
async function getUser(id: string): Promise<User | null> {
|
||||
try {
|
||||
const response = await fetch(`/api/users/${id}`)
|
||||
if (!response.ok) return null
|
||||
return await response.json()
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// Don't force this on them
|
||||
const getUser = (id: string): TE.TaskEither<Error, User> =>
|
||||
pipe(
|
||||
TE.tryCatch(() => fetch(`/api/users/${id}`), E.toError),
|
||||
TE.flatMap(r => r.ok ? TE.right(r) : TE.left(new Error('Not found'))),
|
||||
TE.flatMap(r => TE.tryCatch(() => r.json(), E.toError))
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Wins: Easy Changes That Improve Code Today
|
||||
|
||||
### 1. Replace Nested Ternaries with pipe + fold
|
||||
|
||||
```typescript
|
||||
// Before: Nested ternary nightmare
|
||||
const message = user === null
|
||||
? 'No user'
|
||||
: user.isAdmin
|
||||
? `Admin: ${user.name}`
|
||||
: `User: ${user.name}`
|
||||
|
||||
// After: Clear case handling
|
||||
const message = pipe(
|
||||
O.fromNullable(user),
|
||||
O.fold(
|
||||
() => 'No user',
|
||||
(u) => u.isAdmin ? `Admin: ${u.name}` : `User: ${u.name}`
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### 2. Replace try-catch with tryCatch
|
||||
|
||||
```typescript
|
||||
// Before: try-catch everywhere
|
||||
let config
|
||||
try {
|
||||
config = JSON.parse(rawConfig)
|
||||
} catch {
|
||||
config = defaultConfig
|
||||
}
|
||||
|
||||
// After: One-liner
|
||||
const config = pipe(
|
||||
E.tryCatch(() => JSON.parse(rawConfig), () => 'parse error'),
|
||||
E.getOrElse(() => defaultConfig)
|
||||
)
|
||||
```
|
||||
|
||||
### 3. Replace undefined Returns with Option
|
||||
|
||||
```typescript
|
||||
// Before: Caller might forget to check
|
||||
function findUser(id: string): User | undefined {
|
||||
return users.find(u => u.id === id)
|
||||
}
|
||||
|
||||
// After: Type forces caller to handle missing case
|
||||
function findUser(id: string): O.Option<User> {
|
||||
return O.fromNullable(users.find(u => u.id === id))
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Replace Error Strings with Typed Errors
|
||||
|
||||
```typescript
|
||||
// Before: Just strings
|
||||
function validate(data: unknown): E.Either<string, User> {
|
||||
// ...
|
||||
return E.left('validation failed')
|
||||
}
|
||||
|
||||
// After: Structured errors
|
||||
type ValidationError = {
|
||||
field: string
|
||||
message: string
|
||||
}
|
||||
|
||||
function validate(data: unknown): E.Either<ValidationError, User> {
|
||||
// ...
|
||||
return E.left({ field: 'email', message: 'Invalid format' })
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Use const Assertions for Error Types
|
||||
|
||||
```typescript
|
||||
// Create specific error types without classes
|
||||
const NotFound = (id: string) => ({ _tag: 'NotFound' as const, id })
|
||||
const Unauthorized = { _tag: 'Unauthorized' as const }
|
||||
const ValidationFailed = (errors: string[]) =>
|
||||
({ _tag: 'ValidationFailed' as const, errors })
|
||||
|
||||
type AppError =
|
||||
| ReturnType<typeof NotFound>
|
||||
| typeof Unauthorized
|
||||
| ReturnType<typeof ValidationFailed>
|
||||
|
||||
// Now you can pattern match
|
||||
const handleError = (error: AppError): string => {
|
||||
switch (error._tag) {
|
||||
case 'NotFound': return `Item ${error.id} not found`
|
||||
case 'Unauthorized': return 'Please log in'
|
||||
case 'ValidationFailed': return error.errors.join(', ')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Refactors: Before and After
|
||||
|
||||
### Callback Hell to Pipe
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
fetchUser(id, (user) => {
|
||||
if (!user) return handleNoUser()
|
||||
fetchPosts(user.id, (posts) => {
|
||||
if (!posts) return handleNoPosts()
|
||||
fetchComments(posts[0].id, (comments) => {
|
||||
render(user, posts, comments)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// After (with TaskEither for async)
|
||||
import * as TE from 'fp-ts/TaskEither'
|
||||
|
||||
const loadData = (id: string) =>
|
||||
pipe(
|
||||
fetchUser(id),
|
||||
TE.flatMap(user => pipe(
|
||||
fetchPosts(user.id),
|
||||
TE.map(posts => ({ user, posts }))
|
||||
)),
|
||||
TE.flatMap(({ user, posts }) => pipe(
|
||||
fetchComments(posts[0].id),
|
||||
TE.map(comments => ({ user, posts, comments }))
|
||||
))
|
||||
)
|
||||
|
||||
// Execute
|
||||
const result = await loadData('123')()
|
||||
pipe(
|
||||
result,
|
||||
E.fold(handleError, ({ user, posts, comments }) => render(user, posts, comments))
|
||||
)
|
||||
```
|
||||
|
||||
### Multiple null Checks to Option Chain
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
function getManagerEmail(employee: Employee): string | null {
|
||||
if (!employee.department) return null
|
||||
if (!employee.department.manager) return null
|
||||
if (!employee.department.manager.email) return null
|
||||
return employee.department.manager.email
|
||||
}
|
||||
|
||||
// After
|
||||
const getManagerEmail = (employee: Employee): O.Option<string> =>
|
||||
pipe(
|
||||
O.fromNullable(employee.department),
|
||||
O.flatMap(d => O.fromNullable(d.manager)),
|
||||
O.flatMap(m => O.fromNullable(m.email))
|
||||
)
|
||||
|
||||
// Use it
|
||||
pipe(
|
||||
getManagerEmail(employee),
|
||||
O.fold(
|
||||
() => sendToDefault(),
|
||||
(email) => sendTo(email)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Validation with Multiple Checks
|
||||
|
||||
```typescript
|
||||
// Before: Throws on first error
|
||||
function validateUser(data: unknown): User {
|
||||
if (!data || typeof data !== 'object') throw new Error('Must be object')
|
||||
const obj = data as Record<string, unknown>
|
||||
if (typeof obj.email !== 'string') throw new Error('Email required')
|
||||
if (!obj.email.includes('@')) throw new Error('Invalid email')
|
||||
if (typeof obj.age !== 'number') throw new Error('Age required')
|
||||
if (obj.age < 0) throw new Error('Age must be positive')
|
||||
return obj as User
|
||||
}
|
||||
|
||||
// After: Returns first error, type-safe
|
||||
const validateUser = (data: unknown): E.Either<string, User> =>
|
||||
pipe(
|
||||
E.Do,
|
||||
E.bind('obj', () =>
|
||||
typeof data === 'object' && data !== null
|
||||
? E.right(data as Record<string, unknown>)
|
||||
: E.left('Must be object')
|
||||
),
|
||||
E.bind('email', ({ obj }) =>
|
||||
typeof obj.email === 'string' && obj.email.includes('@')
|
||||
? E.right(obj.email)
|
||||
: E.left('Valid email required')
|
||||
),
|
||||
E.bind('age', ({ obj }) =>
|
||||
typeof obj.age === 'number' && obj.age >= 0
|
||||
? E.right(obj.age)
|
||||
: E.left('Valid age required')
|
||||
),
|
||||
E.map(({ email, age }) => ({ email, age }))
|
||||
)
|
||||
```
|
||||
|
||||
### Promise Chain to TaskEither
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
async function processOrder(orderId: string): Promise<Receipt> {
|
||||
const order = await fetchOrder(orderId)
|
||||
if (!order) throw new Error('Order not found')
|
||||
|
||||
const validated = await validateOrder(order)
|
||||
if (!validated.success) throw new Error(validated.error)
|
||||
|
||||
const payment = await processPayment(validated.order)
|
||||
if (!payment.success) throw new Error('Payment failed')
|
||||
|
||||
return generateReceipt(payment)
|
||||
}
|
||||
|
||||
// After
|
||||
const processOrder = (orderId: string): TE.TaskEither<string, Receipt> =>
|
||||
pipe(
|
||||
fetchOrderTE(orderId),
|
||||
TE.flatMap(order =>
|
||||
order ? TE.right(order) : TE.left('Order not found')
|
||||
),
|
||||
TE.flatMap(validateOrderTE),
|
||||
TE.flatMap(processPaymentTE),
|
||||
TE.map(generateReceipt)
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## The Readability Rule
|
||||
|
||||
Before using any FP pattern, ask: **"Would a junior developer understand this?"**
|
||||
|
||||
### Too Clever (Avoid)
|
||||
|
||||
```typescript
|
||||
const result = pipe(
|
||||
data,
|
||||
A.filter(flow(prop('status'), equals('active'))),
|
||||
A.map(flow(prop('value'), multiply(2))),
|
||||
A.reduce(monoid.concat, monoid.empty),
|
||||
O.fromPredicate(gt(threshold))
|
||||
)
|
||||
```
|
||||
|
||||
### Just Right (Prefer)
|
||||
|
||||
```typescript
|
||||
const activeItems = data.filter(item => item.status === 'active')
|
||||
const doubledValues = activeItems.map(item => item.value * 2)
|
||||
const total = doubledValues.reduce((sum, val) => sum + val, 0)
|
||||
const result = total > threshold ? O.some(total) : O.none
|
||||
```
|
||||
|
||||
### The Middle Ground (Often Best)
|
||||
|
||||
```typescript
|
||||
const result = pipe(
|
||||
data,
|
||||
A.filter(item => item.status === 'active'),
|
||||
A.map(item => item.value * 2),
|
||||
A.reduce(0, (sum, val) => sum + val),
|
||||
total => total > threshold ? O.some(total) : O.none
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cheat Sheet
|
||||
|
||||
| What you want | Plain language | fp-ts |
|
||||
|--------------|----------------|-------|
|
||||
| Handle null/undefined | "Wrap this nullable" | `O.fromNullable(x)` |
|
||||
| Default for missing | "Use this if nothing" | `O.getOrElse(() => default)` |
|
||||
| Transform if present | "If something, change it" | `O.map(fn)` |
|
||||
| Chain nullable operations | "If something, try this" | `O.flatMap(fn)` |
|
||||
| Return success | "Worked, here's the value" | `E.right(value)` |
|
||||
| Return failure | "Failed, here's why" | `E.left(error)` |
|
||||
| Wrap throwing function | "Try this, catch errors" | `E.tryCatch(fn, onError)` |
|
||||
| Handle both cases | "Do this for error, that for success" | `E.fold(onLeft, onRight)` |
|
||||
| Chain operations | "Then do this, then that" | `pipe(x, fn1, fn2, fn3)` |
|
||||
|
||||
---
|
||||
|
||||
## When to Level Up
|
||||
|
||||
Once comfortable with these patterns, explore:
|
||||
|
||||
1. **TaskEither** - Async operations that can fail (replaces Promise + try/catch)
|
||||
2. **Validation** - Collect ALL errors instead of stopping at first
|
||||
3. **Reader** - Dependency injection without classes
|
||||
4. **Do notation** - Cleaner syntax for multiple bindings
|
||||
|
||||
But don't rush. The basics here will handle 80% of real-world scenarios. Get comfortable with these before adding more tools to your belt.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
1. **Use pipe** for 3+ operations
|
||||
2. **Use Option** for nullable chains
|
||||
3. **Use Either** for operations that can fail
|
||||
4. **Use map** to transform wrapped values
|
||||
5. **Use flatMap** to chain operations that might fail
|
||||
6. **Skip FP** when it hurts readability
|
||||
7. **Keep it simple** - if your team can't read it, it's not good code
|
||||
796
skills/fp-ts-react/SKILL.md
Normal file
796
skills/fp-ts-react/SKILL.md
Normal file
@@ -0,0 +1,796 @@
|
||||
---
|
||||
name: fp-ts-react
|
||||
description: Practical patterns for using fp-ts with React - hooks, state, forms, data fetching. Use when building React apps with functional programming patterns. Works with React 18/19, Next.js 14/15.
|
||||
risk: safe
|
||||
source: https://github.com/whatiskadudoing/fp-ts-skills
|
||||
---
|
||||
|
||||
# Functional Programming in React
|
||||
|
||||
Practical patterns for React apps. No jargon, just code that works.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- When building React apps with fp-ts for type-safe state management
|
||||
- When handling loading/error/success states in data fetching
|
||||
- When implementing form validation with error accumulation
|
||||
- When using React 18/19 or Next.js 14/15 with functional patterns
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Pattern | Use When |
|
||||
|---------|----------|
|
||||
| `Option` | Value might be missing (user not loaded yet) |
|
||||
| `Either` | Operation might fail (form validation) |
|
||||
| `TaskEither` | Async operation might fail (API calls) |
|
||||
| `RemoteData` | Need to show loading/error/success states |
|
||||
| `pipe` | Chaining multiple transformations |
|
||||
|
||||
---
|
||||
|
||||
## 1. State with Option (Maybe It's There, Maybe Not)
|
||||
|
||||
Use `Option` instead of `null | undefined` for clearer intent.
|
||||
|
||||
### Basic Pattern
|
||||
|
||||
```typescript
|
||||
import { useState } from 'react'
|
||||
import * as O from 'fp-ts/Option'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
interface User {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
}
|
||||
|
||||
function UserProfile() {
|
||||
// Option says "this might not exist yet"
|
||||
const [user, setUser] = useState<O.Option<User>>(O.none)
|
||||
|
||||
const handleLogin = (userData: User) => {
|
||||
setUser(O.some(userData))
|
||||
}
|
||||
|
||||
const handleLogout = () => {
|
||||
setUser(O.none)
|
||||
}
|
||||
|
||||
return pipe(
|
||||
user,
|
||||
O.match(
|
||||
// When there's no user
|
||||
() => <button onClick={() => handleLogin({ id: '1', name: 'Alice', email: 'alice@example.com' })}>
|
||||
Log In
|
||||
</button>,
|
||||
// When there's a user
|
||||
(u) => (
|
||||
<div>
|
||||
<p>Welcome, {u.name}!</p>
|
||||
<button onClick={handleLogout}>Log Out</button>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Chaining Optional Values
|
||||
|
||||
```typescript
|
||||
import * as O from 'fp-ts/Option'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
interface Profile {
|
||||
user: O.Option<{
|
||||
name: string
|
||||
settings: O.Option<{
|
||||
theme: string
|
||||
}>
|
||||
}>
|
||||
}
|
||||
|
||||
function getTheme(profile: Profile): string {
|
||||
return pipe(
|
||||
profile.user,
|
||||
O.flatMap(u => u.settings),
|
||||
O.map(s => s.theme),
|
||||
O.getOrElse(() => 'light') // default
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Form Validation with Either
|
||||
|
||||
Either is perfect for validation: `Left` = errors, `Right` = valid data.
|
||||
|
||||
### Simple Form Validation
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import * as A from 'fp-ts/Array'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Validation functions return Either<ErrorMessage, ValidValue>
|
||||
const validateEmail = (email: string): E.Either<string, string> =>
|
||||
email.includes('@')
|
||||
? E.right(email)
|
||||
: E.left('Invalid email address')
|
||||
|
||||
const validatePassword = (password: string): E.Either<string, string> =>
|
||||
password.length >= 8
|
||||
? E.right(password)
|
||||
: E.left('Password must be at least 8 characters')
|
||||
|
||||
const validateName = (name: string): E.Either<string, string> =>
|
||||
name.trim().length > 0
|
||||
? E.right(name.trim())
|
||||
: E.left('Name is required')
|
||||
```
|
||||
|
||||
### Collecting All Errors (Not Just First One)
|
||||
|
||||
```typescript
|
||||
import * as E from 'fp-ts/Either'
|
||||
import { sequenceS } from 'fp-ts/Apply'
|
||||
import { getSemigroup } from 'fp-ts/NonEmptyArray'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// This collects ALL errors, not just the first one
|
||||
const validateAll = sequenceS(E.getApplicativeValidation(getSemigroup<string>()))
|
||||
|
||||
interface SignupForm {
|
||||
name: string
|
||||
email: string
|
||||
password: string
|
||||
}
|
||||
|
||||
interface ValidatedForm {
|
||||
name: string
|
||||
email: string
|
||||
password: string
|
||||
}
|
||||
|
||||
function validateForm(form: SignupForm): E.Either<string[], ValidatedForm> {
|
||||
return pipe(
|
||||
validateAll({
|
||||
name: pipe(validateName(form.name), E.mapLeft(e => [e])),
|
||||
email: pipe(validateEmail(form.email), E.mapLeft(e => [e])),
|
||||
password: pipe(validatePassword(form.password), E.mapLeft(e => [e])),
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// Usage in component
|
||||
function SignupForm() {
|
||||
const [form, setForm] = useState({ name: '', email: '', password: '' })
|
||||
const [errors, setErrors] = useState<string[]>([])
|
||||
|
||||
const handleSubmit = () => {
|
||||
pipe(
|
||||
validateForm(form),
|
||||
E.match(
|
||||
(errs) => setErrors(errs), // Show all errors
|
||||
(valid) => {
|
||||
setErrors([])
|
||||
submitToServer(valid) // Submit valid data
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={e => { e.preventDefault(); handleSubmit() }}>
|
||||
<input
|
||||
value={form.name}
|
||||
onChange={e => setForm(f => ({ ...f, name: e.target.value }))}
|
||||
placeholder="Name"
|
||||
/>
|
||||
<input
|
||||
value={form.email}
|
||||
onChange={e => setForm(f => ({ ...f, email: e.target.value }))}
|
||||
placeholder="Email"
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
value={form.password}
|
||||
onChange={e => setForm(f => ({ ...f, password: e.target.value }))}
|
||||
placeholder="Password"
|
||||
/>
|
||||
|
||||
{errors.length > 0 && (
|
||||
<ul style={{ color: 'red' }}>
|
||||
{errors.map((err, i) => <li key={i}>{err}</li>)}
|
||||
</ul>
|
||||
)}
|
||||
|
||||
<button type="submit">Sign Up</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Field-Level Errors (Better UX)
|
||||
|
||||
```typescript
|
||||
type FieldErrors = Partial<Record<keyof SignupForm, string>>
|
||||
|
||||
function validateFormWithFieldErrors(form: SignupForm): E.Either<FieldErrors, ValidatedForm> {
|
||||
const errors: FieldErrors = {}
|
||||
|
||||
pipe(validateName(form.name), E.mapLeft(e => { errors.name = e }))
|
||||
pipe(validateEmail(form.email), E.mapLeft(e => { errors.email = e }))
|
||||
pipe(validatePassword(form.password), E.mapLeft(e => { errors.password = e }))
|
||||
|
||||
return Object.keys(errors).length > 0
|
||||
? E.left(errors)
|
||||
: E.right({ name: form.name.trim(), email: form.email, password: form.password })
|
||||
}
|
||||
|
||||
// In component
|
||||
{errors.email && <span className="error">{errors.email}</span>}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Data Fetching with TaskEither
|
||||
|
||||
TaskEither = async operation that might fail. Perfect for API calls.
|
||||
|
||||
### Basic Fetch Hook
|
||||
|
||||
```typescript
|
||||
import { useState, useEffect } from 'react'
|
||||
import * as TE from 'fp-ts/TaskEither'
|
||||
import * as E from 'fp-ts/Either'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
|
||||
// Wrap fetch in TaskEither
|
||||
const fetchJson = <T>(url: string): TE.TaskEither<Error, T> =>
|
||||
TE.tryCatch(
|
||||
async () => {
|
||||
const res = await fetch(url)
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
||||
return res.json()
|
||||
},
|
||||
(err) => err instanceof Error ? err : new Error(String(err))
|
||||
)
|
||||
|
||||
// Custom hook
|
||||
function useFetch<T>(url: string) {
|
||||
const [data, setData] = useState<T | null>(null)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
pipe(
|
||||
fetchJson<T>(url),
|
||||
TE.match(
|
||||
(err) => {
|
||||
setError(err)
|
||||
setLoading(false)
|
||||
},
|
||||
(result) => {
|
||||
setData(result)
|
||||
setLoading(false)
|
||||
}
|
||||
)
|
||||
)()
|
||||
}, [url])
|
||||
|
||||
return { data, error, loading }
|
||||
}
|
||||
|
||||
// Usage
|
||||
function UserList() {
|
||||
const { data, error, loading } = useFetch<User[]>('/api/users')
|
||||
|
||||
if (loading) return <div>Loading...</div>
|
||||
if (error) return <div>Error: {error.message}</div>
|
||||
return (
|
||||
<ul>
|
||||
{data?.map(user => <li key={user.id}>{user.name}</li>)}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Chaining API Calls
|
||||
|
||||
```typescript
|
||||
// Fetch user, then fetch their posts
|
||||
const fetchUserWithPosts = (userId: string) => pipe(
|
||||
fetchJson<User>(`/api/users/${userId}`),
|
||||
TE.flatMap(user => pipe(
|
||||
fetchJson<Post[]>(`/api/users/${userId}/posts`),
|
||||
TE.map(posts => ({ ...user, posts }))
|
||||
))
|
||||
)
|
||||
```
|
||||
|
||||
### Parallel API Calls
|
||||
|
||||
```typescript
|
||||
import { sequenceT } from 'fp-ts/Apply'
|
||||
|
||||
// Fetch multiple things at once
|
||||
const fetchDashboardData = () => pipe(
|
||||
sequenceT(TE.ApplyPar)(
|
||||
fetchJson<User>('/api/user'),
|
||||
fetchJson<Stats>('/api/stats'),
|
||||
fetchJson<Notifications[]>('/api/notifications')
|
||||
),
|
||||
TE.map(([user, stats, notifications]) => ({
|
||||
user,
|
||||
stats,
|
||||
notifications
|
||||
}))
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. RemoteData Pattern (The Right Way to Handle Async State)
|
||||
|
||||
Stop using `{ data, loading, error }` booleans. Use a proper state machine.
|
||||
|
||||
### The Pattern
|
||||
|
||||
```typescript
|
||||
// RemoteData has exactly 4 states - no impossible combinations
|
||||
type RemoteData<E, A> =
|
||||
| { _tag: 'NotAsked' } // Haven't started yet
|
||||
| { _tag: 'Loading' } // In progress
|
||||
| { _tag: 'Failure'; error: E } // Failed
|
||||
| { _tag: 'Success'; data: A } // Got it!
|
||||
|
||||
// Constructors
|
||||
const notAsked = <E, A>(): RemoteData<E, A> => ({ _tag: 'NotAsked' })
|
||||
const loading = <E, A>(): RemoteData<E, A> => ({ _tag: 'Loading' })
|
||||
const failure = <E, A>(error: E): RemoteData<E, A> => ({ _tag: 'Failure', error })
|
||||
const success = <E, A>(data: A): RemoteData<E, A> => ({ _tag: 'Success', data })
|
||||
|
||||
// Pattern match all states
|
||||
function fold<E, A, R>(
|
||||
rd: RemoteData<E, A>,
|
||||
onNotAsked: () => R,
|
||||
onLoading: () => R,
|
||||
onFailure: (e: E) => R,
|
||||
onSuccess: (a: A) => R
|
||||
): R {
|
||||
switch (rd._tag) {
|
||||
case 'NotAsked': return onNotAsked()
|
||||
case 'Loading': return onLoading()
|
||||
case 'Failure': return onFailure(rd.error)
|
||||
case 'Success': return onSuccess(rd.data)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Hook with RemoteData
|
||||
|
||||
```typescript
|
||||
function useRemoteData<T>(fetchFn: () => Promise<T>) {
|
||||
const [state, setState] = useState<RemoteData<Error, T>>(notAsked())
|
||||
|
||||
const execute = async () => {
|
||||
setState(loading())
|
||||
try {
|
||||
const data = await fetchFn()
|
||||
setState(success(data))
|
||||
} catch (err) {
|
||||
setState(failure(err instanceof Error ? err : new Error(String(err))))
|
||||
}
|
||||
}
|
||||
|
||||
return { state, execute }
|
||||
}
|
||||
|
||||
// Usage
|
||||
function UserProfile({ userId }: { userId: string }) {
|
||||
const { state, execute } = useRemoteData(() =>
|
||||
fetch(`/api/users/${userId}`).then(r => r.json())
|
||||
)
|
||||
|
||||
useEffect(() => { execute() }, [userId])
|
||||
|
||||
return fold(
|
||||
state,
|
||||
() => <button onClick={execute}>Load User</button>,
|
||||
() => <Spinner />,
|
||||
(err) => <ErrorMessage message={err.message} onRetry={execute} />,
|
||||
(user) => <UserCard user={user} />
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Why RemoteData Beats Booleans
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: Impossible states are possible
|
||||
interface BadState {
|
||||
data: User | null
|
||||
loading: boolean
|
||||
error: Error | null
|
||||
}
|
||||
// Can have: { data: user, loading: true, error: someError } - what does that mean?!
|
||||
|
||||
// ✅ GOOD: Only valid states exist
|
||||
type GoodState = RemoteData<Error, User>
|
||||
// Can only be: NotAsked | Loading | Failure | Success
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Referential Stability (Preventing Re-renders)
|
||||
|
||||
fp-ts values like `O.some(1)` create new objects each render. React sees them as "changed".
|
||||
|
||||
### The Problem
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: Creates new Option every render
|
||||
function BadComponent() {
|
||||
const [value, setValue] = useState(O.some(1))
|
||||
|
||||
useEffect(() => {
|
||||
// This runs EVERY render because O.some(1) !== O.some(1)
|
||||
console.log('value changed')
|
||||
}, [value])
|
||||
}
|
||||
```
|
||||
|
||||
### Solution 1: useMemo
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Memoize Option creation
|
||||
function GoodComponent() {
|
||||
const [rawValue, setRawValue] = useState<number | null>(1)
|
||||
|
||||
const value = useMemo(
|
||||
() => O.fromNullable(rawValue),
|
||||
[rawValue] // Only recreate when rawValue changes
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
// Now this only runs when rawValue actually changes
|
||||
console.log('value changed')
|
||||
}, [rawValue]) // Depend on raw value, not Option
|
||||
}
|
||||
```
|
||||
|
||||
### Solution 2: fp-ts-react-stable-hooks
|
||||
|
||||
```bash
|
||||
npm install fp-ts-react-stable-hooks
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { useStableO, useStableEffect } from 'fp-ts-react-stable-hooks'
|
||||
import * as O from 'fp-ts/Option'
|
||||
import * as Eq from 'fp-ts/Eq'
|
||||
|
||||
function StableComponent() {
|
||||
// Uses fp-ts equality instead of reference equality
|
||||
const [value, setValue] = useStableO(O.some(1))
|
||||
|
||||
// Effect that understands Option equality
|
||||
useStableEffect(
|
||||
() => { console.log('value changed') },
|
||||
[value],
|
||||
Eq.tuple(O.getEq(Eq.eqNumber)) // Custom equality
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Dependency Injection with Context
|
||||
|
||||
Use ReaderTaskEither for testable components with injected dependencies.
|
||||
|
||||
### Setup Dependencies
|
||||
|
||||
```typescript
|
||||
import * as RTE from 'fp-ts/ReaderTaskEither'
|
||||
import { pipe } from 'fp-ts/function'
|
||||
import { createContext, useContext, ReactNode } from 'react'
|
||||
|
||||
// Define what services your app needs
|
||||
interface AppDependencies {
|
||||
api: {
|
||||
getUser: (id: string) => Promise<User>
|
||||
updateUser: (id: string, data: Partial<User>) => Promise<User>
|
||||
}
|
||||
analytics: {
|
||||
track: (event: string, data?: object) => void
|
||||
}
|
||||
}
|
||||
|
||||
// Create context
|
||||
const DepsContext = createContext<AppDependencies | null>(null)
|
||||
|
||||
// Provider
|
||||
function AppProvider({ deps, children }: { deps: AppDependencies; children: ReactNode }) {
|
||||
return <DepsContext.Provider value={deps}>{children}</DepsContext.Provider>
|
||||
}
|
||||
|
||||
// Hook to use dependencies
|
||||
function useDeps(): AppDependencies {
|
||||
const deps = useContext(DepsContext)
|
||||
if (!deps) throw new Error('Missing AppProvider')
|
||||
return deps
|
||||
}
|
||||
```
|
||||
|
||||
### Use in Components
|
||||
|
||||
```typescript
|
||||
function UserProfile({ userId }: { userId: string }) {
|
||||
const { api, analytics } = useDeps()
|
||||
const [user, setUser] = useState<RemoteData<Error, User>>(notAsked())
|
||||
|
||||
useEffect(() => {
|
||||
setUser(loading())
|
||||
api.getUser(userId)
|
||||
.then(u => {
|
||||
setUser(success(u))
|
||||
analytics.track('user_viewed', { userId })
|
||||
})
|
||||
.catch(e => setUser(failure(e)))
|
||||
}, [userId, api, analytics])
|
||||
|
||||
// render...
|
||||
}
|
||||
```
|
||||
|
||||
### Testing with Mock Dependencies
|
||||
|
||||
```typescript
|
||||
const mockDeps: AppDependencies = {
|
||||
api: {
|
||||
getUser: jest.fn().mockResolvedValue({ id: '1', name: 'Test User' }),
|
||||
updateUser: jest.fn().mockResolvedValue({ id: '1', name: 'Updated' }),
|
||||
},
|
||||
analytics: {
|
||||
track: jest.fn(),
|
||||
},
|
||||
}
|
||||
|
||||
test('loads user on mount', async () => {
|
||||
render(
|
||||
<AppProvider deps={mockDeps}>
|
||||
<UserProfile userId="1" />
|
||||
</AppProvider>
|
||||
)
|
||||
|
||||
await screen.findByText('Test User')
|
||||
expect(mockDeps.api.getUser).toHaveBeenCalledWith('1')
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. React 19 Patterns
|
||||
|
||||
### use() for Promises (React 19+)
|
||||
|
||||
```typescript
|
||||
import { use, Suspense } from 'react'
|
||||
|
||||
// Instead of useEffect + useState for data fetching
|
||||
function UserProfile({ userPromise }: { userPromise: Promise<User> }) {
|
||||
const user = use(userPromise) // Suspends until resolved
|
||||
return <div>{user.name}</div>
|
||||
}
|
||||
|
||||
// Parent provides the promise
|
||||
function App() {
|
||||
const userPromise = fetchUser('1') // Start fetching immediately
|
||||
|
||||
return (
|
||||
<Suspense fallback={<Spinner />}>
|
||||
<UserProfile userPromise={userPromise} />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### useActionState for Forms (React 19+)
|
||||
|
||||
```typescript
|
||||
import { useActionState } from 'react'
|
||||
import * as E from 'fp-ts/Either'
|
||||
|
||||
interface FormState {
|
||||
errors: string[]
|
||||
success: boolean
|
||||
}
|
||||
|
||||
async function submitForm(
|
||||
prevState: FormState,
|
||||
formData: FormData
|
||||
): Promise<FormState> {
|
||||
const data = {
|
||||
email: formData.get('email') as string,
|
||||
password: formData.get('password') as string,
|
||||
}
|
||||
|
||||
// Use Either for validation
|
||||
const result = pipe(
|
||||
validateForm(data),
|
||||
E.match(
|
||||
(errors) => ({ errors, success: false }),
|
||||
async (valid) => {
|
||||
await saveToServer(valid)
|
||||
return { errors: [], success: true }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function SignupForm() {
|
||||
const [state, formAction, isPending] = useActionState(submitForm, {
|
||||
errors: [],
|
||||
success: false
|
||||
})
|
||||
|
||||
return (
|
||||
<form action={formAction}>
|
||||
<input name="email" type="email" />
|
||||
<input name="password" type="password" />
|
||||
|
||||
{state.errors.map(e => <p key={e} className="error">{e}</p>)}
|
||||
|
||||
<button disabled={isPending}>
|
||||
{isPending ? 'Submitting...' : 'Sign Up'}
|
||||
</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### useOptimistic for Instant Feedback (React 19+)
|
||||
|
||||
```typescript
|
||||
import { useOptimistic } from 'react'
|
||||
|
||||
function TodoList({ todos }: { todos: Todo[] }) {
|
||||
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
|
||||
todos,
|
||||
(state, newTodo: Todo) => [...state, { ...newTodo, pending: true }]
|
||||
)
|
||||
|
||||
const addTodo = async (text: string) => {
|
||||
const newTodo = { id: crypto.randomUUID(), text, done: false }
|
||||
|
||||
// Immediately show in UI
|
||||
addOptimisticTodo(newTodo)
|
||||
|
||||
// Actually save (will reconcile when done)
|
||||
await saveTodo(newTodo)
|
||||
}
|
||||
|
||||
return (
|
||||
<ul>
|
||||
{optimisticTodos.map(todo => (
|
||||
<li key={todo.id} style={{ opacity: todo.pending ? 0.5 : 1 }}>
|
||||
{todo.text}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Common Patterns Cheat Sheet
|
||||
|
||||
### Render Based on Option
|
||||
|
||||
```typescript
|
||||
// Pattern 1: match
|
||||
pipe(
|
||||
maybeUser,
|
||||
O.match(
|
||||
() => <LoginButton />,
|
||||
(user) => <UserMenu user={user} />
|
||||
)
|
||||
)
|
||||
|
||||
// Pattern 2: fold (same as match)
|
||||
O.fold(
|
||||
() => <LoginButton />,
|
||||
(user) => <UserMenu user={user} />
|
||||
)(maybeUser)
|
||||
|
||||
// Pattern 3: getOrElse for simple defaults
|
||||
const name = pipe(
|
||||
maybeUser,
|
||||
O.map(u => u.name),
|
||||
O.getOrElse(() => 'Guest')
|
||||
)
|
||||
```
|
||||
|
||||
### Render Based on Either
|
||||
|
||||
```typescript
|
||||
pipe(
|
||||
validationResult,
|
||||
E.match(
|
||||
(errors) => <ErrorList errors={errors} />,
|
||||
(data) => <SuccessMessage data={data} />
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Safe Array Rendering
|
||||
|
||||
```typescript
|
||||
import * as A from 'fp-ts/Array'
|
||||
|
||||
// Get first item safely
|
||||
const firstUser = pipe(
|
||||
users,
|
||||
A.head,
|
||||
O.map(user => <Featured user={user} />),
|
||||
O.getOrElse(() => <NoFeaturedUser />)
|
||||
)
|
||||
|
||||
// Find specific item
|
||||
const adminUser = pipe(
|
||||
users,
|
||||
A.findFirst(u => u.role === 'admin'),
|
||||
O.map(admin => <AdminBadge user={admin} />),
|
||||
O.toNullable // or O.getOrElse(() => null)
|
||||
)
|
||||
```
|
||||
|
||||
### Conditional Props
|
||||
|
||||
```typescript
|
||||
// Add props only if value exists
|
||||
const modalProps = {
|
||||
isOpen: true,
|
||||
...pipe(
|
||||
maybeTitle,
|
||||
O.map(title => ({ title })),
|
||||
O.getOrElse(() => ({}))
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## When to Use What
|
||||
|
||||
| Situation | Use |
|
||||
|-----------|-----|
|
||||
| Value might not exist | `Option<T>` |
|
||||
| Operation might fail (sync) | `Either<E, A>` |
|
||||
| Async operation might fail | `TaskEither<E, A>` |
|
||||
| Need loading/error/success UI | `RemoteData<E, A>` |
|
||||
| Form with multiple validations | `Either` with validation applicative |
|
||||
| Dependency injection | Context + `ReaderTaskEither` |
|
||||
| Prevent re-renders with fp-ts | `useMemo` or `fp-ts-react-stable-hooks` |
|
||||
|
||||
---
|
||||
|
||||
## Libraries
|
||||
|
||||
- **[fp-ts](https://github.com/gcanti/fp-ts)** - Core library
|
||||
- **[fp-ts-react-stable-hooks](https://github.com/mblink/fp-ts-react-stable-hooks)** - Stable hooks
|
||||
- **[@devexperts/remote-data-ts](https://github.com/devexperts/remote-data-ts)** - RemoteData
|
||||
- **[io-ts](https://github.com/gcanti/io-ts)** - Runtime type validation
|
||||
- **[zod](https://github.com/colinhacks/zod)** - Schema validation (works great with fp-ts)
|
||||
@@ -1,9 +1,4 @@
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.
|
||||
|
||||
name: frontend-slides
|
||||
description: Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.
|
||||
source: https://github.com/zarazhangrui/frontend-slides
|
||||
|
||||
847
skills/radix-ui-design-system/SKILL.md
Normal file
847
skills/radix-ui-design-system/SKILL.md
Normal file
@@ -0,0 +1,847 @@
|
||||
---
|
||||
name: radix-ui-design-system
|
||||
description: Build accessible design systems with Radix UI primitives. Headless component customization, theming strategies, and compound component patterns for production-grade UI libraries.
|
||||
risk: safe
|
||||
source: self
|
||||
---
|
||||
|
||||
# Radix UI Design System
|
||||
|
||||
Build production-ready, accessible design systems using Radix UI primitives with full customization control and zero style opinions.
|
||||
|
||||
## Overview
|
||||
|
||||
Radix UI provides unstyled, accessible components (primitives) that you can customize to match any design system. This skill guides you through building scalable component libraries with Radix UI, focusing on accessibility-first design, theming architecture, and composable patterns.
|
||||
|
||||
**Key Strengths:**
|
||||
- **Headless by design**: Full styling control without fighting defaults
|
||||
- **Accessibility built-in**: WAI-ARIA compliant, keyboard navigation, screen reader support
|
||||
- **Composable primitives**: Build complex components from simple building blocks
|
||||
- **Framework agnostic**: Works with React, but styles work anywhere
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Creating a custom design system from scratch
|
||||
- Building accessible UI component libraries
|
||||
- Implementing complex interactive components (Dialog, Dropdown, Tabs, etc.)
|
||||
- Migrating from styled component libraries to unstyled primitives
|
||||
- Setting up theming systems with CSS variables or Tailwind
|
||||
- Need full control over component behavior and styling
|
||||
- Building applications requiring WCAG 2.1 AA/AAA compliance
|
||||
|
||||
## Do not use this skill when
|
||||
|
||||
- You need pre-styled components out of the box (use shadcn/ui, Mantine, etc.)
|
||||
- Building simple static pages without interactivity
|
||||
- The project doesn't use React 16.8+ (Radix requires hooks)
|
||||
- You need components for frameworks other than React
|
||||
|
||||
---
|
||||
|
||||
## Core Principles
|
||||
|
||||
### 1. Accessibility First
|
||||
|
||||
Every Radix primitive is built with accessibility as the foundation:
|
||||
|
||||
- **Keyboard Navigation**: Full keyboard support (Tab, Arrow keys, Enter, Escape)
|
||||
- **Screen Readers**: Proper ARIA attributes and live regions
|
||||
- **Focus Management**: Automatic focus trapping and restoration
|
||||
- **Disabled States**: Proper handling of disabled and aria-disabled
|
||||
|
||||
**Rule**: Never override accessibility features. Enhance, don't replace.
|
||||
|
||||
### 2. Headless Architecture
|
||||
|
||||
Radix provides **behavior**, you provide **appearance**:
|
||||
|
||||
```tsx
|
||||
// ❌ Don't fight pre-styled components
|
||||
<Button className="override-everything" />
|
||||
|
||||
// ✅ Radix gives you behavior, you add styling
|
||||
<Dialog.Root>
|
||||
<Dialog.Trigger className="your-button-styles" />
|
||||
<Dialog.Content className="your-modal-styles" />
|
||||
</Dialog.Root>
|
||||
```
|
||||
|
||||
### 3. Composition Over Configuration
|
||||
|
||||
Build complex components from simple primitives:
|
||||
|
||||
```tsx
|
||||
// Primitive components compose naturally
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
|
||||
<Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
|
||||
</Tabs.List>
|
||||
<Tabs.Content value="tab1">Content 1</Tabs.Content>
|
||||
<Tabs.Content value="tab2">Content 2</Tabs.Content>
|
||||
</Tabs.Root>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Install individual primitives (recommended)
|
||||
npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu
|
||||
|
||||
# Or install multiple at once
|
||||
npm install @radix-ui/react-{dialog,dropdown-menu,tabs,tooltip}
|
||||
|
||||
# For styling (optional but common)
|
||||
npm install clsx tailwind-merge class-variance-authority
|
||||
```
|
||||
|
||||
### Basic Component Pattern
|
||||
|
||||
Every Radix component follows this pattern:
|
||||
|
||||
```tsx
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
|
||||
export function MyDialog() {
|
||||
return (
|
||||
<Dialog.Root>
|
||||
{/* Trigger the dialog */}
|
||||
<Dialog.Trigger asChild>
|
||||
<button className="trigger-styles">Open</button>
|
||||
</Dialog.Trigger>
|
||||
|
||||
{/* Portal renders outside DOM hierarchy */}
|
||||
<Dialog.Portal>
|
||||
{/* Overlay (backdrop) */}
|
||||
<Dialog.Overlay className="overlay-styles" />
|
||||
|
||||
{/* Content (modal) */}
|
||||
<Dialog.Content className="content-styles">
|
||||
<Dialog.Title>Title</Dialog.Title>
|
||||
<Dialog.Description>Description</Dialog.Description>
|
||||
|
||||
{/* Your content here */}
|
||||
|
||||
<Dialog.Close asChild>
|
||||
<button>Close</button>
|
||||
</Dialog.Close>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Theming Strategies
|
||||
|
||||
### Strategy 1: CSS Variables (Framework-Agnostic)
|
||||
|
||||
**Best for**: Maximum portability, SSR-friendly
|
||||
|
||||
```css
|
||||
/* globals.css */
|
||||
:root {
|
||||
--color-primary: 220 90% 56%;
|
||||
--color-surface: 0 0% 100%;
|
||||
--radius-base: 0.5rem;
|
||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--color-primary: 220 90% 66%;
|
||||
--color-surface: 222 47% 11%;
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// Component.tsx
|
||||
<Dialog.Content
|
||||
className="
|
||||
bg-[hsl(var(--color-surface))]
|
||||
rounded-[var(--radius-base)]
|
||||
shadow-[var(--shadow-lg)]
|
||||
"
|
||||
/>
|
||||
```
|
||||
|
||||
### Strategy 2: Tailwind + CVA (Class Variance Authority)
|
||||
|
||||
**Best for**: Tailwind projects, variant-heavy components
|
||||
|
||||
```tsx
|
||||
// button.tsx
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const buttonVariants = cva(
|
||||
// Base styles
|
||||
"inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
outline: "border border-input bg-background hover:bg-accent",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
interface ButtonProps extends VariantProps<typeof buttonVariants> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function Button({ variant, size, children }: ButtonProps) {
|
||||
return (
|
||||
<button className={cn(buttonVariants({ variant, size }))}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Strategy 3: Stitches (CSS-in-JS)
|
||||
|
||||
**Best for**: Runtime theming, scoped styles
|
||||
|
||||
```tsx
|
||||
import { styled } from '@stitches/react';
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
|
||||
const StyledContent = styled(Dialog.Content, {
|
||||
backgroundColor: '$surface',
|
||||
borderRadius: '$md',
|
||||
padding: '$6',
|
||||
|
||||
variants: {
|
||||
size: {
|
||||
small: { width: '300px' },
|
||||
medium: { width: '500px' },
|
||||
large: { width: '700px' },
|
||||
},
|
||||
},
|
||||
|
||||
defaultVariants: {
|
||||
size: 'medium',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Component Patterns
|
||||
|
||||
### Pattern 1: Compound Components with Context
|
||||
|
||||
**Use case**: Share state between primitive parts
|
||||
|
||||
```tsx
|
||||
// Select.tsx
|
||||
import * as Select from '@radix-ui/react-select';
|
||||
import { CheckIcon, ChevronDownIcon } from '@radix-ui/react-icons';
|
||||
|
||||
export function CustomSelect({ items, placeholder, onValueChange }) {
|
||||
return (
|
||||
<Select.Root onValueChange={onValueChange}>
|
||||
<Select.Trigger className="select-trigger">
|
||||
<Select.Value placeholder={placeholder} />
|
||||
<Select.Icon>
|
||||
<ChevronDownIcon />
|
||||
</Select.Icon>
|
||||
</Select.Trigger>
|
||||
|
||||
<Select.Portal>
|
||||
<Select.Content className="select-content">
|
||||
<Select.Viewport>
|
||||
{items.map((item) => (
|
||||
<Select.Item
|
||||
key={item.value}
|
||||
value={item.value}
|
||||
className="select-item"
|
||||
>
|
||||
<Select.ItemText>{item.label}</Select.ItemText>
|
||||
<Select.ItemIndicator>
|
||||
<CheckIcon />
|
||||
</Select.ItemIndicator>
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Viewport>
|
||||
</Select.Content>
|
||||
</Select.Portal>
|
||||
</Select.Root>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 2: Polymorphic Components with `asChild`
|
||||
|
||||
**Use case**: Render as different elements without losing behavior
|
||||
|
||||
```tsx
|
||||
// ✅ Render as Next.js Link but keep Radix behavior
|
||||
<Dialog.Trigger asChild>
|
||||
<Link href="/settings">Open Settings</Link>
|
||||
</Dialog.Trigger>
|
||||
|
||||
// ✅ Render as custom component
|
||||
<DropdownMenu.Item asChild>
|
||||
<YourCustomButton icon={<Icon />}>Action</YourCustomButton>
|
||||
</DropdownMenu.Item>
|
||||
```
|
||||
|
||||
**Why `asChild` matters**: Prevents nested button/link issues in accessibility tree.
|
||||
|
||||
### Pattern 3: Controlled vs Uncontrolled
|
||||
|
||||
```tsx
|
||||
// Uncontrolled (Radix manages state)
|
||||
<Tabs.Root defaultValue="tab1">
|
||||
<Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
|
||||
</Tabs.Root>
|
||||
|
||||
// Controlled (You manage state)
|
||||
const [activeTab, setActiveTab] = useState('tab1');
|
||||
|
||||
<Tabs.Root value={activeTab} onValueChange={setActiveTab}>
|
||||
<Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
|
||||
</Tabs.Root>
|
||||
```
|
||||
|
||||
**Rule**: Use controlled when you need to sync with external state (URL, Redux, etc.).
|
||||
|
||||
### Pattern 4: Animation with Framer Motion
|
||||
|
||||
```tsx
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
|
||||
export function AnimatedDialog({ open, onOpenChange }) {
|
||||
return (
|
||||
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
||||
<Dialog.Portal forceMount>
|
||||
<AnimatePresence>
|
||||
{open && (
|
||||
<>
|
||||
<Dialog.Overlay asChild>
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="dialog-overlay"
|
||||
/>
|
||||
</Dialog.Overlay>
|
||||
|
||||
<Dialog.Content asChild>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
className="dialog-content"
|
||||
>
|
||||
{/* Content */}
|
||||
</motion.div>
|
||||
</Dialog.Content>
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Primitives Reference
|
||||
|
||||
### Dialog (Modal)
|
||||
|
||||
```tsx
|
||||
<Dialog.Root> {/* State container */}
|
||||
<Dialog.Trigger /> {/* Opens dialog */}
|
||||
<Dialog.Portal> {/* Renders in portal */}
|
||||
<Dialog.Overlay /> {/* Backdrop */}
|
||||
<Dialog.Content> {/* Modal content */}
|
||||
<Dialog.Title /> {/* Required for a11y */}
|
||||
<Dialog.Description /> {/* Required for a11y */}
|
||||
<Dialog.Close /> {/* Closes dialog */}
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
```
|
||||
|
||||
### Dropdown Menu
|
||||
|
||||
```tsx
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger />
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content>
|
||||
<DropdownMenu.Item />
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.CheckboxItem />
|
||||
<DropdownMenu.RadioGroup>
|
||||
<DropdownMenu.RadioItem />
|
||||
</DropdownMenu.RadioGroup>
|
||||
<DropdownMenu.Sub> {/* Nested menus */}
|
||||
<DropdownMenu.SubTrigger />
|
||||
<DropdownMenu.SubContent />
|
||||
</DropdownMenu.Sub>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu.Root>
|
||||
```
|
||||
|
||||
### Tabs
|
||||
|
||||
```tsx
|
||||
<Tabs.Root defaultValue="tab1">
|
||||
<Tabs.List>
|
||||
<Tabs.Trigger value="tab1" />
|
||||
<Tabs.Trigger value="tab2" />
|
||||
</Tabs.List>
|
||||
<Tabs.Content value="tab1" />
|
||||
<Tabs.Content value="tab2" />
|
||||
</Tabs.Root>
|
||||
```
|
||||
|
||||
### Tooltip
|
||||
|
||||
```tsx
|
||||
<Tooltip.Provider delayDuration={200}>
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger />
|
||||
<Tooltip.Portal>
|
||||
<Tooltip.Content side="top" align="center">
|
||||
Tooltip text
|
||||
<Tooltip.Arrow />
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Portal>
|
||||
</Tooltip.Root>
|
||||
</Tooltip.Provider>
|
||||
```
|
||||
|
||||
### Popover
|
||||
|
||||
```tsx
|
||||
<Popover.Root>
|
||||
<Popover.Trigger />
|
||||
<Popover.Portal>
|
||||
<Popover.Content side="bottom" align="start">
|
||||
Content
|
||||
<Popover.Arrow />
|
||||
<Popover.Close />
|
||||
</Popover.Content>
|
||||
</Popover.Portal>
|
||||
</Popover.Root>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Accessibility Checklist
|
||||
|
||||
### Every Component Must Have:
|
||||
|
||||
- [ ] **Focus Management**: Visible focus indicators on all interactive elements
|
||||
- [ ] **Keyboard Navigation**: Full keyboard support (Tab, Arrows, Enter, Esc)
|
||||
- [ ] **ARIA Labels**: Meaningful labels for screen readers
|
||||
- [ ] **Color Contrast**: WCAG AA minimum (4.5:1 for text, 3:1 for UI)
|
||||
- [ ] **Error States**: Clear error messages with `aria-invalid` and `aria-describedby`
|
||||
- [ ] **Loading States**: Proper `aria-busy` during async operations
|
||||
|
||||
### Dialog-Specific:
|
||||
- [ ] `Dialog.Title` is present (required for screen readers)
|
||||
- [ ] `Dialog.Description` provides context
|
||||
- [ ] Focus trapped inside modal when open
|
||||
- [ ] Escape key closes dialog
|
||||
- [ ] Focus returns to trigger on close
|
||||
|
||||
### Dropdown-Specific:
|
||||
- [ ] Arrow keys navigate items
|
||||
- [ ] Type-ahead search works
|
||||
- [ ] First/last item wrapping behavior
|
||||
- [ ] Selected state indicated visually and with ARIA
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ Do This
|
||||
|
||||
1. **Always use `asChild` to avoid wrapper divs**
|
||||
```tsx
|
||||
<Dialog.Trigger asChild>
|
||||
<button>Open</button>
|
||||
</Dialog.Trigger>
|
||||
```
|
||||
|
||||
2. **Provide semantic HTML**
|
||||
```tsx
|
||||
<Dialog.Content asChild>
|
||||
<article role="dialog" aria-labelledby="title">
|
||||
{/* content */}
|
||||
</article>
|
||||
</Dialog.Content>
|
||||
```
|
||||
|
||||
3. **Use CSS variables for theming**
|
||||
```css
|
||||
.dialog-content {
|
||||
background: hsl(var(--surface));
|
||||
color: hsl(var(--on-surface));
|
||||
}
|
||||
```
|
||||
|
||||
4. **Compose primitives for complex components**
|
||||
```tsx
|
||||
function CommandPalette() {
|
||||
return (
|
||||
<Dialog.Root>
|
||||
<Dialog.Content>
|
||||
<Combobox /> {/* Radix Combobox inside Dialog */}
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### ❌ Don't Do This
|
||||
|
||||
1. **Don't skip accessibility parts**
|
||||
```tsx
|
||||
// ❌ Missing Title and Description
|
||||
<Dialog.Content>
|
||||
<div>Content</div>
|
||||
</Dialog.Content>
|
||||
```
|
||||
|
||||
2. **Don't fight the primitives**
|
||||
```tsx
|
||||
// ❌ Overriding internal behavior
|
||||
<Dialog.Content onClick={(e) => e.stopPropagation()}>
|
||||
```
|
||||
|
||||
3. **Don't mix controlled and uncontrolled**
|
||||
```tsx
|
||||
// ❌ Inconsistent state management
|
||||
<Tabs.Root defaultValue="tab1" value={activeTab}>
|
||||
```
|
||||
|
||||
4. **Don't ignore keyboard navigation**
|
||||
```tsx
|
||||
// ❌ Disabling keyboard behavior
|
||||
<DropdownMenu.Item onKeyDown={(e) => e.preventDefault()}>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real-World Examples
|
||||
|
||||
### Example 1: Command Palette (Combo Dialog)
|
||||
|
||||
```tsx
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
import { Command } from 'cmdk';
|
||||
|
||||
export function CommandPalette() {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
|
||||
e.preventDefault();
|
||||
setOpen((open) => !open);
|
||||
}
|
||||
};
|
||||
document.addEventListener('keydown', down);
|
||||
return () => document.removeEventListener('keydown', down);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Dialog.Root open={open} onOpenChange={setOpen}>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay className="fixed inset-0 bg-black/50" />
|
||||
<Dialog.Content className="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<Command>
|
||||
<Command.Input placeholder="Type a command..." />
|
||||
<Command.List>
|
||||
<Command.Empty>No results found.</Command.Empty>
|
||||
<Command.Group heading="Suggestions">
|
||||
<Command.Item>Calendar</Command.Item>
|
||||
<Command.Item>Search Emoji</Command.Item>
|
||||
</Command.Group>
|
||||
</Command.List>
|
||||
</Command>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Example 2: Dropdown Menu with Icons
|
||||
|
||||
```tsx
|
||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
||||
import { DotsHorizontalIcon } from '@radix-ui/react-icons';
|
||||
|
||||
export function ActionsMenu() {
|
||||
return (
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<button className="icon-button" aria-label="Actions">
|
||||
<DotsHorizontalIcon />
|
||||
</button>
|
||||
</DropdownMenu.Trigger>
|
||||
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content className="dropdown-content" align="end">
|
||||
<DropdownMenu.Item className="dropdown-item">
|
||||
Edit
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item className="dropdown-item">
|
||||
Duplicate
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator className="dropdown-separator" />
|
||||
<DropdownMenu.Item className="dropdown-item text-red-500">
|
||||
Delete
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu.Root>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Example 3: Form with Radix Select + React Hook Form
|
||||
|
||||
```tsx
|
||||
import * as Select from '@radix-ui/react-select';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
|
||||
interface FormData {
|
||||
country: string;
|
||||
}
|
||||
|
||||
export function CountryForm() {
|
||||
const { control, handleSubmit } = useForm<FormData>();
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit((data) => console.log(data))}>
|
||||
<Controller
|
||||
name="country"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select.Root onValueChange={field.onChange} value={field.value}>
|
||||
<Select.Trigger className="select-trigger">
|
||||
<Select.Value placeholder="Select a country" />
|
||||
<Select.Icon />
|
||||
</Select.Trigger>
|
||||
|
||||
<Select.Portal>
|
||||
<Select.Content className="select-content">
|
||||
<Select.Viewport>
|
||||
<Select.Item value="us">United States</Select.Item>
|
||||
<Select.Item value="ca">Canada</Select.Item>
|
||||
<Select.Item value="uk">United Kingdom</Select.Item>
|
||||
</Select.Viewport>
|
||||
</Select.Content>
|
||||
</Select.Portal>
|
||||
</Select.Root>
|
||||
)}
|
||||
/>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: Dialog doesn't close on Escape key
|
||||
|
||||
**Cause**: `onEscapeKeyDown` event prevented or `open` state not synced
|
||||
|
||||
**Solution**:
|
||||
```tsx
|
||||
<Dialog.Root open={open} onOpenChange={setOpen}>
|
||||
{/* Don't prevent default on escape */}
|
||||
</Dialog.Root>
|
||||
```
|
||||
|
||||
### Problem: Dropdown menu positioning is off
|
||||
|
||||
**Cause**: Parent container has `overflow: hidden` or transform
|
||||
|
||||
**Solution**:
|
||||
```tsx
|
||||
// Use Portal to render outside overflow container
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content />
|
||||
</DropdownMenu.Portal>
|
||||
```
|
||||
|
||||
### Problem: Animations don't work
|
||||
|
||||
**Cause**: Portal content unmounts immediately
|
||||
|
||||
**Solution**:
|
||||
```tsx
|
||||
// Use forceMount + AnimatePresence
|
||||
<Dialog.Portal forceMount>
|
||||
<AnimatePresence>
|
||||
{open && <Dialog.Content />}
|
||||
</AnimatePresence>
|
||||
</Dialog.Portal>
|
||||
```
|
||||
|
||||
### Problem: TypeScript errors with `asChild`
|
||||
|
||||
**Cause**: Type inference issues with polymorphic components
|
||||
|
||||
**Solution**:
|
||||
```tsx
|
||||
// Explicitly type your component
|
||||
<Dialog.Trigger asChild>
|
||||
<button type="button">Open</button>
|
||||
</Dialog.Trigger>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### 1. Code Splitting
|
||||
|
||||
```tsx
|
||||
// Lazy load heavy primitives
|
||||
const Dialog = lazy(() => import('@radix-ui/react-dialog'));
|
||||
const DropdownMenu = lazy(() => import('@radix-ui/react-dropdown-menu'));
|
||||
```
|
||||
|
||||
### 2. Portal Container Reuse
|
||||
|
||||
```tsx
|
||||
// Create portal container once
|
||||
<Tooltip.Provider>
|
||||
{/* All tooltips share portal container */}
|
||||
<Tooltip.Root>...</Tooltip.Root>
|
||||
<Tooltip.Root>...</Tooltip.Root>
|
||||
</Tooltip.Provider>
|
||||
```
|
||||
|
||||
### 3. Memoization
|
||||
|
||||
```tsx
|
||||
// Memoize expensive render functions
|
||||
const SelectItems = memo(({ items }) => (
|
||||
items.map((item) => <Select.Item key={item.value} value={item.value} />)
|
||||
));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration with Popular Tools
|
||||
|
||||
### shadcn/ui (Built on Radix)
|
||||
|
||||
shadcn/ui is a collection of copy-paste components built with Radix + Tailwind.
|
||||
|
||||
```bash
|
||||
npx shadcn-ui@latest init
|
||||
npx shadcn-ui@latest add dialog
|
||||
```
|
||||
|
||||
**When to use shadcn vs raw Radix**:
|
||||
- Use shadcn: Quick prototyping, standard designs
|
||||
- Use raw Radix: Full customization, unique designs
|
||||
|
||||
### Radix Themes (Official Styled System)
|
||||
|
||||
```tsx
|
||||
import { Theme, Button, Dialog } from '@radix-ui/themes';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<Theme accentColor="crimson" grayColor="sand">
|
||||
<Button>Click me</Button>
|
||||
</Theme>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `@tailwind-design-system` - Tailwind + Radix integration patterns
|
||||
- `@react-patterns` - React composition patterns
|
||||
- `@frontend-design` - Overall frontend architecture
|
||||
- `@accessibility-compliance` - WCAG compliance testing
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
### Official Documentation
|
||||
- [Radix UI Docs](https://www.radix-ui.com/primitives)
|
||||
- [Radix Colors](https://www.radix-ui.com/colors) - Accessible color system
|
||||
- [Radix Icons](https://www.radix-ui.com/icons) - Icon library
|
||||
|
||||
### Community Resources
|
||||
- [shadcn/ui](https://ui.shadcn.com) - Component collection
|
||||
- [Radix UI Discord](https://discord.com/invite/7Xb99uG) - Community support
|
||||
- [CVA Documentation](https://cva.style/docs) - Variant management
|
||||
|
||||
### Examples
|
||||
- [Radix Playground](https://www.radix-ui.com/primitives/docs/overview/introduction#try-it-out)
|
||||
- [shadcn/ui Source](https://github.com/shadcn-ui/ui) - Production examples
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
npm install @radix-ui/react-{primitive-name}
|
||||
```
|
||||
|
||||
### Basic Pattern
|
||||
```tsx
|
||||
<Primitive.Root>
|
||||
<Primitive.Trigger />
|
||||
<Primitive.Portal>
|
||||
<Primitive.Content />
|
||||
</Primitive.Portal>
|
||||
</Primitive.Root>
|
||||
```
|
||||
|
||||
### Key Props
|
||||
- `asChild` - Render as child element
|
||||
- `defaultValue` - Uncontrolled default
|
||||
- `value` / `onValueChange` - Controlled state
|
||||
- `open` / `onOpenChange` - Open state
|
||||
- `side` / `align` - Positioning
|
||||
|
||||
---
|
||||
|
||||
**Remember**: Radix gives you **behavior**, you give it **beauty**. Accessibility is built-in, customization is unlimited.
|
||||
63
skills/radix-ui-design-system/examples/README.md
Normal file
63
skills/radix-ui-design-system/examples/README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Radix UI Design System - Skill Examples
|
||||
|
||||
This folder contains practical examples demonstrating how to use Radix UI primitives to build accessible, customizable components.
|
||||
|
||||
## Examples
|
||||
|
||||
### `dialog-example.tsx`
|
||||
|
||||
Demonstrates Dialog (Modal) component patterns:
|
||||
- **BasicDialog**: Standard modal with form
|
||||
- **ControlledDialog**: Externally controlled modal state
|
||||
|
||||
**Key Concepts**:
|
||||
- Portal rendering outside DOM hierarchy
|
||||
- Overlay (backdrop) handling
|
||||
- Accessibility requirements (Title, Description)
|
||||
- Custom styling with CSS
|
||||
|
||||
### `dropdown-example.tsx`
|
||||
|
||||
Complete dropdown menu implementation:
|
||||
- **CompleteDropdown**: Full-featured menu with all Radix primitives
|
||||
- Regular items
|
||||
- Separators and labels
|
||||
- Checkbox items
|
||||
- Radio groups
|
||||
- Sub-menus
|
||||
- **ActionsMenu**: Simple actions menu for data tables/cards
|
||||
|
||||
**Key Concepts**:
|
||||
- Compound component architecture
|
||||
- Keyboard navigation
|
||||
- Item indicators (checkboxes, radio buttons)
|
||||
- Nested sub-menus
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { BasicDialog } from './examples/dialog-example';
|
||||
import { CompleteDropdown } from './examples/dropdown-example';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<>
|
||||
<BasicDialog />
|
||||
<CompleteDropdown />
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Styling
|
||||
|
||||
These examples use CSS classes. You can:
|
||||
1. Copy the CSS from each file
|
||||
2. Replace with Tailwind classes
|
||||
3. Use CSS-in-JS (Stitches, Emotion, etc.)
|
||||
|
||||
## Learn More
|
||||
|
||||
- [Main SKILL.md](../SKILL.md) - Complete guide
|
||||
- [Component Template](../templates/component-template.tsx) - Boilerplate
|
||||
- [Radix UI Docs](https://www.radix-ui.com/primitives)
|
||||
128
skills/radix-ui-design-system/examples/dialog-example.tsx
Normal file
128
skills/radix-ui-design-system/examples/dialog-example.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
import { Cross2Icon } from '@radix-ui/react-icons';
|
||||
import './dialog.css';
|
||||
|
||||
/**
|
||||
* Example: Basic Dialog Component
|
||||
*
|
||||
* Demonstrates:
|
||||
* - Compound component pattern
|
||||
* - Portal rendering
|
||||
* - Accessibility features (Title, Description)
|
||||
* - Custom styling with CSS
|
||||
*/
|
||||
export function BasicDialog() {
|
||||
return (
|
||||
<Dialog.Root>
|
||||
<Dialog.Trigger asChild>
|
||||
<button className="button-primary">
|
||||
Open Dialog
|
||||
</button>
|
||||
</Dialog.Trigger>
|
||||
|
||||
<Dialog.Portal>
|
||||
{/* Overlay (backdrop) */}
|
||||
<Dialog.Overlay className="dialog-overlay" />
|
||||
|
||||
{/* Content (modal) */}
|
||||
<Dialog.Content className="dialog-content">
|
||||
{/* Title - Required for accessibility */}
|
||||
<Dialog.Title className="dialog-title">
|
||||
Edit Profile
|
||||
</Dialog.Title>
|
||||
|
||||
{/* Description - Recommended for accessibility */}
|
||||
<Dialog.Description className="dialog-description">
|
||||
Make changes to your profile here. Click save when you're done.
|
||||
</Dialog.Description>
|
||||
|
||||
{/* Form Content */}
|
||||
<form className="dialog-form">
|
||||
<fieldset className="fieldset">
|
||||
<label className="label" htmlFor="name">
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
className="input"
|
||||
id="name"
|
||||
defaultValue="John Doe"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset className="fieldset">
|
||||
<label className="label" htmlFor="email">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
className="input"
|
||||
id="email"
|
||||
type="email"
|
||||
defaultValue="john@example.com"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<div className="dialog-actions">
|
||||
<Dialog.Close asChild>
|
||||
<button className="button-secondary" type="button">
|
||||
Cancel
|
||||
</button>
|
||||
</Dialog.Close>
|
||||
<button className="button-primary" type="submit">
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* Close button */}
|
||||
<Dialog.Close asChild>
|
||||
<button className="icon-button" aria-label="Close">
|
||||
<Cross2Icon />
|
||||
</button>
|
||||
</Dialog.Close>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Controlled Dialog
|
||||
*
|
||||
* Use when you need to:
|
||||
* - Sync dialog state with external state
|
||||
* - Programmatically open/close dialog
|
||||
* - Track dialog open state
|
||||
*/
|
||||
export function ControlledDialog() {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const handleSave = () => {
|
||||
// Your save logic here
|
||||
console.log('Saving...');
|
||||
setOpen(false); // Close after save
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog.Root open={open} onOpenChange={setOpen}>
|
||||
<Dialog.Trigger asChild>
|
||||
<button className="button-primary">
|
||||
Open Controlled Dialog
|
||||
</button>
|
||||
</Dialog.Trigger>
|
||||
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay className="dialog-overlay" />
|
||||
<Dialog.Content className="dialog-content">
|
||||
<Dialog.Title>Controlled Dialog</Dialog.Title>
|
||||
<Dialog.Description>
|
||||
This dialog's state is managed externally.
|
||||
</Dialog.Description>
|
||||
|
||||
<p>Dialog is {open ? 'open' : 'closed'}</p>
|
||||
|
||||
<button onClick={handleSave}>Save and Close</button>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
162
skills/radix-ui-design-system/examples/dropdown-example.tsx
Normal file
162
skills/radix-ui-design-system/examples/dropdown-example.tsx
Normal file
@@ -0,0 +1,162 @@
|
||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
||||
import {
|
||||
HamburgerMenuIcon,
|
||||
DotFilledIcon,
|
||||
CheckIcon,
|
||||
ChevronRightIcon,
|
||||
} from '@radix-ui/react-icons';
|
||||
import './dropdown.css';
|
||||
|
||||
/**
|
||||
* Example: Complete Dropdown Menu
|
||||
*
|
||||
* Features:
|
||||
* - Items, separators, labels
|
||||
* - Checkbox items
|
||||
* - Radio group items
|
||||
* - Sub-menus
|
||||
* - Keyboard navigation
|
||||
*/
|
||||
export function CompleteDropdown() {
|
||||
const [bookmarksChecked, setBookmarksChecked] = React.useState(true);
|
||||
const [urlsChecked, setUrlsChecked] = React.useState(false);
|
||||
const [person, setPerson] = React.useState('pedro');
|
||||
|
||||
return (
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<button className="icon-button" aria-label="Customise options">
|
||||
<HamburgerMenuIcon />
|
||||
</button>
|
||||
</DropdownMenu.Trigger>
|
||||
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content className="dropdown-content" sideOffset={5}>
|
||||
{/* Regular items */}
|
||||
<DropdownMenu.Item className="dropdown-item">
|
||||
New Tab <div className="right-slot">⌘+T</div>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item className="dropdown-item">
|
||||
New Window <div className="right-slot">⌘+N</div>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item className="dropdown-item" disabled>
|
||||
New Private Window <div className="right-slot">⇧+⌘+N</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
{/* Sub-menu */}
|
||||
<DropdownMenu.Sub>
|
||||
<DropdownMenu.SubTrigger className="dropdown-subtrigger">
|
||||
More Tools
|
||||
<div className="right-slot">
|
||||
<ChevronRightIcon />
|
||||
</div>
|
||||
</DropdownMenu.SubTrigger>
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.SubContent
|
||||
className="dropdown-subcontent"
|
||||
sideOffset={2}
|
||||
alignOffset={-5}
|
||||
>
|
||||
<DropdownMenu.Item className="dropdown-item">
|
||||
Save Page As… <div className="right-slot">⌘+S</div>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item className="dropdown-item">
|
||||
Create Shortcut…
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item className="dropdown-item">
|
||||
Name Window…
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator className="dropdown-separator" />
|
||||
<DropdownMenu.Item className="dropdown-item">
|
||||
Developer Tools
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.SubContent>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu.Sub>
|
||||
|
||||
<DropdownMenu.Separator className="dropdown-separator" />
|
||||
|
||||
{/* Checkbox items */}
|
||||
<DropdownMenu.CheckboxItem
|
||||
className="dropdown-checkbox-item"
|
||||
checked={bookmarksChecked}
|
||||
onCheckedChange={setBookmarksChecked}
|
||||
>
|
||||
<DropdownMenu.ItemIndicator className="dropdown-item-indicator">
|
||||
<CheckIcon />
|
||||
</DropdownMenu.ItemIndicator>
|
||||
Show Bookmarks <div className="right-slot">⌘+B</div>
|
||||
</DropdownMenu.CheckboxItem>
|
||||
<DropdownMenu.CheckboxItem
|
||||
className="dropdown-checkbox-item"
|
||||
checked={urlsChecked}
|
||||
onCheckedChange={setUrlsChecked}
|
||||
>
|
||||
<DropdownMenu.ItemIndicator className="dropdown-item-indicator">
|
||||
<CheckIcon />
|
||||
</DropdownMenu.ItemIndicator>
|
||||
Show Full URLs
|
||||
</DropdownMenu.CheckboxItem>
|
||||
|
||||
<DropdownMenu.Separator className="dropdown-separator" />
|
||||
|
||||
{/* Radio group */}
|
||||
<DropdownMenu.Label className="dropdown-label">
|
||||
People
|
||||
</DropdownMenu.Label>
|
||||
<DropdownMenu.RadioGroup value={person} onValueChange={setPerson}>
|
||||
<DropdownMenu.RadioItem className="dropdown-radio-item" value="pedro">
|
||||
<DropdownMenu.ItemIndicator className="dropdown-item-indicator">
|
||||
<DotFilledIcon />
|
||||
</DropdownMenu.ItemIndicator>
|
||||
Pedro Duarte
|
||||
</DropdownMenu.RadioItem>
|
||||
<DropdownMenu.RadioItem className="dropdown-radio-item" value="colm">
|
||||
<DropdownMenu.ItemIndicator className="dropdown-item-indicator">
|
||||
<DotFilledIcon />
|
||||
</DropdownMenu.ItemIndicator>
|
||||
Colm Tuite
|
||||
</DropdownMenu.RadioItem>
|
||||
</DropdownMenu.RadioGroup>
|
||||
|
||||
<DropdownMenu.Arrow className="dropdown-arrow" />
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu.Root>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Simple Actions Menu
|
||||
*
|
||||
* Common use case for data tables, cards, etc.
|
||||
*/
|
||||
export function ActionsMenu({ onEdit, onDuplicate, onDelete }) {
|
||||
return (
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<button className="icon-button" aria-label="Actions">
|
||||
<DotsHorizontalIcon />
|
||||
</button>
|
||||
</DropdownMenu.Trigger>
|
||||
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content className="dropdown-content" align="end">
|
||||
<DropdownMenu.Item className="dropdown-item" onSelect={onEdit}>
|
||||
Edit
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item className="dropdown-item" onSelect={onDuplicate}>
|
||||
Duplicate
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator className="dropdown-separator" />
|
||||
<DropdownMenu.Item
|
||||
className="dropdown-item dropdown-item-danger"
|
||||
onSelect={onDelete}
|
||||
>
|
||||
Delete
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu.Root>
|
||||
);
|
||||
}
|
||||
148
skills/radix-ui-design-system/templates/component-template.tsx
Normal file
148
skills/radix-ui-design-system/templates/component-template.tsx
Normal file
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* Radix UI Component Template
|
||||
*
|
||||
* This template provides a starting point for creating
|
||||
* custom components with Radix UI primitives.
|
||||
*
|
||||
* Replace [PRIMITIVE] with actual primitive name:
|
||||
* Dialog, DropdownMenu, Select, Tabs, Tooltip, etc.
|
||||
*/
|
||||
|
||||
import * as [PRIMITIVE] from '@radix-ui/react-[primitive]';
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
// ============================================================================
|
||||
// Variants Definition (using CVA)
|
||||
// ============================================================================
|
||||
|
||||
const [component]Variants = cva(
|
||||
// Base styles (always applied)
|
||||
"base-styles-here",
|
||||
{
|
||||
variants: {
|
||||
// Define your variants
|
||||
variant: {
|
||||
default: "default-styles",
|
||||
secondary: "secondary-styles",
|
||||
destructive: "destructive-styles",
|
||||
},
|
||||
size: {
|
||||
sm: "small-size-styles",
|
||||
md: "medium-size-styles",
|
||||
lg: "large-size-styles",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "md",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
// TypeScript Interfaces
|
||||
// ============================================================================
|
||||
|
||||
interface [Component]Props
|
||||
extends React.ComponentPropsWithoutRef<typeof [PRIMITIVE].Root>,
|
||||
VariantProps<typeof [component]Variants> {
|
||||
// Add custom props here
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Component Implementation
|
||||
// ============================================================================
|
||||
|
||||
export function [Component]({
|
||||
variant,
|
||||
size,
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: [Component]Props) {
|
||||
return (
|
||||
<[PRIMITIVE].Root {...props}>
|
||||
{/* Trigger */}
|
||||
<[PRIMITIVE].Trigger asChild>
|
||||
<button className={cn([component]Variants({ variant, size }), className)}>
|
||||
{children}
|
||||
</button>
|
||||
</[PRIMITIVE].Trigger>
|
||||
|
||||
{/* Portal (if needed) */}
|
||||
<[PRIMITIVE].Portal>
|
||||
{/* Overlay (for Dialog, etc.) */}
|
||||
<[PRIMITIVE].Overlay className="overlay-styles" />
|
||||
|
||||
{/* Content */}
|
||||
<[PRIMITIVE].Content className="content-styles">
|
||||
{/* Required accessibility parts */}
|
||||
<[PRIMITIVE].Title className="title-styles">
|
||||
Title
|
||||
</[PRIMITIVE].Title>
|
||||
|
||||
<[PRIMITIVE].Description className="description-styles">
|
||||
Description
|
||||
</[PRIMITIVE].Description>
|
||||
|
||||
{/* Your content */}
|
||||
<div className="content-body">
|
||||
{/* ... */}
|
||||
</div>
|
||||
|
||||
{/* Close button */}
|
||||
<[PRIMITIVE].Close asChild>
|
||||
<button className="close-button">Close</button>
|
||||
</[PRIMITIVE].Close>
|
||||
</[PRIMITIVE].Content>
|
||||
</[PRIMITIVE].Portal>
|
||||
</[PRIMITIVE].Root>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Sub-components (if needed)
|
||||
// ============================================================================
|
||||
|
||||
[Component].[SubComponent] = function [SubComponent]({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentPropsWithoutRef<typeof [PRIMITIVE].[SubComponent]>) {
|
||||
return (
|
||||
<[PRIMITIVE].[SubComponent]
|
||||
className={cn("subcomponent-styles", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Usage Example
|
||||
// ============================================================================
|
||||
|
||||
/*
|
||||
import { [Component] } from './[component]';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<[Component] variant="default" size="md">
|
||||
Trigger Content
|
||||
</[Component]
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// Accessibility Checklist
|
||||
// ============================================================================
|
||||
|
||||
/*
|
||||
[ ] Keyboard navigation works (Tab, Arrow keys, Enter, Esc)
|
||||
[ ] Focus visible on all interactive elements
|
||||
[ ] Screen reader announces all states
|
||||
[ ] ARIA attributes are correct
|
||||
[ ] Color contrast meets WCAG AA (4.5:1 for text)
|
||||
[ ] Focus trapped when needed (modals)
|
||||
[ ] Focus restored after close
|
||||
*/
|
||||
165
skills/stitch-ui-design/README.md
Normal file
165
skills/stitch-ui-design/README.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Stitch UI Design Skill
|
||||
|
||||
Expert guidance for creating effective prompts in Google Stitch, the AI-powered UI design tool.
|
||||
|
||||
## Overview
|
||||
|
||||
This skill provides comprehensive guidance for crafting precise, actionable prompts that generate high-quality UI designs in Google Stitch. It covers prompt structure, specificity techniques, iteration strategies, and design-to-code workflows.
|
||||
|
||||
## What's Included
|
||||
|
||||
### SKILL.md
|
||||
Core prompting principles and techniques:
|
||||
- Specificity and detail requirements
|
||||
- Visual style definition
|
||||
- Multi-screen flow structuring
|
||||
- Platform and responsive specifications
|
||||
- Functional requirements
|
||||
- Prompt templates
|
||||
- Iteration strategies
|
||||
- Common use cases
|
||||
- Anti-patterns to avoid
|
||||
|
||||
### References
|
||||
|
||||
#### prompt-examples.md
|
||||
Comprehensive library of effective Stitch prompts organized by category:
|
||||
- Landing pages
|
||||
- Mobile apps
|
||||
- Dashboards
|
||||
- E-commerce
|
||||
- Forms & authentication
|
||||
- Content platforms
|
||||
- SaaS applications
|
||||
|
||||
Each example includes detailed component breakdowns, style specifications, and platform requirements.
|
||||
|
||||
#### advanced-techniques.md
|
||||
Advanced strategies for production-ready designs:
|
||||
- Image-to-UI workflows
|
||||
- Design system integration
|
||||
- Responsive design strategies
|
||||
- Accessibility considerations
|
||||
- Performance optimization
|
||||
- Component reusability
|
||||
- Atomic design methodology
|
||||
- Export and handoff best practices
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Creating UI designs in Google Stitch
|
||||
- Generating mobile or web app interfaces
|
||||
- Crafting effective Stitch prompts
|
||||
- Converting sketches or wireframes to digital UI
|
||||
- Building design systems
|
||||
- Creating responsive layouts
|
||||
- Ensuring accessibility compliance
|
||||
- Optimizing design-to-code workflows
|
||||
|
||||
## Key Principles
|
||||
|
||||
1. **Be Specific** - Generic prompts yield generic results
|
||||
2. **Define Visual Style** - Always include colors, aesthetics, and design direction
|
||||
3. **Structure Clearly** - List components and sections explicitly
|
||||
4. **Specify Platform** - Indicate mobile, tablet, desktop, or responsive
|
||||
5. **Include Functionality** - Describe interactions, states, and user flows
|
||||
6. **Iterate Incrementally** - Make focused changes rather than complete redesigns
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Basic Prompt Template
|
||||
|
||||
```
|
||||
[Screen/Component Type] for [User/Context]
|
||||
|
||||
Key Features:
|
||||
- [Feature 1 with specific details]
|
||||
- [Feature 2 with specific details]
|
||||
- [Feature 3 with specific details]
|
||||
|
||||
Visual Style:
|
||||
- [Color scheme]
|
||||
- [Design aesthetic]
|
||||
- [Layout approach]
|
||||
|
||||
Platform: [Mobile/Web/Responsive]
|
||||
```
|
||||
|
||||
### Example Usage
|
||||
|
||||
```
|
||||
Dashboard for SaaS analytics platform
|
||||
|
||||
Key Features:
|
||||
- Top metrics cards showing MRR, active users, churn rate
|
||||
- Line chart for revenue trends (last 30 days)
|
||||
- Recent activity feed with user actions
|
||||
- Quick action buttons for reports and exports
|
||||
|
||||
Visual Style:
|
||||
- Dark mode with blue/purple gradient accents
|
||||
- Modern glassmorphic cards with subtle shadows
|
||||
- Clean data visualization with accessible colors
|
||||
|
||||
Platform: Responsive web (desktop-first)
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Do's ✅
|
||||
- Provide specific component details
|
||||
- Define clear visual direction
|
||||
- Specify responsive behavior
|
||||
- Include interaction states
|
||||
- Use design terminology
|
||||
- Reference existing designs when helpful
|
||||
- Iterate with annotations
|
||||
- Consider accessibility from the start
|
||||
|
||||
### Don'ts ❌
|
||||
- Use vague descriptions ("nice website")
|
||||
- Omit visual style guidance
|
||||
- Forget platform specifications
|
||||
- Ignore responsive requirements
|
||||
- Skip accessibility considerations
|
||||
- Make complete redesigns instead of incremental changes
|
||||
|
||||
## Integration with Development
|
||||
|
||||
### Stitch → Figma → Code
|
||||
1. Generate UI in Stitch with detailed prompts
|
||||
2. Export to Figma for design system integration
|
||||
3. Hand off to developers with design specs
|
||||
4. Implement with production-ready code
|
||||
|
||||
### Stitch → HTML → Framework
|
||||
1. Generate and refine UI in Stitch
|
||||
2. Export HTML/CSS code
|
||||
3. Convert to React/Vue/Svelte components
|
||||
4. Integrate into application codebase
|
||||
|
||||
## Resources
|
||||
|
||||
- **SKILL.md** - Core prompting guide
|
||||
- **prompt-examples.md** - 30+ detailed prompt examples
|
||||
- **advanced-techniques.md** - Production-ready design strategies
|
||||
|
||||
## Tips for Success
|
||||
|
||||
1. Start with clear requirements and context
|
||||
2. Use the prompt template for consistency
|
||||
3. Reference examples for similar use cases
|
||||
4. Iterate incrementally with annotations
|
||||
5. Generate variants to explore options
|
||||
6. Always specify visual style and platform
|
||||
7. Consider accessibility in every prompt
|
||||
8. Refine exports before production use
|
||||
|
||||
## About Google Stitch
|
||||
|
||||
Google Stitch is an experimental AI UI generator powered by Gemini 2.5 Flash that transforms text prompts and visual references into functional UI designs. It supports text-to-UI generation, image-to-UI conversion, multi-screen flows, and exports to HTML/CSS, Figma, and code.
|
||||
|
||||
---
|
||||
|
||||
**Note:** This skill is designed to help you create effective prompts for Stitch. The quality of your output depends on the specificity and clarity of your prompts. Use the templates and examples as starting points, then customize for your unique requirements.
|
||||
378
skills/stitch-ui-design/SKILL.md
Normal file
378
skills/stitch-ui-design/SKILL.md
Normal file
@@ -0,0 +1,378 @@
|
||||
---
|
||||
name: stitch-ui-design
|
||||
description: Expert guide for creating effective prompts for Google Stitch AI UI design tool. Use when user wants to design UI/UX in Stitch, create app interfaces, generate mobile/web designs, or needs help crafting Stitch prompts. Covers prompt structure, specificity techniques, iteration strategies, and design-to-code workflows for Stitch by Google.
|
||||
risk: safe
|
||||
source: "self"
|
||||
---
|
||||
|
||||
# Stitch UI Design Prompting
|
||||
|
||||
Expert guidance for crafting effective prompts in Google Stitch, the AI-powered UI design tool by Google Labs. This skill helps create precise, actionable prompts that generate high-quality UI designs for web and mobile applications.
|
||||
|
||||
## What is Google Stitch?
|
||||
|
||||
Google Stitch is an experimental AI UI generator powered by Gemini 2.5 Flash that transforms text prompts and visual references into functional UI designs. It supports:
|
||||
|
||||
- Text-to-UI generation from natural language prompts
|
||||
- Image-to-UI conversion from sketches, wireframes, or screenshots
|
||||
- Multi-screen app flows and responsive layouts
|
||||
- Export to HTML/CSS, Figma, and code
|
||||
- Iterative refinement with variants and annotations
|
||||
|
||||
## Core Prompting Principles
|
||||
|
||||
### 1. Be Specific and Detailed
|
||||
|
||||
Generic prompts yield generic results. Specific prompts with clear requirements produce tailored, professional designs.
|
||||
|
||||
**Poor prompt:**
|
||||
```
|
||||
Create a dashboard
|
||||
```
|
||||
|
||||
**Effective prompt:**
|
||||
```
|
||||
Member dashboard with course modules grid, progress tracking bar,
|
||||
and community feed sidebar using purple theme and card-based layout
|
||||
```
|
||||
|
||||
**Why it works:** Specifies components (modules, progress, feed), layout structure (grid, sidebar), visual style (purple theme, cards), and context (member dashboard).
|
||||
|
||||
### 2. Define Visual Style and Theme
|
||||
|
||||
Always include color schemes, design aesthetics, and visual direction to avoid generic AI outputs.
|
||||
|
||||
**Components to specify:**
|
||||
- Color palette (primary colors, accent colors)
|
||||
- Design style (minimalist, modern, playful, professional, glassmorphic)
|
||||
- Typography preferences (if any)
|
||||
- Spacing and density (compact, spacious, balanced)
|
||||
|
||||
**Example:**
|
||||
```
|
||||
E-commerce product page with hero image gallery, add-to-cart CTA,
|
||||
reviews section, and related products carousel. Use clean minimalist
|
||||
design with sage green accents and generous white space.
|
||||
```
|
||||
|
||||
### 3. Structure Multi-Screen Flows Clearly
|
||||
|
||||
For apps with multiple screens, list each screen as bullet points before generation.
|
||||
|
||||
**Approach:**
|
||||
```
|
||||
Fitness tracking app with:
|
||||
- Onboarding screen with goal selection
|
||||
- Home dashboard with daily stats and activity rings
|
||||
- Workout library with category filters
|
||||
- Profile screen with achievements and settings
|
||||
```
|
||||
|
||||
Stitch will ask for confirmation before generating multiple screens, ensuring alignment with your vision.
|
||||
|
||||
### 4. Specify Platform and Responsive Behavior
|
||||
|
||||
Indicate whether the design is for mobile, tablet, desktop, or responsive web.
|
||||
|
||||
**Examples:**
|
||||
```
|
||||
Mobile app login screen (iOS style) with email/password fields and social auth buttons
|
||||
|
||||
Responsive landing page that adapts from mobile (320px) to desktop (1440px)
|
||||
with collapsible navigation
|
||||
```
|
||||
|
||||
### 5. Include Functional Requirements
|
||||
|
||||
Describe interactive elements, states, and user flows to generate more complete designs.
|
||||
|
||||
**Elements to specify:**
|
||||
- Button actions and CTAs
|
||||
- Form fields and validation
|
||||
- Navigation patterns
|
||||
- Loading states
|
||||
- Empty states
|
||||
- Error handling
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Checkout flow with:
|
||||
- Cart summary with quantity adjusters
|
||||
- Shipping address form with validation
|
||||
- Payment method selection (cards, PayPal, Apple Pay)
|
||||
- Order confirmation with tracking number
|
||||
```
|
||||
|
||||
## Prompt Structure Template
|
||||
|
||||
Use this template for comprehensive prompts:
|
||||
|
||||
```
|
||||
[Screen/Component Type] for [User/Context]
|
||||
|
||||
Key Features:
|
||||
- [Feature 1 with specific details]
|
||||
- [Feature 2 with specific details]
|
||||
- [Feature 3 with specific details]
|
||||
|
||||
Visual Style:
|
||||
- [Color scheme]
|
||||
- [Design aesthetic]
|
||||
- [Layout approach]
|
||||
|
||||
Platform: [Mobile/Web/Responsive]
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Dashboard for SaaS analytics platform
|
||||
|
||||
Key Features:
|
||||
- Top metrics cards showing MRR, active users, churn rate
|
||||
- Line chart for revenue trends (last 30 days)
|
||||
- Recent activity feed with user actions
|
||||
- Quick action buttons for reports and exports
|
||||
|
||||
Visual Style:
|
||||
- Dark mode with blue/purple gradient accents
|
||||
- Modern glassmorphic cards with subtle shadows
|
||||
- Clean data visualization with accessible colors
|
||||
|
||||
Platform: Responsive web (desktop-first)
|
||||
```
|
||||
|
||||
## Iteration Strategies
|
||||
|
||||
### Refine with Annotations
|
||||
|
||||
Use Stitch's "annotate to edit" feature to make targeted changes without rewriting the entire prompt.
|
||||
|
||||
**Workflow:**
|
||||
1. Generate initial design from prompt
|
||||
2. Annotate specific elements that need changes
|
||||
3. Describe modifications in natural language
|
||||
4. Stitch updates only the annotated areas
|
||||
|
||||
**Example annotations:**
|
||||
- "Make this button larger and use primary color"
|
||||
- "Add more spacing between these cards"
|
||||
- "Change this to a horizontal layout"
|
||||
|
||||
### Generate Variants
|
||||
|
||||
Request multiple variations to explore different design directions:
|
||||
|
||||
```
|
||||
Generate 3 variants of this hero section:
|
||||
1. Image-focused with minimal text
|
||||
2. Text-heavy with supporting graphics
|
||||
3. Video background with overlay content
|
||||
```
|
||||
|
||||
### Progressive Refinement
|
||||
|
||||
Start broad, then add specificity in follow-up prompts:
|
||||
|
||||
**Initial:**
|
||||
```
|
||||
E-commerce homepage
|
||||
```
|
||||
|
||||
**Refinement 1:**
|
||||
```
|
||||
Add featured products section with 4-column grid and hover effects
|
||||
```
|
||||
|
||||
**Refinement 2:**
|
||||
```
|
||||
Update color scheme to earth tones (terracotta, sage, cream)
|
||||
and add promotional banner at top
|
||||
```
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
### Landing Pages
|
||||
|
||||
```
|
||||
SaaS landing page for [product name]
|
||||
|
||||
Sections:
|
||||
- Hero with headline, subheadline, CTA, and product screenshot
|
||||
- Social proof with customer logos
|
||||
- Features grid (3 columns) with icons
|
||||
- Testimonials carousel
|
||||
- Pricing table (3 tiers)
|
||||
- FAQ accordion
|
||||
- Footer with links and newsletter signup
|
||||
|
||||
Style: Modern, professional, trust-building
|
||||
Colors: Navy blue primary, light blue accents, white background
|
||||
```
|
||||
|
||||
### Mobile Apps
|
||||
|
||||
```
|
||||
Food delivery app home screen
|
||||
|
||||
Components:
|
||||
- Search bar with location selector
|
||||
- Category chips (Pizza, Burgers, Sushi, etc.)
|
||||
- Restaurant cards with image, name, rating, delivery time, and price range
|
||||
- Bottom navigation (Home, Search, Orders, Profile)
|
||||
|
||||
Style: Vibrant, appetite-appealing, easy to scan
|
||||
Colors: Orange primary, white background, food photography
|
||||
Platform: iOS mobile (375px width)
|
||||
```
|
||||
|
||||
### Dashboards
|
||||
|
||||
```
|
||||
Admin dashboard for content management system
|
||||
|
||||
Layout:
|
||||
- Left sidebar navigation with collapsible menu
|
||||
- Top bar with search, notifications, and user profile
|
||||
- Main content area with:
|
||||
- Stats overview (4 metric cards)
|
||||
- Recent posts table with actions
|
||||
- Activity timeline
|
||||
- Quick actions panel
|
||||
|
||||
Style: Clean, data-focused, professional
|
||||
Colors: Neutral grays with blue accents
|
||||
Platform: Desktop web (1440px)
|
||||
```
|
||||
|
||||
### Forms and Inputs
|
||||
|
||||
```
|
||||
Multi-step signup form for B2B platform
|
||||
|
||||
Steps:
|
||||
1. Account details (company name, email, password)
|
||||
2. Company information (industry, size, role)
|
||||
3. Team setup (invite members)
|
||||
4. Confirmation with success message
|
||||
|
||||
Features:
|
||||
- Progress indicator at top
|
||||
- Field validation with inline errors
|
||||
- Back/Next navigation
|
||||
- Skip option for step 3
|
||||
|
||||
Style: Minimal, focused, low-friction
|
||||
Colors: White background, green for success states
|
||||
```
|
||||
|
||||
## Design-to-Code Workflow
|
||||
|
||||
### Export Options
|
||||
|
||||
Stitch provides multiple export formats:
|
||||
|
||||
1. **HTML/CSS** - Clean, semantic markup for web projects
|
||||
2. **Figma** - "Paste to Figma" for design system integration
|
||||
3. **Code snippets** - Component-level exports for frameworks
|
||||
|
||||
### Best Practices for Export
|
||||
|
||||
**Before exporting:**
|
||||
- Verify responsive breakpoints
|
||||
- Check color contrast for accessibility
|
||||
- Ensure interactive states are defined
|
||||
- Review component naming and structure
|
||||
|
||||
**After export:**
|
||||
- Refactor generated code for production standards
|
||||
- Add proper semantic HTML tags
|
||||
- Implement accessibility attributes (ARIA labels, alt text)
|
||||
- Optimize images and assets
|
||||
- Add animations and micro-interactions
|
||||
|
||||
## Anti-Patterns to Avoid
|
||||
|
||||
### ❌ Vague Prompts
|
||||
```
|
||||
Make a nice website
|
||||
```
|
||||
|
||||
### ✅ Specific Prompts
|
||||
```
|
||||
Portfolio website for photographer with full-screen image gallery,
|
||||
project case studies, and contact form. Minimalist black and white
|
||||
aesthetic with serif typography.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ❌ Missing Context
|
||||
```
|
||||
Create a login page
|
||||
```
|
||||
|
||||
### ✅ Context-Rich Prompts
|
||||
```
|
||||
Login page for healthcare portal with email/password fields,
|
||||
"Remember me" checkbox, "Forgot password" link, and SSO options
|
||||
(Google, Microsoft). Professional, trustworthy design with
|
||||
blue medical theme.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ❌ No Visual Direction
|
||||
```
|
||||
Design an app for task management
|
||||
```
|
||||
|
||||
### ✅ Clear Visual Direction
|
||||
```
|
||||
Task management app with kanban board layout, drag-and-drop cards,
|
||||
priority labels, and due date indicators. Modern, productivity-focused
|
||||
design with purple/teal gradient accents and dark mode support.
|
||||
```
|
||||
|
||||
## Tips for Better Results
|
||||
|
||||
1. **Reference existing designs** - Upload screenshots or sketches as visual references alongside text prompts
|
||||
|
||||
2. **Use design terminology** - Terms like "hero section," "card layout," "glassmorphic," "bento grid" help Stitch understand your intent
|
||||
|
||||
3. **Specify interactions** - Describe hover states, click actions, and transitions for more complete designs
|
||||
|
||||
4. **Think in components** - Break complex screens into reusable components (header, card, form, etc.)
|
||||
|
||||
5. **Iterate incrementally** - Make small, focused changes rather than complete redesigns
|
||||
|
||||
6. **Test responsiveness** - Always verify designs at multiple breakpoints (mobile, tablet, desktop)
|
||||
|
||||
7. **Consider accessibility** - Mention color contrast, font sizes, and touch target sizes in prompts
|
||||
|
||||
8. **Leverage variants** - Generate multiple options to explore different design directions quickly
|
||||
|
||||
## Integration with Development Workflow
|
||||
|
||||
### Stitch → Figma → Code
|
||||
1. Generate UI in Stitch with detailed prompts
|
||||
2. Export to Figma for design system integration
|
||||
3. Hand off to developers with design specs
|
||||
4. Implement with production-ready code
|
||||
|
||||
### Stitch → HTML → Framework
|
||||
1. Generate and refine UI in Stitch
|
||||
2. Export HTML/CSS code
|
||||
3. Convert to React/Vue/Svelte components
|
||||
4. Integrate into application codebase
|
||||
|
||||
### Rapid Prototyping
|
||||
1. Create multiple screen variations quickly
|
||||
2. Test with users or stakeholders
|
||||
3. Iterate based on feedback
|
||||
4. Finalize design for development
|
||||
|
||||
## Conclusion
|
||||
|
||||
Effective Stitch prompts are specific, context-rich, and visually descriptive. By following these principles and templates, you can generate professional UI designs that serve as strong foundations for production applications.
|
||||
|
||||
**Remember:** Stitch is a starting point, not a final product. Use it to accelerate the design process, explore ideas quickly, and establish visual direction—then refine with human judgment and production standards.
|
||||
541
skills/stitch-ui-design/references/advanced-techniques.md
Normal file
541
skills/stitch-ui-design/references/advanced-techniques.md
Normal file
@@ -0,0 +1,541 @@
|
||||
# Advanced Stitch Techniques
|
||||
|
||||
Advanced strategies for maximizing Stitch's capabilities and creating production-ready designs.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Image-to-UI Workflows](#image-to-ui-workflows)
|
||||
2. [Design System Integration](#design-system-integration)
|
||||
3. [Responsive Design Strategies](#responsive-design-strategies)
|
||||
4. [Accessibility Considerations](#accessibility-considerations)
|
||||
5. [Performance Optimization](#performance-optimization)
|
||||
6. [Component Reusability](#component-reusability)
|
||||
|
||||
---
|
||||
|
||||
## Image-to-UI Workflows
|
||||
|
||||
### Converting Sketches to Digital UI
|
||||
|
||||
Stitch can interpret hand-drawn sketches, wireframes, and rough mockups.
|
||||
|
||||
**Best practices:**
|
||||
|
||||
1. **Clear structure** - Draw distinct boxes for components
|
||||
2. **Label elements** - Annotate buttons, inputs, sections
|
||||
3. **Show hierarchy** - Use size and position to indicate importance
|
||||
4. **Include notes** - Add text describing interactions or states
|
||||
|
||||
**Example workflow:**
|
||||
```
|
||||
1. Sketch wireframe on paper or tablet
|
||||
2. Take clear photo or scan
|
||||
3. Upload to Stitch with prompt:
|
||||
"Convert this wireframe to a modern web interface with
|
||||
glassmorphic design and purple gradient accents"
|
||||
4. Refine generated design with annotations
|
||||
```
|
||||
|
||||
### Reference-Based Design
|
||||
|
||||
Upload screenshots of existing designs to create similar layouts with your own branding.
|
||||
|
||||
**Prompt structure:**
|
||||
```
|
||||
Create a [type] similar to this reference image, but with:
|
||||
- [Your color scheme]
|
||||
- [Your content/copy]
|
||||
- [Your brand style]
|
||||
- [Specific modifications]
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Create a pricing page similar to this reference, but with:
|
||||
- Navy blue and gold color scheme
|
||||
- 4 pricing tiers instead of 3
|
||||
- Annual/monthly toggle
|
||||
- Feature comparison table below
|
||||
- Testimonials section at bottom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Design System Integration
|
||||
|
||||
### Establishing Design Tokens
|
||||
|
||||
Define reusable design tokens in your initial prompt for consistency across screens.
|
||||
|
||||
**Token categories:**
|
||||
- Colors (primary, secondary, accent, neutral, semantic)
|
||||
- Typography (font families, sizes, weights, line heights)
|
||||
- Spacing (scale: 4px, 8px, 16px, 24px, 32px, 48px, 64px)
|
||||
- Border radius (none, sm, md, lg, full)
|
||||
- Shadows (elevation levels)
|
||||
|
||||
**Example prompt:**
|
||||
```
|
||||
Dashboard using this design system:
|
||||
|
||||
Colors:
|
||||
- Primary: #2563EB (blue)
|
||||
- Secondary: #7C3AED (purple)
|
||||
- Success: #10B981 (green)
|
||||
- Warning: #F59E0B (amber)
|
||||
- Error: #EF4444 (red)
|
||||
- Neutral: #6B7280 (gray)
|
||||
|
||||
Typography:
|
||||
- Headings: Inter Bold
|
||||
- Body: Inter Regular
|
||||
- Code: JetBrains Mono
|
||||
|
||||
Spacing: 8px base unit
|
||||
Border radius: 8px for cards, 4px for buttons
|
||||
Shadows: Subtle elevation with 0 4px 6px rgba(0,0,0,0.1)
|
||||
```
|
||||
|
||||
### Component Library Approach
|
||||
|
||||
Create a component library by generating individual components first, then composing them into full screens.
|
||||
|
||||
**Workflow:**
|
||||
```
|
||||
1. Generate base components:
|
||||
- Button variants (primary, secondary, outline, ghost)
|
||||
- Input fields (text, email, password, search)
|
||||
- Cards (basic, with image, with actions)
|
||||
- Navigation (header, sidebar, tabs)
|
||||
|
||||
2. Document component specs:
|
||||
- States (default, hover, active, disabled)
|
||||
- Sizes (sm, md, lg)
|
||||
- Variants
|
||||
|
||||
3. Compose screens using established components:
|
||||
"Create a settings page using the button and input
|
||||
components from previous generations"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Responsive Design Strategies
|
||||
|
||||
### Mobile-First Approach
|
||||
|
||||
Start with mobile design, then scale up to tablet and desktop.
|
||||
|
||||
**Prompt sequence:**
|
||||
|
||||
**Step 1 - Mobile (375px):**
|
||||
```
|
||||
Mobile app home screen for recipe platform
|
||||
|
||||
Layout:
|
||||
- Stacked vertical sections
|
||||
- Full-width cards
|
||||
- Bottom navigation
|
||||
- Hamburger menu
|
||||
|
||||
Content:
|
||||
- Search bar at top
|
||||
- Featured recipe hero card
|
||||
- Category chips (horizontal scroll)
|
||||
- Recipe grid (1 column)
|
||||
```
|
||||
|
||||
**Step 2 - Tablet (768px):**
|
||||
```
|
||||
Adapt the mobile recipe home screen for tablet:
|
||||
- 2-column recipe grid
|
||||
- Persistent sidebar navigation (replaces hamburger)
|
||||
- Larger featured hero with side-by-side layout
|
||||
- Category chips remain scrollable
|
||||
```
|
||||
|
||||
**Step 3 - Desktop (1440px):**
|
||||
```
|
||||
Adapt for desktop:
|
||||
- 3-column recipe grid
|
||||
- Full sidebar with categories expanded
|
||||
- Hero section with 3 featured recipes
|
||||
- Top navigation bar with search and user menu
|
||||
```
|
||||
|
||||
### Breakpoint-Specific Prompts
|
||||
|
||||
Specify exact breakpoints and layout changes.
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Responsive product grid:
|
||||
|
||||
Mobile (< 640px):
|
||||
- 1 column
|
||||
- Full-width cards
|
||||
- Vertical image orientation
|
||||
|
||||
Tablet (640px - 1024px):
|
||||
- 2 columns
|
||||
- Square images
|
||||
- Compact card layout
|
||||
|
||||
Desktop (> 1024px):
|
||||
- 4 columns
|
||||
- Hover effects with overlay
|
||||
- Quick view button
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Accessibility Considerations
|
||||
|
||||
### WCAG Compliance Prompts
|
||||
|
||||
Include accessibility requirements directly in prompts.
|
||||
|
||||
**Key areas to specify:**
|
||||
|
||||
1. **Color Contrast**
|
||||
```
|
||||
Ensure all text meets WCAG AA standards:
|
||||
- Normal text: 4.5:1 contrast ratio minimum
|
||||
- Large text (18pt+): 3:1 contrast ratio minimum
|
||||
- Interactive elements: clear focus states with 3:1 contrast
|
||||
```
|
||||
|
||||
2. **Touch Targets**
|
||||
```
|
||||
All interactive elements minimum 44x44px touch target size
|
||||
Adequate spacing between clickable elements (8px minimum)
|
||||
```
|
||||
|
||||
3. **Keyboard Navigation**
|
||||
```
|
||||
Clear focus indicators on all interactive elements
|
||||
Logical tab order following visual flow
|
||||
Skip navigation link for keyboard users
|
||||
```
|
||||
|
||||
4. **Screen Reader Support**
|
||||
```
|
||||
Descriptive button labels (not just "Click here")
|
||||
Alt text for all meaningful images
|
||||
Form labels properly associated with inputs
|
||||
Heading hierarchy (H1 → H2 → H3)
|
||||
```
|
||||
|
||||
**Comprehensive accessibility prompt:**
|
||||
```
|
||||
Create an accessible contact form:
|
||||
|
||||
Fields:
|
||||
- Name (required, with aria-required)
|
||||
- Email (required, with validation and error message)
|
||||
- Subject (dropdown with clear labels)
|
||||
- Message (textarea with character count)
|
||||
|
||||
Accessibility features:
|
||||
- All inputs have visible labels
|
||||
- Required fields marked with asterisk and aria-required
|
||||
- Error messages with role="alert"
|
||||
- Submit button with descriptive text
|
||||
- Focus indicators with 3px blue outline
|
||||
- Color contrast meets WCAG AA
|
||||
- Touch targets 44x44px minimum
|
||||
|
||||
Style: Clean, form-focused, high contrast
|
||||
Colors: Dark text on light background, red for errors
|
||||
```
|
||||
|
||||
### Inclusive Design Patterns
|
||||
|
||||
**Consider diverse users:**
|
||||
|
||||
```
|
||||
Design a video player interface that supports:
|
||||
- Captions/subtitles toggle
|
||||
- Audio description option
|
||||
- Keyboard shortcuts (space to play/pause, arrows to seek)
|
||||
- Playback speed control
|
||||
- High contrast mode
|
||||
- Reduced motion option (disable animations)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Optimized Asset Prompts
|
||||
|
||||
Request performance-conscious designs from the start.
|
||||
|
||||
**Image optimization:**
|
||||
```
|
||||
E-commerce product gallery with performance optimization:
|
||||
- Lazy loading for images below fold
|
||||
- Thumbnail images (200x200px) for grid
|
||||
- Full-size images (1200x1200px) only on click
|
||||
- WebP format with JPEG fallback
|
||||
- Blur placeholder while loading
|
||||
```
|
||||
|
||||
**Code efficiency:**
|
||||
```
|
||||
Generate lightweight HTML/CSS without:
|
||||
- Unnecessary wrapper divs
|
||||
- Inline styles (use classes)
|
||||
- Large external dependencies
|
||||
- Redundant CSS rules
|
||||
```
|
||||
|
||||
### Progressive Enhancement
|
||||
|
||||
Design for core functionality first, then enhance.
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Create a filterable product list with progressive enhancement:
|
||||
|
||||
Base (no JavaScript):
|
||||
- Server-rendered product grid
|
||||
- Form-based filters with submit button
|
||||
- Pagination links
|
||||
|
||||
Enhanced (with JavaScript):
|
||||
- AJAX filter updates without page reload
|
||||
- Infinite scroll
|
||||
- Smooth animations
|
||||
- Real-time search
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Component Reusability
|
||||
|
||||
### Atomic Design Methodology
|
||||
|
||||
Build from atoms → molecules → organisms → templates → pages.
|
||||
|
||||
**Atoms (basic elements):**
|
||||
```
|
||||
Generate design system atoms:
|
||||
- Button (primary, secondary, outline, ghost, danger)
|
||||
- Input field (text, email, password, search, textarea)
|
||||
- Label, Badge, Tag
|
||||
- Icon set (24x24px, consistent style)
|
||||
- Avatar (circle, square, with status indicator)
|
||||
```
|
||||
|
||||
**Molecules (simple combinations):**
|
||||
```
|
||||
Create molecules using atoms:
|
||||
- Search bar (input + button + icon)
|
||||
- Form field (label + input + error message)
|
||||
- Card header (avatar + name + timestamp + menu)
|
||||
- Stat card (icon + label + value + trend)
|
||||
```
|
||||
|
||||
**Organisms (complex components):**
|
||||
```
|
||||
Build organisms from molecules:
|
||||
- Navigation bar (logo + search bar + user menu)
|
||||
- Product card (image + title + price + rating + button)
|
||||
- Comment thread (avatar + name + timestamp + text + actions)
|
||||
- Data table (headers + rows + pagination + filters)
|
||||
```
|
||||
|
||||
**Templates (page layouts):**
|
||||
```
|
||||
Compose templates from organisms:
|
||||
- Dashboard layout (sidebar + header + content grid)
|
||||
- Article layout (header + hero + content + sidebar)
|
||||
- Checkout flow (progress + form + summary)
|
||||
```
|
||||
|
||||
### Variant Generation
|
||||
|
||||
Create systematic variations of components.
|
||||
|
||||
**Button variants prompt:**
|
||||
```
|
||||
Generate button component with all variants:
|
||||
|
||||
Sizes: Small (32px), Medium (40px), Large (48px)
|
||||
|
||||
Types:
|
||||
- Primary (filled, brand color)
|
||||
- Secondary (filled, gray)
|
||||
- Outline (border only)
|
||||
- Ghost (transparent, hover background)
|
||||
- Danger (filled, red)
|
||||
|
||||
States for each:
|
||||
- Default
|
||||
- Hover
|
||||
- Active (pressed)
|
||||
- Disabled
|
||||
- Loading (with spinner)
|
||||
|
||||
Include: Icon support (left/right), full-width option
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Iteration Techniques
|
||||
|
||||
### Conditional Variations
|
||||
|
||||
Generate multiple versions based on different conditions.
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Create 3 hero section variants for A/B testing:
|
||||
|
||||
Variant A - Image-focused:
|
||||
- Large background image
|
||||
- Minimal text overlay
|
||||
- Single CTA button
|
||||
|
||||
Variant B - Text-focused:
|
||||
- Solid color background
|
||||
- Detailed copy with bullet points
|
||||
- Two CTA buttons (primary + secondary)
|
||||
|
||||
Variant C - Video-focused:
|
||||
- Background video
|
||||
- Minimal text
|
||||
- Play button + CTA
|
||||
|
||||
All variants use same brand colors and maintain mobile responsiveness
|
||||
```
|
||||
|
||||
### State-Based Design
|
||||
|
||||
Design for all possible states, not just the happy path.
|
||||
|
||||
**Comprehensive state prompt:**
|
||||
```
|
||||
Design a data table with all states:
|
||||
|
||||
Default state:
|
||||
- 10 rows of data
|
||||
- Sortable columns
|
||||
- Pagination
|
||||
|
||||
Loading state:
|
||||
- Skeleton loaders for rows
|
||||
- Disabled controls
|
||||
|
||||
Empty state:
|
||||
- Illustration
|
||||
- "No data found" message
|
||||
- "Add new" CTA button
|
||||
|
||||
Error state:
|
||||
- Error icon
|
||||
- Error message
|
||||
- "Retry" button
|
||||
|
||||
Search/Filter active:
|
||||
- Applied filters shown as chips
|
||||
- Clear filters option
|
||||
- Result count
|
||||
|
||||
Selected rows:
|
||||
- Checkbox selection
|
||||
- Bulk action toolbar
|
||||
- Select all option
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Export and Handoff Best Practices
|
||||
|
||||
### Preparing for Development
|
||||
|
||||
Before exporting, ensure designs are developer-ready.
|
||||
|
||||
**Pre-export checklist:**
|
||||
|
||||
1. **Naming conventions**
|
||||
- Use semantic class names
|
||||
- Follow BEM or consistent methodology
|
||||
- Name components clearly
|
||||
|
||||
2. **Documentation**
|
||||
- Add comments for complex interactions
|
||||
- Document responsive breakpoints
|
||||
- Note any required JavaScript behavior
|
||||
|
||||
3. **Asset organization**
|
||||
- Export images at correct sizes
|
||||
- Provide SVG for icons
|
||||
- Include font files or CDN links
|
||||
|
||||
4. **Specifications**
|
||||
- Document spacing values
|
||||
- List color hex codes
|
||||
- Specify font sizes and weights
|
||||
|
||||
### Figma Integration
|
||||
|
||||
Optimize Stitch → Figma workflow.
|
||||
|
||||
**Steps:**
|
||||
```
|
||||
1. Generate design in Stitch with detailed specifications
|
||||
2. Use "Paste to Figma" export
|
||||
3. In Figma:
|
||||
- Organize layers with clear naming
|
||||
- Create components from repeated elements
|
||||
- Set up auto-layout for responsive behavior
|
||||
- Define color and text styles
|
||||
- Add design system documentation
|
||||
4. Share with developers using Figma's inspect mode
|
||||
```
|
||||
|
||||
### Code Export Refinement
|
||||
|
||||
Improve exported HTML/CSS for production.
|
||||
|
||||
**Post-export tasks:**
|
||||
|
||||
1. **Semantic HTML**
|
||||
- Replace divs with semantic tags (header, nav, main, article, section, footer)
|
||||
- Add ARIA labels where needed
|
||||
- Ensure proper heading hierarchy
|
||||
|
||||
2. **CSS optimization**
|
||||
- Extract repeated styles into utility classes
|
||||
- Use CSS custom properties for theme values
|
||||
- Organize with methodology (BEM, SMACSS, etc.)
|
||||
- Add responsive media queries if missing
|
||||
|
||||
3. **Accessibility**
|
||||
- Add alt text to images
|
||||
- Ensure form labels are associated
|
||||
- Add focus styles
|
||||
- Test with screen reader
|
||||
|
||||
4. **Performance**
|
||||
- Optimize images
|
||||
- Minify CSS
|
||||
- Remove unused styles
|
||||
- Add loading strategies
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
These advanced techniques help you move beyond basic Stitch usage to create production-ready, accessible, and performant designs. Combine these strategies with the core prompting principles to maximize your efficiency and output quality.
|
||||
|
||||
**Key takeaways:**
|
||||
- Use images and references to accelerate design
|
||||
- Establish design systems early for consistency
|
||||
- Design responsively from the start
|
||||
- Prioritize accessibility in every prompt
|
||||
- Think in reusable components
|
||||
- Plan for all states, not just happy paths
|
||||
- Refine exports before production use
|
||||
601
skills/stitch-ui-design/references/prompt-examples.md
Normal file
601
skills/stitch-ui-design/references/prompt-examples.md
Normal file
@@ -0,0 +1,601 @@
|
||||
# Stitch Prompt Examples Library
|
||||
|
||||
Comprehensive collection of effective Stitch prompts organized by use case and complexity level.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Landing Pages](#landing-pages)
|
||||
2. [Mobile Apps](#mobile-apps)
|
||||
3. [Dashboards](#dashboards)
|
||||
4. [E-commerce](#e-commerce)
|
||||
5. [Forms & Authentication](#forms--authentication)
|
||||
6. [Content Platforms](#content-platforms)
|
||||
7. [SaaS Applications](#saas-applications)
|
||||
|
||||
---
|
||||
|
||||
## Landing Pages
|
||||
|
||||
### Startup Landing Page
|
||||
|
||||
```
|
||||
Landing page for AI writing assistant startup
|
||||
|
||||
Hero Section:
|
||||
- Bold headline: "Write Better, Faster with AI"
|
||||
- Subheadline explaining value proposition
|
||||
- Primary CTA button "Start Free Trial"
|
||||
- Secondary CTA "Watch Demo"
|
||||
- Hero illustration showing product interface
|
||||
|
||||
Features Section:
|
||||
- 3-column grid with icons
|
||||
- Feature 1: AI-powered suggestions
|
||||
- Feature 2: Multi-language support
|
||||
- Feature 3: Team collaboration
|
||||
|
||||
Social Proof:
|
||||
- Customer logos (6 companies)
|
||||
- Testimonial cards with photos and quotes
|
||||
|
||||
Pricing:
|
||||
- 3-tier pricing table (Free, Pro, Enterprise)
|
||||
- Feature comparison
|
||||
- Annual/Monthly toggle
|
||||
|
||||
Style: Modern, tech-forward, trustworthy
|
||||
Colors: Deep purple primary, cyan accents, white background
|
||||
Typography: Sans-serif, clean and readable
|
||||
Platform: Responsive web
|
||||
```
|
||||
|
||||
### Service Business Landing
|
||||
|
||||
```
|
||||
Landing page for boutique yoga studio
|
||||
|
||||
Above Fold:
|
||||
- Full-width hero image of studio space
|
||||
- Centered headline: "Find Your Balance"
|
||||
- Class schedule CTA button
|
||||
- Location and hours overlay
|
||||
|
||||
Class Offerings:
|
||||
- Card grid (2x3) with class types
|
||||
- Each card: class name, duration, difficulty level, instructor photo
|
||||
- Hover effect reveals class description
|
||||
|
||||
Instructor Profiles:
|
||||
- Horizontal scrolling carousel
|
||||
- Circular photos with names and specialties
|
||||
|
||||
Testimonials:
|
||||
- Large quote format with student photos
|
||||
- 5-star ratings
|
||||
|
||||
Call-to-Action:
|
||||
- "Book Your First Class Free" banner
|
||||
- Contact form with name, email, phone
|
||||
|
||||
Style: Calm, organic, welcoming
|
||||
Colors: Sage green, warm beige, soft white
|
||||
Typography: Serif headings, sans-serif body
|
||||
Platform: Responsive web with mobile-first approach
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mobile Apps
|
||||
|
||||
### Fitness Tracking App
|
||||
|
||||
```
|
||||
Fitness tracking app - Home screen (iOS)
|
||||
|
||||
Top Section:
|
||||
- Greeting with user name and current date
|
||||
- Daily goal progress ring (calories, steps, active minutes)
|
||||
- Motivational message based on progress
|
||||
|
||||
Quick Stats Cards:
|
||||
- Today's steps with trend arrow
|
||||
- Active calories burned
|
||||
- Distance covered
|
||||
- Active time
|
||||
|
||||
Recent Workouts:
|
||||
- List of last 3 workouts with type, duration, calories
|
||||
- Thumbnail icons for workout type
|
||||
- Swipe actions for details/delete
|
||||
|
||||
Bottom Section:
|
||||
- "Start Workout" prominent button
|
||||
- Quick access to workout types (Run, Cycle, Strength, Yoga)
|
||||
|
||||
Bottom Navigation:
|
||||
- Home (active), Workouts, Progress, Profile
|
||||
|
||||
Style: Energetic, motivating, data-focused
|
||||
Colors: Vibrant orange primary, dark mode background, neon accents
|
||||
Typography: Bold headings, clear metrics
|
||||
Platform: iOS mobile (375x812px)
|
||||
```
|
||||
|
||||
### Food Delivery App
|
||||
|
||||
```
|
||||
Restaurant detail screen for food delivery app
|
||||
|
||||
Header:
|
||||
- Restaurant cover photo
|
||||
- Back button and favorite icon
|
||||
- Restaurant name, rating (4.5 stars), delivery time (25-35 min)
|
||||
- Cuisine tags (Italian, Pizza, Pasta)
|
||||
|
||||
Info Bar:
|
||||
- Delivery fee, minimum order, distance
|
||||
- Promo badge if applicable
|
||||
|
||||
Menu Categories:
|
||||
- Sticky horizontal scroll tabs (Popular, Pizza, Pasta, Salads, Drinks)
|
||||
|
||||
Menu Items:
|
||||
- Card layout with food photo, name, description, price
|
||||
- Add button with quantity selector
|
||||
- Dietary icons (vegetarian, spicy, etc.)
|
||||
|
||||
Floating Cart:
|
||||
- Bottom sheet showing cart summary
|
||||
- Item count and total price
|
||||
- "View Cart" button
|
||||
|
||||
Style: Appetite-appealing, easy to scan, vibrant
|
||||
Colors: Red primary (hunger-inducing), white background, food photography
|
||||
Typography: Friendly sans-serif
|
||||
Platform: Android mobile (360x800px)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dashboards
|
||||
|
||||
### Analytics Dashboard
|
||||
|
||||
```
|
||||
Web analytics dashboard for marketing team
|
||||
|
||||
Top Bar:
|
||||
- Date range selector (last 7 days, 30 days, custom)
|
||||
- Export button
|
||||
- Notification bell
|
||||
- User profile dropdown
|
||||
|
||||
Key Metrics Row:
|
||||
- 4 metric cards in a row
|
||||
- Card 1: Total visitors (with % change)
|
||||
- Card 2: Conversion rate (with trend sparkline)
|
||||
- Card 3: Bounce rate (with comparison to previous period)
|
||||
- Card 4: Average session duration
|
||||
|
||||
Main Chart:
|
||||
- Line chart showing traffic over time
|
||||
- Multiple lines for different sources (Organic, Paid, Social, Direct)
|
||||
- Interactive legend to toggle lines
|
||||
- Hover tooltips with exact values
|
||||
|
||||
Secondary Panels:
|
||||
- Left: Top pages table (page, views, avg time, bounce rate)
|
||||
- Right: Traffic sources pie chart with percentages
|
||||
|
||||
Bottom Section:
|
||||
- Recent conversions table with user, source, value, timestamp
|
||||
|
||||
Style: Clean, data-focused, professional
|
||||
Colors: Navy blue sidebar, white main area, colorful chart lines
|
||||
Typography: Monospace for numbers, sans-serif for labels
|
||||
Platform: Desktop web (1440px+)
|
||||
```
|
||||
|
||||
### Project Management Dashboard
|
||||
|
||||
```
|
||||
Project management dashboard - Team view
|
||||
|
||||
Sidebar:
|
||||
- Workspace selector dropdown
|
||||
- Navigation: Dashboard, Projects, Tasks, Team, Reports
|
||||
- Create new project button
|
||||
|
||||
Header:
|
||||
- Project name and status badge
|
||||
- Team member avatars (max 5, then +N)
|
||||
- Search bar
|
||||
- View options (Board, List, Calendar)
|
||||
|
||||
Kanban Board:
|
||||
- 4 columns: To Do, In Progress, Review, Done
|
||||
- Drag-and-drop cards
|
||||
- Each card shows: title, assignee avatar, due date, priority label, comment count
|
||||
- Add card button at bottom of each column
|
||||
|
||||
Right Panel:
|
||||
- Task details when card is selected
|
||||
- Description, attachments, comments, activity log
|
||||
|
||||
Quick Stats:
|
||||
- Progress bar showing completion percentage
|
||||
- Tasks by status mini chart
|
||||
- Upcoming deadlines list
|
||||
|
||||
Style: Modern, organized, collaborative
|
||||
Colors: Purple primary, light gray background, status color coding
|
||||
Typography: Clear sans-serif, readable at all sizes
|
||||
Platform: Desktop web (1280px+)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## E-commerce
|
||||
|
||||
### Product Detail Page
|
||||
|
||||
```
|
||||
Product detail page for fashion e-commerce
|
||||
|
||||
Image Gallery:
|
||||
- Main product image (large, zoomable)
|
||||
- Thumbnail strip below (5-6 images)
|
||||
- 360° view option
|
||||
- Video thumbnail if available
|
||||
|
||||
Product Info:
|
||||
- Brand name
|
||||
- Product title
|
||||
- Star rating (4.8) with review count (234 reviews)
|
||||
- Price with original price struck through if on sale
|
||||
- Sale badge if applicable
|
||||
|
||||
Options:
|
||||
- Size selector (XS, S, M, L, XL) with availability indicators
|
||||
- Color swatches with product image preview on hover
|
||||
- Quantity selector
|
||||
|
||||
Actions:
|
||||
- Add to Cart button (prominent)
|
||||
- Add to Wishlist button (outline)
|
||||
- Size guide link
|
||||
- Shipping calculator
|
||||
|
||||
Product Details:
|
||||
- Tabbed interface (Description, Specifications, Reviews, Shipping)
|
||||
- Expandable sections on mobile
|
||||
|
||||
Recommendations:
|
||||
- "You May Also Like" carousel
|
||||
- "Complete the Look" suggestions
|
||||
|
||||
Style: Clean, product-focused, trustworthy
|
||||
Colors: Black and white with brand accent color (burgundy)
|
||||
Typography: Elegant serif for headings, sans-serif for body
|
||||
Platform: Responsive web
|
||||
```
|
||||
|
||||
### Shopping Cart
|
||||
|
||||
```
|
||||
Shopping cart page with checkout flow
|
||||
|
||||
Cart Items:
|
||||
- List of products with thumbnail, name, size/color, price
|
||||
- Quantity adjuster (+/- buttons)
|
||||
- Remove item link
|
||||
- Save for later option
|
||||
|
||||
Order Summary:
|
||||
- Sticky sidebar on desktop, bottom sheet on mobile
|
||||
- Subtotal
|
||||
- Shipping (calculated or "Free over $50")
|
||||
- Tax (estimated)
|
||||
- Discount code input field
|
||||
- Total (prominent)
|
||||
- Checkout button (large, primary color)
|
||||
|
||||
Trust Signals:
|
||||
- Secure checkout badge
|
||||
- Free returns policy
|
||||
- Customer service contact
|
||||
|
||||
Recommendations:
|
||||
- "Frequently Bought Together" section
|
||||
- Promotional banner for free shipping threshold
|
||||
|
||||
Empty State:
|
||||
- Illustration
|
||||
- "Your cart is empty" message
|
||||
- "Continue Shopping" button
|
||||
- Recently viewed items
|
||||
|
||||
Style: Clean, conversion-focused, reassuring
|
||||
Colors: Green for checkout CTA, neutral grays, trust badges
|
||||
Typography: Clear pricing, readable product names
|
||||
Platform: Responsive web
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Forms & Authentication
|
||||
|
||||
### Multi-Step Signup Form
|
||||
|
||||
```
|
||||
B2B SaaS signup flow - 3 steps
|
||||
|
||||
Progress Indicator:
|
||||
- Step 1: Account (active)
|
||||
- Step 2: Company
|
||||
- Step 3: Team
|
||||
|
||||
Step 1 - Account Details:
|
||||
- Email input with validation
|
||||
- Password input with strength indicator
|
||||
- Confirm password
|
||||
- Terms and conditions checkbox
|
||||
- "Continue" button
|
||||
- "Already have an account? Sign in" link
|
||||
|
||||
Step 2 - Company Information:
|
||||
- Company name
|
||||
- Industry dropdown
|
||||
- Company size radio buttons (1-10, 11-50, 51-200, 201+)
|
||||
- Role/Title input
|
||||
- "Back" and "Continue" buttons
|
||||
|
||||
Step 3 - Invite Team:
|
||||
- Email input fields (dynamic, add more)
|
||||
- Role selector for each invite
|
||||
- "Skip for now" option
|
||||
- "Finish Setup" button
|
||||
|
||||
Success State:
|
||||
- Checkmark animation
|
||||
- "Welcome to [Product]!" message
|
||||
- "Go to Dashboard" button
|
||||
|
||||
Style: Minimal, focused, low-friction
|
||||
Colors: Blue primary, white background, green success states
|
||||
Typography: Clear labels, helpful microcopy
|
||||
Platform: Responsive web, mobile-optimized
|
||||
```
|
||||
|
||||
### Login Page
|
||||
|
||||
```
|
||||
Login page for enterprise software
|
||||
|
||||
Left Panel (Desktop):
|
||||
- Brand logo
|
||||
- Hero image or illustration
|
||||
- Value proposition headline
|
||||
- Key benefits (3 bullet points)
|
||||
|
||||
Right Panel (Form):
|
||||
- "Welcome back" heading
|
||||
- Email input field
|
||||
- Password input field with show/hide toggle
|
||||
- "Remember me" checkbox
|
||||
- "Forgot password?" link
|
||||
- "Sign In" button (full width)
|
||||
- Divider with "OR"
|
||||
- SSO options (Google, Microsoft, Okta) as buttons with logos
|
||||
- "Don't have an account? Sign up" link at bottom
|
||||
|
||||
Security Indicators:
|
||||
- SSL badge
|
||||
- "Your data is secure" message
|
||||
|
||||
Style: Professional, trustworthy, enterprise-grade
|
||||
Colors: Corporate blue, white, subtle grays
|
||||
Typography: Professional sans-serif
|
||||
Platform: Responsive (left panel hidden on mobile)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Content Platforms
|
||||
|
||||
### Blog Post Layout
|
||||
|
||||
```
|
||||
Blog article page for tech publication
|
||||
|
||||
Header:
|
||||
- Site navigation (logo, categories, search, subscribe)
|
||||
|
||||
Article Header:
|
||||
- Category tag
|
||||
- Article title (large, bold)
|
||||
- Subtitle/excerpt
|
||||
- Author info (photo, name, bio link, publish date)
|
||||
- Social share buttons
|
||||
- Reading time estimate
|
||||
|
||||
Article Body:
|
||||
- Readable column width (max 680px)
|
||||
- Paragraph text with proper line height
|
||||
- H2 and H3 subheadings
|
||||
- Pull quotes (styled distinctly)
|
||||
- Inline images with captions
|
||||
- Code blocks with syntax highlighting
|
||||
- Embedded videos
|
||||
- Table of contents (sticky sidebar on desktop)
|
||||
|
||||
Article Footer:
|
||||
- Tags
|
||||
- Share buttons
|
||||
- Author card (expanded)
|
||||
- Related articles (3 cards)
|
||||
- Comments section
|
||||
|
||||
Sidebar (Desktop):
|
||||
- Newsletter signup
|
||||
- Popular posts
|
||||
- Ad placement
|
||||
|
||||
Style: Editorial, readable, content-first
|
||||
Colors: Black text on white, accent color for links
|
||||
Typography: Serif for body text, sans-serif for UI
|
||||
Platform: Responsive web
|
||||
```
|
||||
|
||||
### Video Platform Interface
|
||||
|
||||
```
|
||||
Video streaming platform - Watch page
|
||||
|
||||
Video Player:
|
||||
- Full-width video player with controls
|
||||
- Quality selector, playback speed, captions, fullscreen
|
||||
- Progress bar with thumbnail preview on hover
|
||||
|
||||
Video Info:
|
||||
- Video title
|
||||
- View count and upload date
|
||||
- Like/Dislike buttons
|
||||
- Share button
|
||||
- Save to playlist button
|
||||
|
||||
Channel Info:
|
||||
- Channel avatar and name
|
||||
- Subscriber count
|
||||
- Subscribe button (prominent if not subscribed)
|
||||
|
||||
Description:
|
||||
- Expandable description text
|
||||
- Show more/less toggle
|
||||
- Hashtags and links
|
||||
|
||||
Comments Section:
|
||||
- Sort options (Top, Newest)
|
||||
- Comment input with user avatar
|
||||
- Comment cards with avatar, name, timestamp, text
|
||||
- Like/Reply buttons
|
||||
- Nested replies (indented)
|
||||
|
||||
Sidebar:
|
||||
- Up next autoplay preview
|
||||
- Recommended videos list (thumbnail, title, channel, views)
|
||||
|
||||
Style: Dark mode, video-focused, minimal distractions
|
||||
Colors: Dark gray background, white text, red accent for CTAs
|
||||
Typography: Sans-serif, readable at distance
|
||||
Platform: Responsive web
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SaaS Applications
|
||||
|
||||
### Email Client Interface
|
||||
|
||||
```
|
||||
Email client - Inbox view
|
||||
|
||||
Left Sidebar:
|
||||
- Compose button (prominent)
|
||||
- Folder list (Inbox, Sent, Drafts, Spam, Trash)
|
||||
- Labels/Tags with color coding
|
||||
- Storage usage indicator
|
||||
|
||||
Email List (Center):
|
||||
- Search bar with filters
|
||||
- Sort and view options
|
||||
- Email rows showing:
|
||||
- Sender avatar/initial
|
||||
- Sender name (bold if unread)
|
||||
- Subject line
|
||||
- Preview text (truncated)
|
||||
- Timestamp
|
||||
- Attachment icon if present
|
||||
- Star/flag icons
|
||||
- Checkbox for bulk actions
|
||||
- Pagination or infinite scroll
|
||||
|
||||
Email Detail (Right):
|
||||
- Email header (from, to, cc, timestamp)
|
||||
- Subject line
|
||||
- Email body with formatting preserved
|
||||
- Attachments section
|
||||
- Action buttons (Reply, Reply All, Forward, Archive, Delete)
|
||||
- Previous emails in thread (collapsed)
|
||||
|
||||
Top Bar:
|
||||
- Refresh button
|
||||
- Settings icon
|
||||
- User profile dropdown
|
||||
|
||||
Style: Clean, productivity-focused, organized
|
||||
Colors: Blue accents, white background, gray dividers
|
||||
Typography: Sans-serif, scannable
|
||||
Platform: Desktop web (1280px+)
|
||||
```
|
||||
|
||||
### CRM Contact Detail
|
||||
|
||||
```
|
||||
CRM contact detail page
|
||||
|
||||
Header:
|
||||
- Contact name and company
|
||||
- Contact photo/avatar
|
||||
- Status badge (Lead, Customer, Inactive)
|
||||
- Quick actions (Email, Call, Schedule Meeting, Edit)
|
||||
|
||||
Info Tabs:
|
||||
- Overview (active), Activity, Deals, Notes, Files
|
||||
|
||||
Overview Tab:
|
||||
- Contact information card (email, phone, address, social links)
|
||||
- Company information card
|
||||
- Tags and custom fields
|
||||
- Assigned to (team member)
|
||||
|
||||
Activity Timeline:
|
||||
- Chronological list of interactions
|
||||
- Icons for type (email, call, meeting, note)
|
||||
- Timestamp and description
|
||||
- Filter by activity type
|
||||
|
||||
Deals Section:
|
||||
- Active deals table (deal name, value, stage, close date)
|
||||
- Won/Lost deals summary
|
||||
|
||||
Notes Section:
|
||||
- Add note input with rich text editor
|
||||
- Note cards with author, timestamp, content
|
||||
- Pin important notes
|
||||
|
||||
Right Sidebar:
|
||||
- Next scheduled activity
|
||||
- Recent emails
|
||||
- Related contacts
|
||||
- Deal pipeline stage
|
||||
|
||||
Style: Professional, data-rich, organized
|
||||
Colors: Navy blue, white, status color coding
|
||||
Typography: Clear hierarchy, readable data
|
||||
Platform: Desktop web (1440px+)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tips for Using These Examples
|
||||
|
||||
1. **Customize for your needs** - Replace placeholder content with your specific requirements
|
||||
2. **Combine elements** - Mix and match components from different examples
|
||||
3. **Adjust complexity** - Simplify or expand based on your project scope
|
||||
4. **Specify your brand** - Add your color palette, fonts, and visual style
|
||||
5. **Consider platform** - Adapt layouts for your target device (mobile/desktop)
|
||||
6. **Add context** - Include user personas or use cases for better results
|
||||
7. **Iterate** - Start with a basic prompt, then refine with annotations
|
||||
|
||||
Remember: These are starting points. Stitch works best when you provide specific details relevant to your unique project.
|
||||
@@ -2186,6 +2186,33 @@
|
||||
"risk": "unknown",
|
||||
"source": "unknown"
|
||||
},
|
||||
{
|
||||
"id": "fp-ts-errors",
|
||||
"path": "skills/fp-ts-errors",
|
||||
"category": "uncategorized",
|
||||
"name": "fp-ts-errors",
|
||||
"description": "Handle errors as values using fp-ts Either and TaskEither for cleaner, more predictable TypeScript code. Use when implementing error handling patterns with fp-ts.",
|
||||
"risk": "safe",
|
||||
"source": "https://github.com/whatiskadudoing/fp-ts-skills"
|
||||
},
|
||||
{
|
||||
"id": "fp-ts-pragmatic",
|
||||
"path": "skills/fp-ts-pragmatic",
|
||||
"category": "uncategorized",
|
||||
"name": "fp-ts-pragmatic",
|
||||
"description": "A practical, jargon-free guide to fp-ts functional programming - the 80/20 approach that gets results without the academic overhead. Use when writing TypeScript with fp-ts library.",
|
||||
"risk": "safe",
|
||||
"source": "https://github.com/whatiskadudoing/fp-ts-skills"
|
||||
},
|
||||
{
|
||||
"id": "fp-ts-react",
|
||||
"path": "skills/fp-ts-react",
|
||||
"category": "uncategorized",
|
||||
"name": "fp-ts-react",
|
||||
"description": "Practical patterns for using fp-ts with React - hooks, state, forms, data fetching. Use when building React apps with functional programming patterns. Works with React 18/19, Next.js 14/15.",
|
||||
"risk": "safe",
|
||||
"source": "https://github.com/whatiskadudoing/fp-ts-skills"
|
||||
},
|
||||
{
|
||||
"id": "framework-migration-code-migrate",
|
||||
"path": "skills/framework-migration-code-migrate",
|
||||
@@ -2222,15 +2249,6 @@
|
||||
"risk": "unknown",
|
||||
"source": "unknown"
|
||||
},
|
||||
{
|
||||
"id": "frontend-slides",
|
||||
"path": "skills/frontend-slides",
|
||||
"category": "uncategorized",
|
||||
"name": "Frontend Slides",
|
||||
"description": "Create zero-dependency, animation-rich HTML presentations that run entirely in the browser. This skill helps non-designers discover their preferred aesthetic through visual exploration (\"show, don't tell\"), then generates production-quality slide dec",
|
||||
"risk": "unknown",
|
||||
"source": "unknown"
|
||||
},
|
||||
{
|
||||
"id": "frontend-design",
|
||||
"path": "skills/frontend-design",
|
||||
@@ -2294,6 +2312,15 @@
|
||||
"risk": "unknown",
|
||||
"source": "unknown"
|
||||
},
|
||||
{
|
||||
"id": "frontend-slides",
|
||||
"path": "skills/frontend-slides",
|
||||
"category": "uncategorized",
|
||||
"name": "frontend-slides",
|
||||
"description": "Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.",
|
||||
"risk": "safe",
|
||||
"source": "https://github.com/zarazhangrui/frontend-slides"
|
||||
},
|
||||
{
|
||||
"id": "full-stack-orchestration-full-stack-feature",
|
||||
"path": "skills/full-stack-orchestration-full-stack-feature",
|
||||
@@ -3950,6 +3977,15 @@
|
||||
"risk": "unknown",
|
||||
"source": "unknown"
|
||||
},
|
||||
{
|
||||
"id": "radix-ui-design-system",
|
||||
"path": "skills/radix-ui-design-system",
|
||||
"category": "uncategorized",
|
||||
"name": "radix-ui-design-system",
|
||||
"description": "Build accessible design systems with Radix UI primitives. Headless component customization, theming strategies, and compound component patterns for production-grade UI libraries.",
|
||||
"risk": "safe",
|
||||
"source": "self"
|
||||
},
|
||||
{
|
||||
"id": "rag-engineer",
|
||||
"path": "skills/rag-engineer",
|
||||
@@ -4760,6 +4796,15 @@
|
||||
"risk": "unknown",
|
||||
"source": "unknown"
|
||||
},
|
||||
{
|
||||
"id": "stitch-ui-design",
|
||||
"path": "skills/stitch-ui-design",
|
||||
"category": "uncategorized",
|
||||
"name": "stitch-ui-design",
|
||||
"description": "Expert guide for creating effective prompts for Google Stitch AI UI design tool. Use when user wants to design UI/UX in Stitch, create app interfaces, generate mobile/web designs, or needs help crafting Stitch prompts. Covers prompt structure, specificity techniques, iteration strategies, and design-to-code workflows for Stitch by Google.",
|
||||
"risk": "safe",
|
||||
"source": "self"
|
||||
},
|
||||
{
|
||||
"id": "stride-analysis-patterns",
|
||||
"path": "skills/stride-analysis-patterns",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user