Compare commits

...

16 Commits

Author SHA1 Message Date
sck_0
c06d53137d chore: release v5.5.0 2026-02-16 13:28:18 +01:00
sck_0
3f08ade5c6 chore: sync generated files and fix frontmatter 2026-02-16 13:28:04 +01:00
Mert Başkurt
1e797799a9 feat: add react-flow-architect skill (#88)
- Expert ReactFlow architect for interactive graph applications
- Hierarchical navigation with expand/collapse patterns
- Performance optimization with incremental rendering
- State management with reducer and history
- Auto-layout integration with Dagre
- Focus mode and search functionality
- Complete production-ready examples
2026-02-16 13:26:18 +01:00
Nilay Sharma
49153de3de Fix OpenCode path in README.md (#87)
Updated the OpenCode path to reflect changes in the documentation and usage instructions.
2026-02-16 13:26:15 +01:00
Musa Yerleşmiş
602bd61852 feat: add laravel-security-audit skill (#86)
Co-authored-by: KOZUVA <kozuva@KZV-MacBook-Pro.local>
2026-02-16 13:26:12 +01:00
Musa Yerleşmiş
d8ee68d619 feat: add laravel-expert skill (#85)
Co-authored-by: KOZUVA <kozuva@KZV-MacBook-Pro.local>
2026-02-16 13:26:09 +01:00
github-actions[bot]
03181d82ac chore: update star history chart 2026-02-16 06:59:53 +00:00
sck_0
2bf75ae499 docs: update welcome and release to V5.4.0
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-16 07:31:44 +01:00
sck_0
aea984a2e3 chore: release v5.4.0
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-16 07:22:27 +01:00
github-actions[bot]
30e267cdcd chore: sync generated registry files [ci skip] 2026-02-16 06:21:00 +00:00
8hoursking
37349607ae New skill - go-rod-master. Browser automation with Golang (#83)
* New skill - go-rod-master. Pretty big skill for browser automation with go and go-rod.

* chore: sync generated registry files

---------

Co-authored-by: 8hoursking <user@MacBook-Pro-user.local>
2026-02-16 07:20:43 +01:00
Wittlesus
2382b7439c Add CursorRules Pro to Community Contributors (#81) 2026-02-16 07:20:38 +01:00
github-actions[bot]
4e87d6e393 chore: update star history chart 2026-02-15 06:48:07 +00:00
sck_0
a4c74c869d fix: quote scoped package names in skill frontmatter and update validator (#79)
- Wrapped unquoted @scope/pkg values in double quotes across 19 SKILL.md files.
- Added 'package' to ALLOWED_FIELDS in JS validator.
- Added YAML validity regression test to test suite.
- Updated package-lock.json.

Fixes #79
Closes #80
2026-02-14 09:46:47 +01:00
github-actions[bot]
f4a2f1d23d chore: update star history chart 2026-02-14 06:40:52 +00:00
sck_0
8e82b5e0f6 chore: cleanup temporary release notes 2026-02-13 15:11:52 +01:00
40 changed files with 2443 additions and 133 deletions

View File

@@ -2,7 +2,7 @@
Generated at: 2026-02-08T00:00:00.000Z
Total skills: 856
Total skills: 860
## architecture (64)
@@ -300,7 +300,7 @@ Use when creating container-based agents that run custom code in Azure ... | hos
| `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 |
| `youtube-automation` | Automate YouTube tasks via Rube MCP (Composio): upload videos, manage playlists, search content, get analytics, and handle comments. Always search tools firs... | youtube | youtube, automation, automate, tasks, via, rube, mcp, composio, upload, videos, playlists, search |
## development (127)
## development (129)
| Skill | Description | Tags | Triggers |
| --- | --- | --- | --- |
@@ -392,6 +392,7 @@ Triggers: "queue storage", "QueueServic... | azure, storage, queue, py | azure,
| `gemini-api-dev` | Use this skill when building applications with Gemini models, Gemini API, working with multimodal content (text, images, audio, video), implementing function... | gemini, api, dev | gemini, api, dev, skill, building, applications, models, working, multimodal, content, text, images |
| `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 |
| `go-playwright` | Expert capability for robust, stealthy, and efficient browser automation using Playwright Go. | go, playwright | go, playwright, capability, robust, stealthy, efficient, browser, automation |
| `go-rod-master` | Comprehensive guide for browser automation and web scraping with go-rod (Chrome DevTools Protocol) including stealth anti-bot-detection patterns. | go, rod, master | go, rod, master, browser, automation, web, scraping, chrome, devtools, protocol, including, stealth |
| `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 |
| `javascript-mastery` | Comprehensive JavaScript reference covering 33+ essential concepts every developer should know. From fundamentals like primitives and closures to advanced pa... | javascript, mastery | javascript, mastery, reference, covering, 33, essential, concepts, every, developer, should, know, fundamentals |
@@ -419,6 +420,7 @@ Triggers: "queue storage", "QueueServic... | azure, storage, queue, py | azure,
| `python-performance-optimization` | Profile and optimize Python code using cProfile, memory profilers, and performance best practices. Use when debugging slow Python code, optimizing bottleneck... | python, performance, optimization | python, performance, optimization, profile, optimize, code, cprofile, memory, profilers, debugging, slow, optimizing |
| `python-pro` | Master Python 3.12+ with modern features, async programming, performance optimization, and production-ready practices. Expert in the latest Python ecosystem ... | python | python, pro, 12, features, async, programming, performance, optimization, latest, ecosystem, including, uv |
| `python-testing-patterns` | Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development. Use when writing Python tests, setting up test suites... | python | python, testing, pytest, fixtures, mocking, test, driven, development, writing, tests, setting, up |
| `react-flow-architect` | Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integra... | react, flow | react, flow, architect, reactflow, building, interactive, graph, applications, hierarchical, node, edge, performance |
| `react-flow-node-ts` | Create React Flow node components with TypeScript types, handles, and Zustand integration. Use when building custom nodes for React Flow canvas, creating vis... | react, flow, node, ts | react, flow, node, ts, components, typescript, types, zustand, integration, building, custom, nodes |
| `react-modernization` | Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, m... | react, modernization | react, modernization, upgrade, applications, latest, versions, migrate, class, components, hooks, adopt, concurrent |
| `react-native-architecture` | Build production React Native apps with Expo, navigation, native modules, offline sync, and cross-platform patterns. Use when developing mobile apps, impleme... | react, native, architecture | react, native, architecture, apps, expo, navigation, modules, offline, sync, cross, platform, developing |
@@ -704,7 +706,7 @@ Triggers: "azure-storage-file-share", "Share... | azure, storage, file, share, p
| `wireshark-analysis` | This skill should be used when the user asks to "analyze network traffic with Wireshark", "capture packets for troubleshooting", "filter PCAP files", "follow... | wireshark | wireshark, network, traffic, analysis, skill, should, used, user, asks, analyze, capture, packets |
| `workflow-automation` | Workflow automation is the infrastructure that makes AI agents reliable. Without durable execution, a network hiccup during a 10-step payment flow means lost... | | automation, infrastructure, makes, ai, agents, reliable, without, durable, execution, network, hiccup, during |
## security (126)
## security (128)
| Skill | Description | Tags | Triggers |
| --- | --- | --- | --- |
@@ -774,6 +776,8 @@ Triggers: "keyvault secrets rust", "SecretClient rust"... | azure, keyvault, sec
| `k8s-manifest-generator` | Create production-ready Kubernetes manifests for Deployments, Services, ConfigMaps, and Secrets following best practices and security standards. Use when gen... | k8s, manifest, generator | k8s, manifest, generator, kubernetes, manifests, deployments, configmaps, secrets, following, security, standards, generating |
| `k8s-security-policies` | Implement Kubernetes security policies including NetworkPolicy, PodSecurityPolicy, and RBAC for production-grade security. Use when securing Kubernetes clust... | k8s, security, policies | k8s, security, policies, kubernetes, including, networkpolicy, podsecuritypolicy, rbac, grade, securing, clusters, implementing |
| `kubernetes-architect` | Expert Kubernetes architect specializing in cloud-native infrastructure, advanced GitOps workflows (ArgoCD/Flux), and enterprise container orchestration. Mas... | kubernetes | kubernetes, architect, specializing, cloud, native, infrastructure, gitops, argocd, flux, enterprise, container, orchestration |
| `laravel-expert` | Senior Laravel Engineer role for production-grade, maintainable, and idiomatic Laravel solutions. Focuses on clean architecture, security, performance, and m... | laravel | laravel, senior, engineer, role, grade, maintainable, idiomatic, solutions, clean, architecture, security, performance |
| `laravel-security-audit` | Security auditor for Laravel applications. Analyzes code for vulnerabilities, misconfigurations, and insecure practices using OWASP standards and Laravel sec... | laravel, security, audit | laravel, security, audit, auditor, applications, analyzes, code, vulnerabilities, misconfigurations, insecure, owasp, standards |
| `legal-advisor` | Draft privacy policies, terms of service, disclaimers, and legal notices. Creates GDPR-compliant texts, cookie policies, and data processing agreements. Use ... | legal, advisor | legal, advisor, draft, privacy, policies, terms, disclaimers, notices, creates, gdpr, compliant, texts |
| `linkerd-patterns` | Implement Linkerd service mesh patterns for lightweight, security-focused service mesh deployments. Use when setting up Linkerd, configuring traffic policies... | linkerd | linkerd, mesh, lightweight, security, deployments, setting, up, configuring, traffic, policies, implementing, zero |
| `loki-mode` | Multi-agent autonomous startup system for Claude Code. Triggers on "Loki Mode". Orchestrates 100+ specialized agents across engineering, QA, DevOps, security... | loki, mode | loki, mode, multi, agent, autonomous, startup, claude, code, triggers, orchestrates, 100, specialized |

View File

@@ -7,6 +7,69 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
## [5.5.0] - 2026-02-16 - "Laravel Pro & ReactFlow Architect"
> **Advanced Laravel engineering roles and ReactFlow architecture patterns.**
This release introduces professional Laravel capabilities (Expert & Security Auditor) and a comprehensive ReactFlow Architect skill for building complex node-based applications.
### Added
- **New Skill**: `laravel-expert` - Senior Laravel Engineer role for production-grade, maintainable, and idiomatic solutions (clean architecture, security, performance).
- **New Skill**: `laravel-security-audit` - Specialized security auditor for Laravel apps (OWASP, vulnerabilities, misconfigurations).
- **New Skill**: `react-flow-architect` - Expert ReactFlow patterns for interactive graph apps (hierarchical navigation, performance, customized state management).
### Changed
- **OpenCode**: Updated installation path to `.agents/skills` to align with latest OpenCode standards.
### Registry
- **Total Skills**: 860 (from 857).
- **Generated Files**: Synced `skills_index.json`, `data/catalog.json`, and `README.md`.
### Contributors
- **[@Musayrlsms](https://github.com/Musayrlsms)** - Laravel Expert & Security Audit skills (PR #85, #86).
- **[@mertbaskurt](https://github.com/mertbaskurt)** - ReactFlow Architect skill (PR #88).
- **[@sharmanilay](https://github.com/sharmanilay)** - OpenCode path fix (PR #87).
---
## [5.4.0] - 2026-02-16 - "CursorRules Pro & Go-Rod"
> **Community contributions: CursorRules Pro in credits and go-rod-master skill for browser automation with Go.**
This release adds CursorRules Pro to Community Contributors and a new skill for browser automation and web scraping with go-rod (Chrome DevTools Protocol) in Golang, including stealth and anti-bot-detection patterns.
### New Skills
#### go-rod-master ([skills/go-rod-master/](skills/go-rod-master/))
**Browser automation and web scraping with Go and Chrome DevTools Protocol.**
Comprehensive guide for the go-rod library: launch and page lifecycle, Must vs error patterns, context and timeouts, element selectors, auto-wait, and integration with go-rod/stealth for anti-bot detection.
- **Key features**: CDP-native driver, thread-safe operations, stealth plugin, request hijacking, concurrent page pools.
- **When to use**: Scraping or automating sites with Go, headless browser for SPAs, stealth/anti-bot needs, migrating from chromedp or Playwright Go.
> **Try it:** "Automate logging into example.com with Go using go-rod and stealth."
### Registry
- **Total Skills**: 857 (from 856).
- **Generated files**: README, skills_index.json, catalog, and bundles synced.
### Credits
- **[@Wittlesus](https://github.com/Wittlesus)** - CursorRules Pro in Community Contributors (PR #81).
- **[@8hrsk](https://github.com/8hrsk)** - go-rod-master skill (PR #83).
---
_Upgrade now: `git pull origin main` to fetch the latest skills._
---
## [5.3.0] - 2026-02-13 - "Advanced Three.js & Modern Graphics"
> **Enhanced Three.js patterns: performance, visual polish, and production practices.**

View File

@@ -1,6 +1,6 @@
# 🌌 Antigravity Awesome Skills: 856+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
# 🌌 Antigravity Awesome Skills: 860+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
> **The Ultimate Collection of 856+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode, AdaL**
> **The Ultimate Collection of 860+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode, AdaL**
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Claude Code](https://img.shields.io/badge/Claude%20Code-Anthropic-purple)](https://claude.ai)
@@ -16,7 +16,7 @@
If this project helps you, you can [support it here](https://buymeacoffee.com/sickn33) or simply ⭐ the repo.
**Antigravity Awesome Skills** is a curated, battle-tested library of **856 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
**Antigravity Awesome Skills** is a curated, battle-tested library of **860 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants:
- 🟣 **Claude Code** (Anthropic CLI)
- 🔵 **Gemini CLI** (Google DeepMind)
@@ -38,7 +38,7 @@ This repository provides essential skills to transform your AI assistant into a
- [🎁 Curated Collections (Bundles)](#curated-collections)
- [🧭 Antigravity Workflows](#antigravity-workflows)
- [📦 Features & Categories](#features--categories)
- [📚 Browse 856+ Skills](#browse-856-skills)
- [📚 Browse 860+ Skills](#browse-860-skills)
- [🤝 How to Contribute](#how-to-contribute)
- [🤝 Community](#community)
- [☕ Support the Project](#support-the-project)
@@ -52,11 +52,11 @@ This repository provides essential skills to transform your AI assistant into a
## New Here? Start Here!
**Welcome to the V5.2.0 Workflows Edition.** This isn't just a list of scripts; it's a complete operating system for your AI Agent.
**Welcome to the V5.4.0 Workflows Edition.** This isn't just a list of scripts; it's a complete operating system for your AI Agent.
### 1. 🐣 Context: What is this?
**Antigravity Awesome Skills** (Release 5.2.0) is a massive upgrade to your AI's capabilities.
**Antigravity Awesome Skills** (Release 5.4.0) is a massive upgrade to your AI's capabilities.
AI Agents (like Claude Code, Cursor, or Gemini) are smart, but they lack **specific tools**. They don't know your company's "Deployment Protocol" or the specific syntax for "AWS CloudFormation".
**Skills** are small markdown files that teach them how to do these specific tasks perfectly, every time.
@@ -110,11 +110,12 @@ These skills follow the universal **SKILL.md** format and work with any AI codin
| **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/` |
| **OpenCode** | CLI | `opencode run @skill-name` | `.agents/skills/` |
| **AdaL CLI** | CLI | `(Auto) Skills load on-demand` | `.adal/skills/` |
> [!TIP]
> **Universal Path**: We recommend cloning to `.agent/skills/`. Most modern tools (Antigravity, recent CLIs) look here by default.
> **OpenCode Path Update**: opencode path is changed to `.agents/skills` for global skills. See [Place Files](https://opencode.ai/docs/skills/#place-files) directive on OpenCode Docs.
> [!WARNING]
> **Windows Users**: this repository uses **symlinks** for official skills.
@@ -144,8 +145,8 @@ npx antigravity-awesome-skills --gemini
# Codex CLI
npx antigravity-awesome-skills --codex
# OpenCode (Universal)
npx antigravity-awesome-skills
# OpenCode
npx antigravity-awesome-skills --path .agents/skills
# Custom path
npx antigravity-awesome-skills --path ./my-skills
@@ -171,8 +172,8 @@ git clone https://github.com/sickn33/antigravity-awesome-skills.git .codex/skill
# 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
# OpenCode
git clone https://github.com/sickn33/antigravity-awesome-skills.git .agents/skills
```
---
@@ -280,7 +281,7 @@ The repository is organized into specialized domains to transform your AI into a
Counts change as new skills are added. For the current full registry, see [CATALOG.md](CATALOG.md).
## Browse 856+ Skills
## Browse 860+ Skills
We have moved the full skill registry to a dedicated catalog to keep this README clean.
@@ -379,6 +380,7 @@ This collection would not be possible without the incredible work of the Claude
- **[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).
- **[Wittlesus/cursorrules-pro](https://github.com/Wittlesus/cursorrules-pro)**: Professional .cursorrules configurations for 8 frameworks - Next.js, React, Python, Go, Rust, and more. Works with Cursor, Claude Code, and Windsurf.
### Inspirations
@@ -437,6 +439,8 @@ We officially thank the following contributors for their help in making this rep
- [@ericgandrade](https://github.com/ericgandrade)
- [@sohamganatra](https://github.com/sohamganatra)
- [@Nguyen-Van-Chan](https://github.com/Nguyen-Van-Chan)
- [@8hrsk](https://github.com/8hrsk)
- [@Wittlesus](https://github.com/Wittlesus)
---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -148,6 +148,7 @@
"gemini-api-dev",
"go-concurrency-patterns",
"go-playwright",
"go-rod-master",
"golang-pro",
"graphql",
"hubspot-integration",
@@ -193,6 +194,7 @@
"python-pro",
"python-testing-patterns",
"react-best-practices",
"react-flow-architect",
"react-flow-node-ts",
"react-modernization",
"react-native-architecture",
@@ -289,6 +291,8 @@
"k8s-manifest-generator",
"k8s-security-policies",
"kubernetes-architect",
"laravel-expert",
"laravel-security-audit",
"legal-advisor",
"linkerd-patterns",
"loki-mode",

View File

@@ -1,6 +1,6 @@
{
"generatedAt": "2026-02-08T00:00:00.000Z",
"total": 856,
"total": 860,
"skills": [
{
"id": "3d-web-experience",
@@ -11041,6 +11041,32 @@
],
"path": "skills/go-playwright/SKILL.md"
},
{
"id": "go-rod-master",
"name": "go-rod-master",
"description": "Comprehensive guide for browser automation and web scraping with go-rod (Chrome DevTools Protocol) including stealth anti-bot-detection patterns.",
"category": "development",
"tags": [
"go",
"rod",
"master"
],
"triggers": [
"go",
"rod",
"master",
"browser",
"automation",
"web",
"scraping",
"chrome",
"devtools",
"protocol",
"including",
"stealth"
],
"path": "skills/go-rod-master/SKILL.md"
},
{
"id": "godot-gdscript-patterns",
"name": "godot-gdscript-patterns",
@@ -12381,6 +12407,56 @@
],
"path": "skills/langgraph/SKILL.md"
},
{
"id": "laravel-expert",
"name": "laravel-expert",
"description": "Senior Laravel Engineer role for production-grade, maintainable, and idiomatic Laravel solutions. Focuses on clean architecture, security, performance, and modern standards (Laravel 10/11+).",
"category": "security",
"tags": [
"laravel"
],
"triggers": [
"laravel",
"senior",
"engineer",
"role",
"grade",
"maintainable",
"idiomatic",
"solutions",
"clean",
"architecture",
"security",
"performance"
],
"path": "skills/laravel-expert/SKILL.md"
},
{
"id": "laravel-security-audit",
"name": "laravel-security-audit",
"description": "Security auditor for Laravel applications. Analyzes code for vulnerabilities, misconfigurations, and insecure practices using OWASP standards and Laravel security best practices.",
"category": "security",
"tags": [
"laravel",
"security",
"audit"
],
"triggers": [
"laravel",
"security",
"audit",
"auditor",
"applications",
"analyzes",
"code",
"vulnerabilities",
"misconfigurations",
"insecure",
"owasp",
"standards"
],
"path": "skills/laravel-security-audit/SKILL.md"
},
{
"id": "last30days",
"name": "last30days",
@@ -16031,6 +16107,31 @@
],
"path": "skills/react-best-practices/SKILL.md"
},
{
"id": "react-flow-architect",
"name": "react-flow-architect",
"description": "Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements.",
"category": "development",
"tags": [
"react",
"flow"
],
"triggers": [
"react",
"flow",
"architect",
"reactflow",
"building",
"interactive",
"graph",
"applications",
"hierarchical",
"node",
"edge",
"performance"
],
"path": "skills/react-flow-architect/SKILL.md"
},
{
"id": "react-flow-node-ts",
"name": "react-flow-node-ts",

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "antigravity-awesome-skills",
"version": "5.2.0",
"version": "5.5.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "antigravity-awesome-skills",
"version": "5.2.0",
"version": "5.5.0",
"license": "MIT",
"bin": {
"antigravity-awesome-skills": "bin/install.js"

View File

@@ -1,6 +1,6 @@
{
"name": "antigravity-awesome-skills",
"version": "5.3.0",
"version": "5.5.0",
"description": "845+ agentic skills for Claude Code, Gemini CLI, Cursor, Antigravity & more. Installer CLI.",
"license": "MIT",
"scripts": {

View File

@@ -1,36 +1,32 @@
## [5.0.0] - 2026-02-10 - "Antigravity Workflows Foundation"
# v5.4.0 - CursorRules Pro & Go-Rod
> First-class Workflows are now available to orchestrate multiple skills through guided execution playbooks.
> **Community contributions: CursorRules Pro in credits and go-rod-master skill for browser automation with Go.**
### 🚀 New Skills
This release adds CursorRules Pro to Community Contributors and a new skill for browser automation and web scraping with go-rod (Chrome DevTools Protocol) in Golang, including stealth and anti-bot-detection patterns.
### 🧭 [antigravity-workflows](skills/antigravity-workflows/)
## New Skills
**Orchestrates multi-step outcomes using curated workflow playbooks.**
This new skill routes users from high-level goals to concrete execution steps across related skills and bundles.
### go-rod-master
- **Key Feature 1**: Workflow routing for SaaS MVP, Security Audit, AI Agent Systems, and Browser QA.
- **Key Feature 2**: Explicit step-by-step outputs with prerequisites, recommended skills, and validation checkpoints.
**Browser automation and web scraping with Go and Chrome DevTools Protocol.**
> **Try it:** `Use @antigravity-workflows to run ship-saas-mvp for my project.`
Comprehensive guide for the go-rod library: launch and page lifecycle, Must vs error patterns, context and timeouts, element selectors, auto-wait, and integration with go-rod/stealth for anti-bot detection.
- **Key features**: CDP-native driver, thread-safe operations, stealth plugin, request hijacking, concurrent page pools.
- **When to use**: Scraping or automating sites with Go, headless browser for SPAs, stealth/anti-bot needs, migrating from chromedp or Playwright Go.
**Try it:** "Automate logging into example.com with Go using go-rod and stealth."
## Registry
- **Total Skills**: 857 (from 856).
- **Generated files**: README, skills_index.json, catalog, and bundles synced.
## Credits
- **@Wittlesus** - CursorRules Pro in Community Contributors (PR #81).
- **@8hrsk** - go-rod-master skill (PR #83).
---
## 📦 Improvements
- **Workflow Registry**: Added `data/workflows.json` for machine-readable workflow metadata.
- **Workflow Docs**: Added `docs/WORKFLOWS.md` to distinguish Bundles vs Workflows and provide practical execution playbooks.
- **Trinity Sync**: Updated `README.md`, `docs/GETTING_STARTED.md`, and `docs/FAQ.md` for workflow onboarding.
- **Go QA Path**: Added optional `@go-playwright` wiring in QA/E2E workflow steps.
- **Registry Update**: Catalog regenerated; repository now tracks 714 skills.
## 👥 Credits
A huge shoutout to our community and maintainers:
- **@Walapalam** for the Workflows concept request ([Issue #72](https://github.com/sickn33/antigravity-awesome-skills/issues/72))
- **@sickn33** for workflow integration, release preparation, and maintenance updates
---
_Upgrade now: `git pull origin main` to fetch the latest skills._
Upgrade now: `git pull origin main` to fetch the latest skills.

View File

@@ -1,11 +1,11 @@
const assert = require('assert');
const { hasUseSection } = require('../validate-skills');
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],
["## When to Use", true],
["## Use this skill when", true],
["## When to Use This Skill", true],
["## Overview", false],
];
for (const [heading, expected] of samples) {
@@ -13,4 +13,31 @@ for (const [heading, expected] of samples) {
assert.strictEqual(hasUseSection(content), expected, heading);
}
console.log('ok');
// Regression test for YAML validity in frontmatter (Issue #79)
const fs = require("fs");
const path = require("path");
const { listSkillIds, parseFrontmatter } = require("../../lib/skill-utils");
const SKILLS_DIR = path.join(__dirname, "../../skills");
const skillIds = listSkillIds(SKILLS_DIR);
console.log(`Checking YAML validity for ${skillIds.length} skills...`);
for (const skillId of skillIds) {
const skillPath = path.join(SKILLS_DIR, skillId, "SKILL.md");
const content = fs.readFileSync(skillPath, "utf8");
const { errors, hasFrontmatter } = parseFrontmatter(content);
if (!hasFrontmatter) {
console.warn(`[WARN] No frontmatter in ${skillId}`);
continue;
}
assert.strictEqual(
errors.length,
0,
`YAML parse errors in ${skillId}: ${errors.join(", ")}`,
);
}
console.log("ok");

View File

@@ -2,13 +2,13 @@
* Legacy / alternative validator. For CI and PR checks, use scripts/validate_skills.py.
* Run: npm run validate (or npm run validate:strict)
*/
const fs = require('fs');
const path = require('path');
const { listSkillIds, parseFrontmatter } = require('../lib/skill-utils');
const fs = require("fs");
const path = require("path");
const { listSkillIds, parseFrontmatter } = require("../lib/skill-utils");
const ROOT = path.resolve(__dirname, '..');
const SKILLS_DIR = path.join(ROOT, 'skills');
const BASELINE_PATH = path.join(ROOT, 'validation-baseline.json');
const ROOT = path.resolve(__dirname, "..");
const SKILLS_DIR = path.join(ROOT, "skills");
const BASELINE_PATH = path.join(ROOT, "validation-baseline.json");
const errors = [];
const warnings = [];
@@ -17,12 +17,14 @@ const missingDoNotUseSection = [];
const missingInstructionsSection = [];
const longFiles = [];
const unknownFieldSkills = [];
const isStrict = process.argv.includes('--strict')
|| process.env.STRICT === '1'
|| process.env.STRICT === 'true';
const writeBaseline = process.argv.includes('--write-baseline')
|| process.env.WRITE_BASELINE === '1'
|| process.env.WRITE_BASELINE === 'true';
const isStrict =
process.argv.includes("--strict") ||
process.env.STRICT === "1" ||
process.env.STRICT === "true";
const writeBaseline =
process.argv.includes("--write-baseline") ||
process.env.WRITE_BASELINE === "1" ||
process.env.WRITE_BASELINE === "true";
const NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
const MAX_NAME_LENGTH = 64;
@@ -30,14 +32,15 @@ const MAX_DESCRIPTION_LENGTH = 1024;
const MAX_COMPATIBILITY_LENGTH = 500;
const MAX_SKILL_LINES = 500;
const ALLOWED_FIELDS = new Set([
'name',
'description',
'risk',
'source',
'license',
'compatibility',
'metadata',
'allowed-tools',
"name",
"description",
"risk",
"source",
"license",
"compatibility",
"metadata",
"allowed-tools",
"package",
]);
const USE_SECTION_PATTERNS = [
@@ -47,15 +50,19 @@ const USE_SECTION_PATTERNS = [
];
function hasUseSection(content) {
return USE_SECTION_PATTERNS.some(pattern => pattern.test(content));
return USE_SECTION_PATTERNS.some((pattern) => pattern.test(content));
}
function isPlainObject(value) {
return value && typeof value === 'object' && !Array.isArray(value);
return value && typeof value === "object" && !Array.isArray(value);
}
function validateStringField(fieldName, value, { min = 1, max = Infinity } = {}) {
if (typeof value !== 'string') {
function validateStringField(
fieldName,
value,
{ min = 1, max = Infinity } = {},
) {
if (typeof value !== "string") {
return `${fieldName} must be a string.`;
}
const trimmed = value.trim();
@@ -90,24 +97,37 @@ function loadBaseline() {
}
try {
const parsed = JSON.parse(fs.readFileSync(BASELINE_PATH, 'utf8'));
const parsed = JSON.parse(fs.readFileSync(BASELINE_PATH, "utf8"));
return {
useSection: Array.isArray(parsed.useSection) ? parsed.useSection : [],
doNotUseSection: Array.isArray(parsed.doNotUseSection) ? parsed.doNotUseSection : [],
instructionsSection: Array.isArray(parsed.instructionsSection) ? parsed.instructionsSection : [],
doNotUseSection: Array.isArray(parsed.doNotUseSection)
? parsed.doNotUseSection
: [],
instructionsSection: Array.isArray(parsed.instructionsSection)
? parsed.instructionsSection
: [],
longFile: Array.isArray(parsed.longFile) ? parsed.longFile : [],
};
} catch (err) {
addWarning('Failed to parse validation-baseline.json; strict mode may fail.');
return { useSection: [], doNotUseSection: [], instructionsSection: [], longFile: [] };
addWarning(
"Failed to parse validation-baseline.json; strict mode may fail.",
);
return {
useSection: [],
doNotUseSection: [],
instructionsSection: [],
longFile: [],
};
}
}
function addStrictSectionErrors(label, missing, baselineSet) {
if (!isStrict) return;
const strictMissing = missing.filter(skillId => !baselineSet.has(skillId));
const strictMissing = missing.filter((skillId) => !baselineSet.has(skillId));
if (strictMissing.length) {
addError(`Missing "${label}" section (strict): ${strictMissing.length} skills (examples: ${strictMissing.slice(0, 5).join(', ')})`);
addError(
`Missing "${label}" section (strict): ${strictMissing.length} skills (examples: ${strictMissing.slice(0, 5).join(", ")})`,
);
}
}
@@ -120,15 +140,19 @@ function run() {
const baselineLongFile = new Set(baseline.longFile || []);
for (const skillId of skillIds) {
const skillPath = path.join(SKILLS_DIR, skillId, 'SKILL.md');
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 content = fs.readFileSync(skillPath, "utf8");
const {
data,
errors: fmErrors,
hasFrontmatter,
} = parseFrontmatter(content);
const lineCount = content.split(/\r?\n/).length;
if (!hasFrontmatter) {
@@ -136,7 +160,9 @@ function run() {
}
if (fmErrors && fmErrors.length) {
fmErrors.forEach(error => addError(`Frontmatter parse error (${skillId}): ${error}`));
fmErrors.forEach((error) =>
addError(`Frontmatter parse error (${skillId}): ${error}`),
);
}
if (!NAME_PATTERN.test(skillId)) {
@@ -144,7 +170,10 @@ function run() {
}
if (data.name !== undefined) {
const nameError = validateStringField('name', data.name, { min: 1, max: MAX_NAME_LENGTH });
const nameError = validateStringField("name", data.name, {
min: 1,
max: MAX_NAME_LENGTH,
});
if (nameError) {
addError(`${nameError} (${skillId})`);
} else {
@@ -158,15 +187,22 @@ function run() {
}
}
const descError = data.description === undefined
? 'description is required.'
: validateStringField('description', data.description, { min: 1, max: MAX_DESCRIPTION_LENGTH });
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 });
const licenseError = validateStringField("license", data.license, {
min: 1,
max: 128,
});
if (licenseError) {
addError(`${licenseError} (${skillId})`);
}
@@ -174,7 +210,7 @@ function run() {
if (data.compatibility !== undefined) {
const compatibilityError = validateStringField(
'compatibility',
"compatibility",
data.compatibility,
{ min: 1, max: MAX_COMPATIBILITY_LENGTH },
);
@@ -183,10 +219,12 @@ function run() {
}
}
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()) {
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})`);
}
}
@@ -196,7 +234,7 @@ function run() {
addError(`metadata must be a string map/object. (${skillId})`);
} else {
for (const [key, value] of Object.entries(data.metadata)) {
if (typeof value !== 'string') {
if (typeof value !== "string") {
addError(`metadata.${key} must be a string. (${skillId})`);
}
}
@@ -204,10 +242,14 @@ function run() {
}
if (data && Object.keys(data).length) {
const unknownFields = Object.keys(data).filter(key => !ALLOWED_FIELDS.has(key));
const unknownFields = Object.keys(data).filter(
(key) => !ALLOWED_FIELDS.has(key),
);
if (unknownFields.length) {
unknownFieldSkills.push(skillId);
addError(`Unknown frontmatter fields (${skillId}): ${unknownFields.join(', ')}`);
addError(
`Unknown frontmatter fields (${skillId}): ${unknownFields.join(", ")}`,
);
}
}
@@ -219,39 +261,61 @@ function run() {
missingUseSection.push(skillId);
}
if (!content.includes('## Do not use')) {
if (!content.includes("## Do not use")) {
missingDoNotUseSection.push(skillId);
}
if (!content.includes('## Instructions')) {
if (!content.includes("## Instructions")) {
missingInstructionsSection.push(skillId);
}
}
if (missingUseSection.length) {
addWarning(`Missing "Use this skill when" section: ${missingUseSection.length} skills (examples: ${missingUseSection.slice(0, 5).join(', ')})`);
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(', ')})`);
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(', ')})`);
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(', ')})`);
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(', ')})`);
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);
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 = {
@@ -266,14 +330,14 @@ function run() {
}
if (warnings.length) {
console.warn('Warnings:');
console.warn("Warnings:");
for (const warning of warnings) {
console.warn(`- ${warning}`);
}
}
if (errors.length) {
console.error('\nErrors:');
console.error("\nErrors:");
for (const error of errors) {
console.error(`- ${error}`);
}

View File

@@ -1,7 +1,7 @@
---
name: azure-ai-contentsafety-ts
description: Analyze text and images for harmful content using Azure AI Content Safety (@azure-rest/ai-content-safety). Use when moderating user-generated content, detecting hate speech, violence, sexual content, or self-harm, or managing custom blocklists.
package: @azure-rest/ai-content-safety
package: "@azure-rest/ai-content-safety"
---
# Azure AI Content Safety REST SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-ai-document-intelligence-ts
description: Extract text, tables, and structured data from documents using Azure Document Intelligence (@azure-rest/ai-document-intelligence). Use when processing invoices, receipts, IDs, forms, or building custom document models.
package: @azure-rest/ai-document-intelligence
package: "@azure-rest/ai-document-intelligence"
---
# Azure Document Intelligence REST SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-ai-projects-ts
description: Build AI applications using Azure AI Projects SDK for JavaScript (@azure/ai-projects). Use when working with Foundry project clients, agents, connections, deployments, datasets, indexes, evaluations, or getting OpenAI clients.
package: @azure/ai-projects
package: "@azure/ai-projects"
---
# Azure AI Projects SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-ai-translation-ts
description: Build translation applications using Azure Translation SDKs for JavaScript (@azure-rest/ai-translation-text, @azure-rest/ai-translation-document). Use when implementing text translation, transliteration, language detection, or batch document translation.
package: @azure-rest/ai-translation-text, @azure-rest/ai-translation-document
package: "@azure-rest/ai-translation-text, @azure-rest/ai-translation-document"
---
# Azure Translation SDKs for TypeScript

View File

@@ -2,7 +2,7 @@
name: azure-ai-voicelive-ts
description: |
Azure AI Voice Live SDK for JavaScript/TypeScript. Build real-time voice AI applications with bidirectional WebSocket communication. Use for voice assistants, conversational AI, real-time speech-to-speech, and voice-enabled chatbots in Node.js or browser environments. Triggers: "voice live", "real-time voice", "VoiceLiveClient", "VoiceLiveSession", "voice assistant TypeScript", "bidirectional audio", "speech-to-speech JavaScript".
package: @azure/ai-voicelive
package: "@azure/ai-voicelive"
---
# @azure/ai-voicelive (JavaScript/TypeScript)

View File

@@ -1,7 +1,7 @@
---
name: azure-appconfiguration-ts
description: Build applications using Azure App Configuration SDK for JavaScript (@azure/app-configuration). Use when working with configuration settings, feature flags, Key Vault references, dynamic refresh, or centralized configuration management.
package: @azure/app-configuration
package: "@azure/app-configuration"
---
# Azure App Configuration SDK for TypeScript

View File

@@ -2,7 +2,7 @@
name: azure-cosmos-ts
description: |
Azure Cosmos DB JavaScript/TypeScript SDK (@azure/cosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: "Cosmos DB", "@azure/cosmos", "CosmosClient", "document CRUD", "NoSQL queries", "bulk operations", "partition key", "container.items".
package: @azure/cosmos
package: "@azure/cosmos"
---
# @azure/cosmos (TypeScript/JavaScript)

View File

@@ -1,7 +1,7 @@
---
name: azure-eventhub-ts
description: Build event streaming applications using Azure Event Hubs SDK for JavaScript (@azure/event-hubs). Use when implementing high-throughput event ingestion, real-time analytics, IoT telemetry, or event-driven architectures with partitioned consumers.
package: @azure/event-hubs
package: "@azure/event-hubs"
---
# Azure Event Hubs SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-identity-ts
description: Authenticate to Azure services using Azure Identity SDK for JavaScript (@azure/identity). Use when configuring authentication with DefaultAzureCredential, managed identity, service principals, or interactive browser login.
package: @azure/identity
package: "@azure/identity"
---
# Azure Identity SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-keyvault-keys-ts
description: Manage cryptographic keys using Azure Key Vault Keys SDK for JavaScript (@azure/keyvault-keys). Use when creating, encrypting/decrypting, signing, or rotating keys.
package: @azure/keyvault-keys
package: "@azure/keyvault-keys"
---
# Azure Key Vault Keys SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-keyvault-secrets-ts
description: Manage secrets using Azure Key Vault Secrets SDK for JavaScript (@azure/keyvault-secrets). Use when storing and retrieving application secrets or configuration values.
package: @azure/keyvault-secrets
package: "@azure/keyvault-secrets"
---
# Azure Key Vault Secrets SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-monitor-opentelemetry-ts
description: Instrument applications with Azure Monitor and OpenTelemetry for JavaScript (@azure/monitor-opentelemetry). Use when adding distributed tracing, metrics, and logs to Node.js applications with Application Insights.
package: @azure/monitor-opentelemetry
package: "@azure/monitor-opentelemetry"
---
# Azure Monitor OpenTelemetry SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-search-documents-ts
description: Build search applications using Azure AI Search SDK for JavaScript (@azure/search-documents). Use when creating/managing indexes, implementing vector/hybrid search, semantic ranking, or building agentic retrieval with knowledge bases.
package: @azure/search-documents
package: "@azure/search-documents"
---
# Azure AI Search SDK for TypeScript

View File

@@ -1,7 +1,7 @@
---
name: azure-servicebus-ts
description: Build messaging applications using Azure Service Bus SDK for JavaScript (@azure/service-bus). Use when implementing queues, topics/subscriptions, message sessions, dead-letter handling, or enterprise messaging patterns.
package: @azure/service-bus
package: "@azure/service-bus"
---
# Azure Service Bus SDK for TypeScript

View File

@@ -2,7 +2,7 @@
name: azure-storage-blob-ts
description: |
Azure Blob Storage JavaScript/TypeScript SDK (@azure/storage-blob) for blob operations. Use for uploading, downloading, listing, and managing blobs and containers. Supports block blobs, append blobs, page blobs, SAS tokens, and streaming. Triggers: "blob storage", "@azure/storage-blob", "BlobServiceClient", "ContainerClient", "upload blob", "download blob", "SAS token", "block blob".
package: @azure/storage-blob
package: "@azure/storage-blob"
---
# @azure/storage-blob (TypeScript/JavaScript)

View File

@@ -2,7 +2,7 @@
name: azure-storage-file-share-ts
description: |
Azure File Share JavaScript/TypeScript SDK (@azure/storage-file-share) for SMB file share operations. Use for creating shares, managing directories, uploading/downloading files, and handling file metadata. Supports Azure Files SMB protocol scenarios. Triggers: "file share", "@azure/storage-file-share", "ShareServiceClient", "ShareClient", "SMB", "Azure Files".
package: @azure/storage-file-share
package: "@azure/storage-file-share"
---
# @azure/storage-file-share (TypeScript/JavaScript)

View File

@@ -2,7 +2,7 @@
name: azure-storage-queue-ts
description: |
Azure Queue Storage JavaScript/TypeScript SDK (@azure/storage-queue) for message queue operations. Use for sending, receiving, peeking, and deleting messages in queues. Supports visibility timeout, message encoding, and batch operations. Triggers: "queue storage", "@azure/storage-queue", "QueueServiceClient", "QueueClient", "send message", "receive message", "dequeue", "visibility timeout".
package: @azure/storage-queue
package: "@azure/storage-queue"
---
# @azure/storage-queue (TypeScript/JavaScript)

View File

@@ -1,7 +1,7 @@
---
name: azure-web-pubsub-ts
description: Build real-time messaging applications using Azure Web PubSub SDKs for JavaScript (@azure/web-pubsub, @azure/web-pubsub-client). Use when implementing WebSocket-based real-time features, pub/sub messaging, group chat, or live notifications.
package: @azure/web-pubsub, @azure/web-pubsub-client
package: "@azure/web-pubsub, @azure/web-pubsub-client"
---
# Azure Web PubSub SDKs for TypeScript

View File

@@ -0,0 +1,544 @@
---
name: go-rod-master
description: "Comprehensive guide for browser automation and web scraping with go-rod (Chrome DevTools Protocol) including stealth anti-bot-detection patterns."
risk: safe
source: https://github.com/go-rod/rod
---
# Go-Rod Browser Automation Master
## Overview
[Rod](https://github.com/go-rod/rod) is a high-level Go driver built directly on the [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) for browser automation and web scraping. Unlike wrappers around other tools, Rod communicates with the browser natively via CDP, providing thread-safe operations, chained context design for timeouts/cancellation, auto-wait for elements, correct iframe/shadow DOM handling, and zero zombie browser processes.
The companion library [go-rod/stealth](https://github.com/go-rod/stealth) injects anti-bot-detection evasions based on [puppeteer-extra stealth](https://github.com/nichochar/puppeteer-extra/tree/master/packages/extract-stealth-evasions), hiding headless browser fingerprints from detection systems.
## When to Use This Skill
- Use when the user asks to **scrape**, **automate**, or **test** a website using Go.
- Use when the user needs a **headless browser** for dynamic/SPA content (React, Vue, Angular).
- Use when the user mentions **stealth**, **anti-bot**, **avoiding detection**, **Cloudflare**, or **bot detection bypass**.
- Use when the user wants to work with the **Chrome DevTools Protocol (CDP)** directly from Go.
- Use when the user needs to **intercept** or **hijack** network requests in a browser context.
- Use when the user asks about **concurrent browser scraping** or **page pooling** in Go.
- Use when the user is migrating from **chromedp** or **Playwright Go** and wants a simpler API.
## Safety & Risk
**Risk Level: 🔵 Safe**
- **Read-Only by Default:** Default behavior is navigating and reading page content (scraping/testing).
- **Isolated Contexts:** Browser contexts are sandboxed; cookies and storage do not persist unless explicitly saved.
- **Resource Cleanup:** Designed around Go's `defer` pattern — browsers and pages close automatically.
- **No External Mutations:** Does not modify external state unless the script explicitly submits forms or POSTs data.
## Installation
```bash
# Core rod library
go get github.com/go-rod/rod@latest
# Stealth anti-detection plugin (ALWAYS include for production scraping)
go get github.com/go-rod/stealth@latest
```
Rod auto-downloads a compatible Chromium binary on first run. To pre-download:
```bash
go run github.com/nichochar/go-rod.github.io/cmd/launcher@latest
```
## Core Concepts
### Browser Lifecycle
Rod manages three layers: **Browser → Page → Element**.
```go
// Launch and connect to a browser
browser := rod.New().MustConnect()
defer browser.MustClose()
// Create a page (tab)
page := browser.MustPage("https://example.com")
// Find an element
el := page.MustElement("h1")
fmt.Println(el.MustText())
```
### Must vs Error Patterns
Rod provides two API styles for every operation:
| Style | Method | Use Case |
|:------|:-------|:---------|
| **Must** | `MustElement()`, `MustClick()`, `MustText()` | Scripting, debugging, prototyping. Panics on error. |
| **Error** | `Element()`, `Click()`, `Text()` | Production code. Returns `error` for explicit handling. |
**Production pattern:**
```go
el, err := page.Element("#login-btn")
if err != nil {
return fmt.Errorf("login button not found: %w", err)
}
if err := el.Click(proto.InputMouseButtonLeft, 1); err != nil {
return fmt.Errorf("click failed: %w", err)
}
```
**Scripting pattern with Try:**
```go
err := rod.Try(func() {
page.MustElement("#login-btn").MustClick()
})
if errors.Is(err, context.DeadlineExceeded) {
log.Println("timeout finding login button")
}
```
### Context & Timeout
Rod uses Go's `context.Context` for cancellation and timeouts. Context propagates recursively to all child operations.
```go
// Set a 5-second timeout for the entire operation chain
page.Timeout(5 * time.Second).
MustWaitLoad().
MustElement("title").
CancelTimeout(). // subsequent calls are not bound by the 5s timeout
Timeout(30 * time.Second).
MustText()
```
### Element Selectors
Rod supports multiple selector strategies:
```go
// CSS selector (most common)
page.MustElement("div.content > p.intro")
// CSS selector with text regex matching
page.MustElementR("button", "Submit|Send")
// XPath
page.MustElementX("//div[@class='content']//p")
// Search across iframes and shadow DOM (like DevTools Ctrl+F)
page.MustSearch(".deeply-nested-element")
```
### Auto-Wait
Rod automatically retries element queries until the element appears or the context times out. You do not need manual sleeps:
```go
// This will automatically wait until the element exists
el := page.MustElement("#dynamic-content")
// Wait until the element is stable (position/size not changing)
el.MustWaitStable().MustClick()
// Wait until page has no pending network requests
wait := page.MustWaitRequestIdle()
page.MustElement("#search").MustInput("query")
wait()
```
---
## Stealth & Anti-Bot Detection (go-rod/stealth)
> **IMPORTANT:** For any production scraping or automation against real websites, ALWAYS use `stealth.MustPage()` instead of `browser.MustPage()`. This is the single most important step for avoiding bot detection.
### How Stealth Works
The `go-rod/stealth` package injects JavaScript evasions into every new page that:
- **Remove `navigator.webdriver`** — the primary headless detection signal.
- **Spoof WebGL vendor/renderer** — presents real GPU info (e.g., "Intel Inc." / "Intel Iris OpenGL Engine") instead of headless markers like "Google SwiftShader".
- **Fix Chrome plugin array** — reports proper `PluginArray` type with realistic plugin count.
- **Patch permissions API** — returns `"prompt"` instead of bot-revealing values.
- **Set realistic languages** — reports `en-US,en` instead of empty arrays.
- **Fix broken image dimensions** — headless browsers report 0x0; stealth fixes this to 16x16.
### Usage
**Creating a stealth page (recommended for all production use):**
```go
import (
"github.com/go-rod/rod"
"github.com/go-rod/stealth"
)
browser := rod.New().MustConnect()
defer browser.MustClose()
// Use stealth.MustPage instead of browser.MustPage
page := stealth.MustPage(browser)
page.MustNavigate("https://bot.sannysoft.com")
```
**With error handling:**
```go
page, err := stealth.Page(browser)
if err != nil {
return fmt.Errorf("failed to create stealth page: %w", err)
}
page.MustNavigate("https://example.com")
```
**Using stealth.JS directly (advanced — for custom page creation):**
```go
// If you need to create the page yourself (e.g., with specific options),
// inject stealth.JS manually via EvalOnNewDocument
page := browser.MustPage()
page.MustEvalOnNewDocument(stealth.JS)
page.MustNavigate("https://example.com")
```
### Verifying Stealth
Navigate to a bot detection test page to verify evasions:
```go
page := stealth.MustPage(browser)
page.MustNavigate("https://bot.sannysoft.com")
page.MustScreenshot("stealth_test.png")
```
Expected results for a properly stealth-configured browser:
- **WebDriver**: `missing (passed)`
- **Chrome**: `present (passed)`
- **Plugins Length**: `3` (not `0`)
- **Languages**: `en-US,en`
---
## Implementation Guidelines
### 1. Launcher Configuration
Use the `launcher` package to customize browser launch flags:
```go
import "github.com/go-rod/rod/lib/launcher"
url := launcher.New().
Headless(true). // false for debugging
Proxy("127.0.0.1:8080"). // upstream proxy
Set("disable-gpu", ""). // custom Chrome flag
Delete("use-mock-keychain"). // remove a default flag
MustLaunch()
browser := rod.New().ControlURL(url).MustConnect()
defer browser.MustClose()
```
**Debugging mode (visible browser + slow motion):**
```go
l := launcher.New().
Headless(false).
Devtools(true)
defer l.Cleanup()
browser := rod.New().
ControlURL(l.MustLaunch()).
Trace(true).
SlowMotion(2 * time.Second).
MustConnect()
```
### 2. Proxy Support
```go
// Set proxy at launch
url := launcher.New().
Proxy("socks5://127.0.0.1:1080").
MustLaunch()
browser := rod.New().ControlURL(url).MustConnect()
// Handle proxy authentication
go browser.MustHandleAuth("username", "password")()
// Ignore SSL certificate errors (for MITM proxies)
browser.MustIgnoreCertErrors(true)
```
### 3. Input Simulation
```go
import "github.com/go-rod/rod/lib/input"
// Type into an input field (replaces existing value)
page.MustElement("#email").MustInput("user@example.com")
// Simulate keyboard keys
page.Keyboard.MustType(input.Enter)
// Press key combinations
page.Keyboard.MustPress(input.ControlLeft)
page.Keyboard.MustType(input.KeyA)
page.Keyboard.MustRelease(input.ControlLeft)
// Mouse click at coordinates
page.Mouse.MustClick(input.MouseLeft)
page.Mouse.MustMoveTo(100, 200)
```
### 4. Network Request Interception (Hijacking)
```go
router := browser.HijackRequests()
defer router.MustStop()
// Block all image requests
router.MustAdd("*.png", func(ctx *rod.Hijack) {
ctx.Response.Fail(proto.NetworkErrorReasonBlockedByClient)
})
// Modify request headers
router.MustAdd("*api.example.com*", func(ctx *rod.Hijack) {
ctx.Request.Req().Header.Set("Authorization", "Bearer token123")
ctx.MustLoadResponse()
})
// Modify response body
router.MustAdd("*.js", func(ctx *rod.Hijack) {
ctx.MustLoadResponse()
ctx.Response.SetBody(ctx.Response.Body() + "\n// injected")
})
go router.Run()
```
### 5. Waiting Strategies
```go
// Wait for page load event
page.MustWaitLoad()
// Wait for no pending network requests (AJAX idle)
wait := page.MustWaitRequestIdle()
page.MustElement("#search").MustInput("query")
wait()
// Wait for element to be stable (not animating)
page.MustElement(".modal").MustWaitStable().MustClick()
// Wait for element to become invisible
page.MustElement(".loading").MustWaitInvisible()
// Wait for JavaScript condition
page.MustWait(`() => document.title === 'Ready'`)
// Wait for specific navigation/event
wait := page.WaitEvent(&proto.PageLoadEventFired{})
page.MustNavigate("https://example.com")
wait()
```
### 6. Race Selectors (Multiple Outcomes)
Handle pages where the result can be one of several outcomes (e.g., login success vs error):
```go
page.MustElement("#username").MustInput("user")
page.MustElement("#password").MustInput("pass").MustType(input.Enter)
// Race between success and error selectors
elm := page.Race().
Element(".dashboard").MustHandle(func(e *rod.Element) {
fmt.Println("Login successful:", e.MustText())
}).
Element(".error-message").MustDo()
if elm.MustMatches(".error-message") {
log.Fatal("Login failed:", elm.MustText())
}
```
### 7. Screenshots & PDF
```go
// Full-page screenshot
page.MustScreenshot("page.png")
// Custom screenshot (JPEG, specific region)
img, _ := page.Screenshot(true, &proto.PageCaptureScreenshot{
Format: proto.PageCaptureScreenshotFormatJpeg,
Quality: gson.Int(90),
Clip: &proto.PageViewport{
X: 0, Y: 0, Width: 1280, Height: 800, Scale: 1,
},
})
utils.OutputFile("screenshot.jpg", img)
// Scroll screenshot (captures full scrollable page)
img, _ := page.MustWaitStable().ScrollScreenshot(nil)
utils.OutputFile("full_page.jpg", img)
// PDF export
page.MustPDF("output.pdf")
```
### 8. Concurrent Page Pool
```go
pool := rod.NewPagePool(5) // max 5 concurrent pages
create := func() *rod.Page {
return browser.MustIncognito().MustPage()
}
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
page := pool.MustGet(create)
defer pool.Put(page)
page.MustNavigate(u).MustWaitLoad()
fmt.Println(page.MustInfo().Title)
}(url)
}
wg.Wait()
pool.Cleanup(func(p *rod.Page) { p.MustClose() })
```
### 9. Event Handling
```go
// Listen for console.log output
go page.EachEvent(func(e *proto.RuntimeConsoleAPICalled) {
if e.Type == proto.RuntimeConsoleAPICalledTypeLog {
fmt.Println(page.MustObjectsToJSON(e.Args))
}
})()
// Wait for a specific event before proceeding
wait := page.WaitEvent(&proto.PageLoadEventFired{})
page.MustNavigate("https://example.com")
wait()
```
### 10. File Download
```go
wait := browser.MustWaitDownload()
page.MustElementR("a", "Download PDF").MustClick()
data := wait()
utils.OutputFile("downloaded.pdf", data)
```
### 11. JavaScript Evaluation
```go
// Execute JS on the page
page.MustEval(`() => console.log("hello")`)
// Pass parameters and get return value
result := page.MustEval(`(a, b) => a + b`, 1, 2)
fmt.Println(result.Int()) // 3
// Eval on a specific element ("this" = the DOM element)
title := page.MustElement("title").MustEval(`() => this.innerText`).String()
// Direct CDP calls for features Rod doesn't wrap
proto.PageSetAdBlockingEnabled{Enabled: true}.Call(page)
```
### 12. Loading Chrome Extensions
```go
extPath, _ := filepath.Abs("./my-extension")
u := launcher.New().
Set("load-extension", extPath).
Headless(false). // extensions require headed mode
MustLaunch()
browser := rod.New().ControlURL(u).MustConnect()
```
---
## Examples
See the `examples/` directory for complete, runnable Go files:
- `examples/basic_scrape.go` — Minimal scraping example
- `examples/stealth_page.go` — Anti-detection with go-rod/stealth
- `examples/request_hijacking.go` — Intercepting and modifying network requests
- `examples/concurrent_pages.go` — Page pool for concurrent scraping
---
## Best Practices
-**ALWAYS use `stealth.MustPage(browser)`** instead of `browser.MustPage()` for real-world sites.
-**ALWAYS `defer browser.MustClose()`** immediately after connecting.
- ✅ Use the error-returning API (not `Must*`) in production code.
- ✅ Set explicit timeouts with `.Timeout()` — never rely on defaults for production.
- ✅ Use `browser.MustIncognito().MustPage()` for isolated sessions.
- ✅ Use `PagePool` for concurrent scraping instead of spawning unlimited pages.
- ✅ Use `MustWaitStable()` before clicking elements that might be animating.
- ✅ Use `MustWaitRequestIdle()` after actions that trigger AJAX calls.
- ✅ Use `launcher.New().Headless(false).Devtools(true)` for debugging.
-**NEVER** use `time.Sleep()` for waiting — use Rod's built-in wait methods.
-**NEVER** create a new `Browser` per task — create one Browser, use multiple `Page` instances.
-**NEVER** use `browser.MustPage()` for production scraping — use `stealth.MustPage()`.
-**NEVER** ignore errors in production — always handle them explicitly.
-**NEVER** forget to defer-close browsers, pages, and hijack routers.
## Common Pitfalls
- **Problem:** Element not found even though it exists on the page.
**Solution:** The element may be inside an iframe or shadow DOM. Use `page.MustSearch()` instead of `page.MustElement()` — it searches across all iframes and shadow DOMs.
- **Problem:** Click doesn't work because the element is animating.
**Solution:** Call `el.MustWaitStable()` before `el.MustClick()`.
- **Problem:** Bot detection despite using stealth.
**Solution:** Combine `stealth.MustPage()` with: randomized viewport sizes, realistic User-Agent strings, human-like input delays between keystrokes, and random idle behaviors (scroll, hover).
- **Problem:** Browser process leaks (zombie processes).
**Solution:** Always `defer browser.MustClose()`. Rod uses [leakless](https://github.com/ysmood/leakless) to kill zombies after main process crash, but explicit cleanup is preferred.
- **Problem:** Timeout errors on slow pages.
**Solution:** Use chained context: `page.Timeout(30 * time.Second).MustWaitLoad()`. For AJAX-heavy pages, use `MustWaitRequestIdle()` instead of `MustWaitLoad()`.
- **Problem:** HijackRequests router not intercepting requests.
**Solution:** You must call `go router.Run()` after setting up routes, and `defer router.MustStop()` for cleanup.
## Limitations
- **CAPTCHAs:** Rod does not include CAPTCHA solving. External services (2captcha, etc.) must be integrated separately.
- **Extreme Anti-Bot:** While `go-rod/stealth` handles common detection (WebDriver, plugin fingerprints, WebGL), extremely strict systems (some Cloudflare configurations, Akamai Bot Manager) may still detect automation. Additional measures (residential proxies, human-like behavioral patterns) may be needed.
- **DRM Content:** Cannot interact with DRM-protected media (e.g., Widevine).
- **Resource Usage:** Each browser instance consumes significant RAM (~100-300MB+). Use `PagePool` and limit concurrency on memory-constrained systems.
- **Extensions in Headless:** Chrome extensions do not work in headless mode. Use `Headless(false)` with XVFB for server environments.
- **Platform:** Requires a Chromium-compatible browser. Does not support Firefox or Safari.
## Documentation References
- [Official Documentation](https://go-rod.github.io/) — Guides, tutorials, FAQ
- [Go API Reference](https://pkg.go.dev/github.com/go-rod/rod) — Complete type and method documentation
- [go-rod/stealth](https://github.com/go-rod/stealth) — Anti-bot detection plugin
- [Examples (source)](https://github.com/go-rod/rod/blob/main/examples_test.go) — Official example tests
- [Rod vs Chromedp Comparison](https://github.com/nichochar/go-rod.github.io/blob/main/lib/examples/compare-chromedp) — Migration reference
- [Chrome DevTools Protocol Docs](https://chromedevtools.github.io/devtools-protocol/) — Underlying protocol reference
- [Chrome CLI Flags Reference](https://peter.sh/experiments/chromium-command-line-switches) — Launcher flag documentation
- `references/api-reference.md` — Quick-reference cheat sheet

View File

@@ -0,0 +1,41 @@
package main
import (
"fmt"
"time"
"github.com/go-rod/rod"
"github.com/go-rod/rod/lib/input"
)
// basic_scrape demonstrates a minimal go-rod scraping workflow:
// Launch browser → navigate → extract text → close.
func main() {
// Launch and connect to a new browser instance.
// Rod auto-downloads Chromium if not present.
browser := rod.New().
Timeout(time.Minute). // global timeout for the browser
MustConnect()
defer browser.MustClose()
// Navigate to the target page and wait for it to stabilize
page := browser.MustPage("https://github.com").MustWaitStable()
// Extract the page title via JavaScript evaluation
title := page.MustElement("title").MustEval(`() => this.innerText`).String()
fmt.Println("Page title:", title)
// Use CSS selector to find elements
links := page.MustElements("a[href]")
fmt.Printf("Found %d links on the page\n", len(links))
// Use keyboard shortcut to trigger search
page.Keyboard.MustType(input.Slash)
// Type into the search input and press Enter
page.MustElement("#query-builder-test").MustInput("go-rod").MustType(input.Enter)
// Wait for results — MustElementR matches by CSS selector + text regex
result := page.MustElementR("span", "DevTools Protocol").MustText()
fmt.Println("Found result:", result)
}

View File

@@ -0,0 +1,81 @@
package main
import (
"fmt"
"sync"
"time"
"github.com/go-rod/rod"
"github.com/go-rod/stealth"
)
// concurrent_pages demonstrates using rod.PagePool for concurrent scraping
// with stealth-enabled pages.
func main() {
browser := rod.New().
Timeout(2 * time.Minute).
MustConnect()
defer browser.MustClose()
// URLs to scrape concurrently
urls := []string{
"https://example.com",
"https://example.org",
"https://www.iana.org/domains/reserved",
"https://www.iana.org/about",
}
// Create a page pool with max 3 concurrent pages
pool := rod.NewPagePool(3)
// Factory function: creates stealth-enabled pages in isolated incognito contexts
create := func() *rod.Page {
// MustIncognito creates an isolated browser context (separate cookies, storage)
page := stealth.MustPage(browser.MustIncognito())
return page
}
// Collect results safely using a mutex
var mu sync.Mutex
results := make(map[string]string)
// Scrape all URLs concurrently
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
// Get a page from the pool (blocks if pool is full)
page := pool.MustGet(create)
defer pool.Put(page) // return page to pool when done
// Navigate and wait for the page to stabilize
page.MustNavigate(u).MustWaitStable()
// Extract the page title
title := page.MustInfo().Title
// Store result
mu.Lock()
results[u] = title
mu.Unlock()
fmt.Printf("[done] %s → %s\n", u, title)
}(url)
}
// Wait for all goroutines to complete
wg.Wait()
// Clean up the pool
pool.Cleanup(func(p *rod.Page) {
p.MustClose()
})
// Print summary
fmt.Printf("\n--- Results (%d pages scraped) ---\n", len(results))
for url, title := range results {
fmt.Printf(" %s: %s\n", url, title)
}
}

View File

@@ -0,0 +1,85 @@
package main
import (
"fmt"
"net/http"
"time"
"github.com/go-rod/rod"
"github.com/go-rod/rod/lib/proto"
"github.com/go-rod/stealth"
)
// request_hijacking demonstrates intercepting and modifying network requests
// using Rod's HijackRequests API.
func main() {
browser := rod.New().
Timeout(time.Minute).
MustConnect()
defer browser.MustClose()
// --- Example 1: Block image requests to save bandwidth ---
router := browser.HijackRequests()
defer router.MustStop()
// Block all PNG and JPEG image requests
router.MustAdd("*.png", func(ctx *rod.Hijack) {
ctx.Response.Fail(proto.NetworkErrorReasonBlockedByClient)
})
router.MustAdd("*.jpg", func(ctx *rod.Hijack) {
ctx.Response.Fail(proto.NetworkErrorReasonBlockedByClient)
})
// Modify request headers for API calls
router.MustAdd("*api.*", func(ctx *rod.Hijack) {
ctx.Request.Req().Header.Set("X-Custom-Header", "go-rod")
ctx.Request.Req().Header.Set("Authorization", "Bearer my-token")
// Load the actual response from the server
if err := ctx.LoadResponse(http.DefaultClient, true); err != nil {
fmt.Printf("Failed to load response: %v\n", err)
return
}
fmt.Printf("API response status: %d\n", ctx.Response.Payload().ResponseCode)
})
// Inject JavaScript into every JS file loaded
router.MustAdd("*.js", func(ctx *rod.Hijack) {
if err := ctx.LoadResponse(http.DefaultClient, true); err != nil {
return
}
// Append tracking code to all JavaScript files
body := ctx.Response.Body()
ctx.Response.SetBody(body + "\n// Monitored by go-rod")
})
// IMPORTANT: Start the router in a goroutine
go router.Run()
// Use stealth page for anti-detection
page := stealth.MustPage(browser)
page.MustNavigate("https://example.com").MustWaitLoad()
fmt.Println("Page loaded with request hijacking active")
fmt.Println("Title:", page.MustElement("title").MustText())
// --- Example 2: Capture and log all network requests ---
// (Using a separate page to show different patterns)
page2 := stealth.MustPage(browser)
// Enable network domain for request logging
proto.NetworkEnable{}.Call(page2)
// Listen for network responses
go page2.EachEvent(func(e *proto.NetworkResponseReceived) {
fmt.Printf(" [%d] %s %s\n",
e.Response.Status,
e.Type.String(),
e.Response.URL,
)
})()
page2.MustNavigate("https://example.com").MustWaitLoad()
fmt.Println("\nNetwork log above shows all requests captured")
}

View File

@@ -0,0 +1,91 @@
package main
import (
"fmt"
"strings"
"time"
"github.com/go-rod/rod"
"github.com/go-rod/rod/lib/launcher"
"github.com/go-rod/rod/lib/utils"
"github.com/go-rod/stealth"
)
// stealth_page demonstrates using go-rod/stealth to bypass bot detection.
// It creates a stealth-enabled page and verifies evasions against a detection site.
func main() {
// Ensure the browser binary is downloaded
launcher.NewBrowser().MustGet()
// Launch browser with custom launcher settings
url := launcher.New().
Headless(true).
MustLaunch()
browser := rod.New().
ControlURL(url).
Timeout(time.Minute).
MustConnect()
defer browser.MustClose()
// CRITICAL: Use stealth.MustPage instead of browser.MustPage
// This injects anti-detection JavaScript into every new document
page := stealth.MustPage(browser)
// Navigate to a bot detection test page
page.MustNavigate("https://bot.sannysoft.com")
// Wait for the detection tests to complete
page.MustElement("#broken-image-dimensions.passed")
// Take a screenshot to verify results
page.MustScreenshot("stealth_result.png")
fmt.Println("Screenshot saved to stealth_result.png")
// Print detection results
printBotDetectionReport(page)
// ---- Advanced: Using stealth.JS directly ----
// If you need to create the page manually (e.g., with specific context),
// you can inject stealth.JS via EvalOnNewDocument:
advancedPage := browser.MustPage()
advancedPage.MustEvalOnNewDocument(stealth.JS)
advancedPage.MustNavigate("https://bot.sannysoft.com")
advancedPage.MustElement("#broken-image-dimensions.passed")
fmt.Println("\nAdvanced stealth page also passed detection tests")
// ---- Production: Error handling pattern ----
prodPage, err := stealth.Page(browser)
if err != nil {
fmt.Printf("Failed to create stealth page: %v\n", err)
return
}
prodPage.MustNavigate("https://example.com")
title, err := prodPage.MustElement("title").Text()
if err != nil {
fmt.Printf("Failed to get title: %v\n", err)
return
}
fmt.Printf("\nProduction page title: %s\n", title)
}
// printBotDetectionReport extracts and prints the detection test results.
func printBotDetectionReport(page *rod.Page) {
el := page.MustElement("#broken-image-dimensions.passed")
for _, row := range el.MustParents("table").First().MustElements("tr:nth-child(n+2)") {
cells := row.MustElements("td")
key := cells[0].MustProperty("textContent")
if strings.HasPrefix(key.String(), "User Agent") {
ua := cells[1].MustProperty("textContent").String()
passed := !strings.Contains(ua, "HeadlessChrome/")
fmt.Printf(" %s: %t\n", key, passed)
} else if strings.HasPrefix(key.String(), "Hairline Feature") {
continue // machine-dependent, skip
} else {
fmt.Printf(" %s: %s\n", key, cells[1].MustProperty("textContent"))
}
}
_ = utils.OutputFile("stealth_result.png", []byte{})
}

View File

@@ -0,0 +1,148 @@
# Go-Rod API Quick Reference
Cheat sheet for the most-used `go-rod/rod` and `go-rod/stealth` APIs.
Every `Must*` method has a corresponding error-returning version (without the `Must` prefix).
---
## Browser (`rod.Browser`)
| Method | Description |
|:-------|:------------|
| `rod.New().MustConnect()` | Launch new browser and connect |
| `rod.New().ControlURL(url).MustConnect()` | Connect to existing browser via WebSocket URL |
| `browser.MustClose()` | Close browser and all pages |
| `browser.MustPage(url)` | Create new page (tab) and navigate |
| `browser.MustPage()` | Create blank page |
| `browser.MustIncognito()` | Create isolated incognito context |
| `browser.MustIgnoreCertErrors(true)` | Ignore SSL certificate errors |
| `browser.MustHandleAuth(user, pass)` | Handle HTTP basic/proxy auth |
| `browser.HijackRequests()` | Create request interceptor router |
| `browser.MustWaitDownload()` | Wait for a file download to complete |
| `browser.ServeMonitor("")` | Start visual monitoring server |
| `browser.Trace(true)` | Enable verbose tracing |
| `browser.SlowMotion(duration)` | Add delay between actions |
| `rod.NewPagePool(n)` | Create pool of max `n` reusable pages |
| `rod.NewBrowserPool(n)` | Create pool of max `n` reusable browsers |
## Page (`rod.Page`)
| Method | Description |
|:-------|:------------|
| `page.MustNavigate(url)` | Navigate to URL |
| `page.MustWaitLoad()` | Wait for `load` event |
| `page.MustWaitStable()` | Wait until page DOM is stable |
| `page.MustWaitRequestIdle()` | Wait until no pending network requests |
| `page.MustWaitIdle()` | Wait for both load and request idle |
| `page.MustWait(js)` | Wait for JS expression to return truthy |
| `page.MustElement(selector)` | Find element by CSS selector (auto-wait) |
| `page.MustElementR(selector, regex)` | Find element by CSS + text regex |
| `page.MustElementX(xpath)` | Find element by XPath |
| `page.MustElements(selector)` | Find all matching elements |
| `page.MustSearch(query)` | Search across iframes + shadow DOM |
| `page.MustEval(js, args...)` | Execute JavaScript on page |
| `page.MustEvalOnNewDocument(js)` | Inject JS before any page script runs |
| `page.MustScreenshot(path)` | Take PNG screenshot |
| `page.MustPDF(path)` | Export page as PDF |
| `page.ScrollScreenshot(opts)` | Full-page scroll screenshot |
| `page.MustInfo()` | Get page info (title, URL) |
| `page.Timeout(duration)` | Set timeout for chained operations |
| `page.CancelTimeout()` | Remove timeout for subsequent operations |
| `page.Race()` | Start race selector (multiple outcomes) |
| `page.Keyboard` | Access keyboard controller |
| `page.Mouse` | Access mouse controller |
| `page.WaitEvent(proto)` | Wait for specific CDP event |
| `page.EachEvent(handler)` | Subscribe to events continuously |
| `page.Event()` | Channel-based event stream |
## Element (`rod.Element`)
| Method | Description |
|:-------|:------------|
| `el.MustClick()` | Click the element |
| `el.MustInput(text)` | Clear and type text into input |
| `el.MustType(keys...)` | Simulate key presses |
| `el.MustText()` | Get text content |
| `el.MustHTML()` | Get outer HTML |
| `el.MustProperty(name)` | Get JS property value |
| `el.MustAttribute(name)` | Get HTML attribute value |
| `el.MustWaitStable()` | Wait until position/size stable |
| `el.MustWaitVisible()` | Wait until element is visible |
| `el.MustWaitInvisible()` | Wait until element is hidden |
| `el.MustParents(selector)` | Find parent elements matching selector |
| `el.MustElements(selector)` | Find child elements |
| `el.MustMatches(selector)` | Check if element matches selector |
| `el.MustEval(js)` | Eval JS with `this` = element |
| `el.MustScreenshot(path)` | Screenshot just this element |
## Input (`rod/lib/input`)
| Constant | Description |
|:---------|:------------|
| `input.Enter` | Enter key |
| `input.Escape` | Escape key |
| `input.Tab` | Tab key |
| `input.Slash` | `/` key |
| `input.ControlLeft` | Left Ctrl |
| `input.ShiftLeft` | Left Shift |
| `input.KeyA``input.KeyZ` | Letter keys |
| `input.MouseLeft` | Left mouse button |
## Launcher (`rod/lib/launcher`)
| Method | Description |
|:-------|:------------|
| `launcher.New()` | Create new launcher |
| `l.Headless(bool)` | Enable/disable headless mode |
| `l.Devtools(bool)` | Auto-open DevTools |
| `l.Proxy(addr)` | Set proxy server |
| `l.Set(flag, value)` | Set Chrome CLI flag |
| `l.Delete(flag)` | Remove Chrome CLI flag |
| `l.MustLaunch()` | Launch browser, return control URL |
| `l.Cleanup()` | Kill browser process |
| `launcher.NewBrowser().MustGet()` | Download browser binary |
| `launcher.Open(url)` | Open URL in system browser |
## Stealth (`go-rod/stealth`)
| API | Description |
|:----|:------------|
| `stealth.MustPage(browser)` | Create stealth page (panics on error) |
| `stealth.Page(browser)` | Create stealth page (returns error) |
| `stealth.JS` | Raw JS string with all stealth evasions |
**What stealth.JS injects:**
- Removes `navigator.webdriver` detection
- Spoofs WebGL vendor/renderer to real GPU values
- Fixes Chrome plugin array (`PluginArray` type, count=3)
- Patches permissions API (returns `"prompt"`)
- Sets realistic languages (`en-US,en`)
- Fixes broken image dimensions (16x16 instead of 0x0)
## Network Hijacking (`rod.Hijack`)
| Method | Description |
|:-------|:------------|
| `router.MustAdd(pattern, handler)` | Add URL pattern handler |
| `router.Run()` | Start intercepting (call with `go`) |
| `router.MustStop()` | Stop intercepting |
| `ctx.Request.Req()` | Access `*http.Request` |
| `ctx.Request.URL()` | Get request URL |
| `ctx.LoadResponse(client, true)` | Load response from server |
| `ctx.MustLoadResponse()` | Load response (panics on error) |
| `ctx.Response.Body()` | Get response body |
| `ctx.Response.SetBody(s)` | Modify response body |
| `ctx.Response.Fail(reason)` | Block the request |
| `ctx.Response.Payload()` | Get response metadata |
## Direct CDP (`rod/lib/proto`)
```go
// Call any CDP method directly
proto.PageSetAdBlockingEnabled{Enabled: true}.Call(page)
// Or via generic JSON API
page.Call(ctx, "", "Page.setAdBlockingEnabled", map[string]bool{"enabled": true})
```
Full CDP protocol reference: https://chromedevtools.github.io/devtools-protocol/

View File

@@ -0,0 +1,185 @@
---
name: laravel-expert
description: Senior Laravel Engineer role for production-grade, maintainable, and idiomatic Laravel solutions. Focuses on clean architecture, security, performance, and modern standards (Laravel 10/11+).
risk: safe
source: community
---
# Laravel Expert
## Skill Metadata
Name: laravel-expert
Focus: General Laravel Development
Scope: Laravel Framework (10/11+)
---
## Role
You are a Senior Laravel Engineer.
You provide production-grade, maintainable, and idiomatic Laravel solutions.
You prioritize:
- Clean architecture
- Readability
- Testability
- Security best practices
- Performance awareness
- Convention over configuration
You follow modern Laravel standards and avoid legacy patterns unless explicitly required.
---
## Use This Skill When
- Building new Laravel features
- Refactoring legacy Laravel code
- Designing APIs
- Creating validation logic
- Implementing authentication/authorization
- Structuring services and business logic
- Optimizing database interactions
- Reviewing Laravel code quality
---
## Do NOT Use When
- The project is not Laravel-based
- The task is framework-agnostic PHP only
- The user requests non-PHP solutions
- The task is unrelated to backend engineering
---
## Engineering Principles
### Architecture
- Keep controllers thin
- Move business logic into Services
- Use FormRequest for validation
- Use API Resources for API responses
- Use Policies/Gates for authorization
- Apply Dependency Injection
- Avoid static abuse and global state
### Routing
- Use route model binding
- Group routes logically
- Apply middleware properly
- Separate web and api routes
### Validation
- Always validate input
- Never use request()->all() blindly
- Prefer FormRequest classes
- Return structured validation errors for APIs
### Eloquent & Database
- Use guarded/fillable correctly
- Avoid N+1 (use eager loading)
- Prefer query scopes for reusable filters
- Avoid raw queries unless necessary
- Use transactions for critical operations
### API Development
- Use API Resources
- Standardize JSON structure
- Use proper HTTP status codes
- Implement pagination
- Apply rate limiting
### Authentication
- Use Laravels native auth system
- Prefer Sanctum for SPA/API
- Implement password hashing securely
- Never expose sensitive data in responses
### Queues & Jobs
- Offload heavy operations to queues
- Use dispatchable jobs
- Ensure idempotency where needed
### Caching
- Cache expensive queries
- Use cache tags if supported
- Invalidate cache properly
### Blade & Views
- Escape user input
- Avoid business logic in views
- Use components for reuse
---
## Anti-Patterns to Avoid
- Fat controllers
- Business logic in routes
- Massive service classes
- Direct model manipulation without validation
- Blind mass assignment
- Hardcoded configuration values
- Duplicated logic across controllers
---
## Response Standards
When generating code:
- Provide complete, production-ready examples
- Include namespace declarations
- Use strict typing when possible
- Follow PSR standards
- Use proper return types
- Add minimal but meaningful comments
- Do not over-engineer
When reviewing code:
- Identify structural problems
- Suggest Laravel-native improvements
- Explain tradeoffs clearly
- Provide refactored example if necessary
---
## Output Structure
When designing a feature:
1. Architecture Overview
2. File Structure
3. Code Implementation
4. Explanation
5. Possible Improvements
When refactoring:
1. Identified Issues
2. Refactored Version
3. Why Its Better
---
## Behavioral Constraints
- Prefer Laravel-native solutions over third-party packages
- Avoid unnecessary abstractions
- Do not introduce microservice architecture unless requested
- Do not assume cloud infrastructure
- Keep solutions pragmatic and realistic

View File

@@ -0,0 +1,223 @@
---
name: laravel-security-audit
description: Security auditor for Laravel applications. Analyzes code for vulnerabilities, misconfigurations, and insecure practices using OWASP standards and Laravel security best practices.
risk: safe
source: community
---
# Laravel Security Audit
## Skill Metadata
Name: laravel-security-audit
Focus: Security Review & Vulnerability Detection
Scope: Laravel 10/11+ Applications
---
## Role
You are a Laravel Security Auditor.
You analyze Laravel applications for security vulnerabilities,
misconfigurations, and insecure coding practices.
You think like an attacker but respond like a security engineer.
You prioritize:
- Data protection
- Input validation integrity
- Authorization correctness
- Secure configuration
- OWASP awareness
- Real-world exploit scenarios
You do NOT overreact or label everything as critical.
You classify risk levels appropriately.
---
## Use This Skill When
- Reviewing Laravel code for vulnerabilities
- Auditing authentication/authorization flows
- Checking API security
- Reviewing file upload logic
- Validating request handling
- Checking rate limiting
- Reviewing .env exposure risks
- Evaluating deployment security posture
---
## Do NOT Use When
- The project is not Laravel-based
- The user wants feature implementation only
- The question is purely architectural (non-security)
- The request is unrelated to backend security
---
## Threat Model Awareness
Always consider:
- Unauthenticated attacker
- Authenticated low-privilege user
- Privilege escalation attempts
- Mass assignment exploitation
- IDOR (Insecure Direct Object Reference)
- CSRF & XSS vectors
- SQL injection
- File upload abuse
- API abuse & rate bypass
- Session hijacking
- Misconfigured middleware
- Exposed debug information
---
## Core Audit Areas
### 1⃣ Input Validation
- Is all user input validated?
- Is FormRequest used?
- Is request()->all() used dangerously?
- Are validation rules sufficient?
- Are arrays properly validated?
- Are nested inputs sanitized?
---
### 2⃣ Authorization
- Are Policies or Gates used?
- Is authorization checked in controllers?
- Is there IDOR risk?
- Can users access other users resources?
- Are admin routes properly protected?
- Are middleware applied consistently?
---
### 3⃣ Authentication
- Is password hashing secure?
- Is sensitive data exposed in API responses?
- Is Sanctum/JWT configured securely?
- Are tokens stored safely?
- Is logout properly invalidating tokens?
---
### 4⃣ Database Security
- Is mass assignment protected?
- Are $fillable / $guarded properly configured?
- Are raw queries used unsafely?
- Is user input directly used in queries?
- Are transactions used for critical operations?
---
### 5⃣ File Upload Handling
- MIME type validation?
- File extension validation?
- Storage path safe?
- Public disk misuse?
- Executable upload risk?
- Size limits enforced?
---
### 6⃣ API Security
- Rate limiting enabled?
- Throttling per user?
- Proper HTTP codes?
- Sensitive fields hidden?
- Pagination limits enforced?
---
### 7⃣ XSS & Output Escaping
- Blade uses {{ }} instead of {!! !!}?
- API responses sanitized?
- User-generated HTML filtered?
---
### 8⃣ Configuration & Deployment
- APP_DEBUG disabled in production?
- .env accessible via web?
- Storage symlink safe?
- CORS configuration safe?
- Trusted proxies configured?
- HTTPS enforced?
---
## Risk Classification Model
Each issue must be labeled as:
- Critical
- High
- Medium
- Low
- Informational
Do not exaggerate severity.
---
## Response Structure
When auditing code:
1. Summary
2. Identified Vulnerabilities
3. Risk Level (per issue)
4. Exploit Scenario (if applicable)
5. Recommended Fix
6. Secure Refactored Example (if needed)
---
## Behavioral Constraints
- Do not invent vulnerabilities
- Do not assume production unless specified
- Do not recommend heavy external security packages unnecessarily
- Prefer Laravel-native mitigation
- Be realistic and precise
- Do not shame the code author
---
## Example Audit Output Format
Issue: Missing Authorization Check
Risk: High
Problem:
The controller fetches a model by ID without verifying ownership.
Exploit:
An authenticated user can access another user's resource by changing the ID.
Fix:
Use policy check or scoped query.
Refactored Example:
```php
$post = Post::where('user_id', auth()->id())
->findOrFail($id);
```

View File

@@ -2,7 +2,7 @@
name: m365-agents-ts
description: |
Microsoft 365 Agents SDK for TypeScript/Node.js. Build multichannel agents for Teams/M365/Copilot Studio with AgentApplication routing, Express hosting, streaming responses, and Copilot Studio client integration. Triggers: "Microsoft 365 Agents SDK", "@microsoft/agents-hosting", "AgentApplication", "startServer", "streamingResponse", "Copilot Studio client", "@microsoft/agents-copilotstudio-client".
package: @microsoft/agents-hosting, @microsoft/agents-hosting-express, @microsoft/agents-activity, @microsoft/agents-copilotstudio-client
package: "@microsoft/agents-hosting, @microsoft/agents-hosting-express, @microsoft/agents-activity, @microsoft/agents-copilotstudio-client"
---
# Microsoft 365 Agents SDK (TypeScript)

View File

@@ -0,0 +1,613 @@
---
name: react-flow-architect
description: "Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements."
---
# ReactFlow Architect
Build production-ready ReactFlow applications with hierarchical navigation, performance optimization, and advanced state management.
## Quick Start
Create basic interactive graph:
```tsx
import ReactFlow, { Node, Edge } from "reactflow";
const nodes: Node[] = [
{ id: "1", position: { x: 0, y: 0 }, data: { label: "Node 1" } },
{ id: "2", position: { x: 100, y: 100 }, data: { label: "Node 2" } },
];
const edges: Edge[] = [{ id: "e1-2", source: "1", target: "2" }];
export default function Graph() {
return <ReactFlow nodes={nodes} edges={edges} />;
}
```
## Core Patterns
### Hierarchical Tree Navigation
Build expandable/collapsible tree structures with parent-child relationships.
#### Node Schema
```typescript
interface TreeNode extends Node {
data: {
label: string;
level: number;
hasChildren: boolean;
isExpanded: boolean;
childCount: number;
category: "root" | "category" | "process" | "detail";
};
}
```
#### Incremental Node Building
```typescript
const buildVisibleNodes = useCallback(
(allNodes: TreeNode[], expandedIds: Set<string>, otherDeps: any[]) => {
const visibleNodes = new Map<string, TreeNode>();
const visibleEdges = new Map<string, TreeEdge>();
// Start with root nodes
const rootNodes = allNodes.filter((n) => n.data.level === 0);
// Recursively add visible nodes
const addVisibleChildren = (node: TreeNode) => {
visibleNodes.set(node.id, node);
if (expandedIds.has(node.id)) {
const children = allNodes.filter((n) => n.parentNode === node.id);
children.forEach((child) => addVisibleChildren(child));
}
};
rootNodes.forEach((root) => addVisibleChildren(root));
return {
nodes: Array.from(visibleNodes.values()),
edges: Array.from(visibleEdges.values()),
};
},
[],
);
```
### Performance Optimization
Handle large datasets with incremental rendering and memoization.
#### Incremental Rendering
```typescript
const useIncrementalGraph = (
allNodes: Node[],
allEdges: Edge[],
expandedList: string[],
) => {
const prevExpandedListRef = useRef<Set<string>>(new Set());
const prevOtherDepsRef = useRef<any[]>([]);
const { visibleNodes, visibleEdges } = useMemo(() => {
const currentExpandedSet = new Set(expandedList);
const prevExpandedSet = prevExpandedListRef.current;
// Check if expanded list changed
const expandedChanged = !areSetsEqual(currentExpandedSet, prevExpandedSet);
// Check if other dependencies changed
const otherDepsChanged = !arraysEqual(otherDeps, prevOtherDepsRef.current);
if (expandedChanged && !otherDepsChanged) {
// Only expanded list changed - incremental update
return buildIncrementalUpdate(
cachedVisibleNodesRef.current,
cachedVisibleEdgesRef.current,
allNodes,
allEdges,
currentExpandedSet,
prevExpandedSet,
);
} else {
// Full rebuild needed
return buildFullGraph(allNodes, allEdges, currentExpandedSet);
}
}, [allNodes, allEdges, expandedList, ...otherDeps]);
return { visibleNodes, visibleEdges };
};
```
#### Memoization Patterns
```typescript
// Memoize node components to prevent unnecessary re-renders
const ProcessNode = memo(({ data, selected }: NodeProps) => {
return (
<div className={`process-node ${selected ? 'selected' : ''}`}>
{data.label}
</div>
);
}, (prevProps, nextProps) => {
// Custom comparison function
return (
prevProps.data.label === nextProps.data.label &&
prevProps.selected === nextProps.selected &&
prevProps.data.isExpanded === nextProps.data.isExpanded
);
});
// Memoize edge calculations
const styledEdges = useMemo(() => {
return edges.map(edge => ({
...edge,
style: {
...edge.style,
strokeWidth: selectedEdgeId === edge.id ? 3 : 2,
stroke: selectedEdgeId === edge.id ? '#3b82f6' : '#94a3b8',
},
animated: selectedEdgeId === edge.id,
}));
}, [edges, selectedEdgeId]);
```
### State Management
Complex node/edge state patterns with undo/redo and persistence.
#### Reducer Pattern
```typescript
type GraphAction =
| { type: "SELECT_NODE"; payload: string }
| { type: "SELECT_EDGE"; payload: string }
| { type: "TOGGLE_EXPAND"; payload: string }
| { type: "UPDATE_NODES"; payload: Node[] }
| { type: "UPDATE_EDGES"; payload: Edge[] }
| { type: "UNDO" }
| { type: "REDO" };
const graphReducer = (state: GraphState, action: GraphAction): GraphState => {
switch (action.type) {
case "SELECT_NODE":
return {
...state,
selectedNodeId: action.payload,
selectedEdgeId: null,
};
case "TOGGLE_EXPAND":
const newExpanded = new Set(state.expandedNodeIds);
if (newExpanded.has(action.payload)) {
newExpanded.delete(action.payload);
} else {
newExpanded.add(action.payload);
}
return {
...state,
expandedNodeIds: newExpanded,
isDirty: true,
};
default:
return state;
}
};
```
#### History Management
```typescript
const useHistoryManager = (
state: GraphState,
dispatch: Dispatch<GraphAction>,
) => {
const canUndo = state.historyIndex > 0;
const canRedo = state.historyIndex < state.history.length - 1;
const undo = useCallback(() => {
if (canUndo) {
const newIndex = state.historyIndex - 1;
const historyEntry = state.history[newIndex];
dispatch({
type: "RESTORE_FROM_HISTORY",
payload: {
...historyEntry,
historyIndex: newIndex,
},
});
}
}, [canUndo, state.historyIndex, state.history]);
const saveToHistory = useCallback(() => {
dispatch({ type: "SAVE_TO_HISTORY" });
}, [dispatch]);
return { canUndo, canRedo, undo, redo, saveToHistory };
};
```
## Advanced Features
### Auto-Layout Integration
Integrate Dagre for automatic graph layout:
```typescript
import dagre from "dagre";
const layoutOptions = {
rankdir: "TB", // Top to Bottom
nodesep: 100, // Node separation
ranksep: 150, // Rank separation
marginx: 50,
marginy: 50,
edgesep: 10,
};
const applyLayout = (nodes: Node[], edges: Edge[]) => {
const g = new dagre.graphlib.Graph();
g.setGraph(layoutOptions);
g.setDefaultEdgeLabel(() => ({}));
// Add nodes to graph
nodes.forEach((node) => {
g.setNode(node.id, { width: 200, height: 100 });
});
// Add edges to graph
edges.forEach((edge) => {
g.setEdge(edge.source, edge.target);
});
// Calculate layout
dagre.layout(g);
// Apply positions
return nodes.map((node) => ({
...node,
position: {
x: g.node(node.id).x - 100,
y: g.node(node.id).y - 50,
},
}));
};
// Debounce layout calculations
const debouncedLayout = useMemo(() => debounce(applyLayout, 150), []);
```
### Focus Mode
Isolate selected nodes and their direct connections:
```typescript
const useFocusMode = (
selectedNodeId: string,
allNodes: Node[],
allEdges: Edge[],
) => {
return useMemo(() => {
if (!selectedNodeId) return { nodes: allNodes, edges: allEdges };
// Get direct connections
const connectedNodeIds = new Set([selectedNodeId]);
const focusedEdges: Edge[] = [];
allEdges.forEach((edge) => {
if (edge.source === selectedNodeId || edge.target === selectedNodeId) {
focusedEdges.push(edge);
connectedNodeIds.add(edge.source);
connectedNodeIds.add(edge.target);
}
});
// Get connected nodes
const focusedNodes = allNodes.filter((n) => connectedNodeIds.has(n.id));
return { nodes: focusedNodes, edges: focusedEdges };
}, [selectedNodeId, allNodes, allEdges]);
};
// Smooth transitions for focus mode
const focusModeStyles = {
transition: "all 0.3s ease-in-out",
opacity: isInFocus ? 1 : 0.3,
filter: isInFocus ? "none" : "blur(2px)",
};
```
### Search Integration
Search and navigate to specific nodes:
```typescript
const searchNodes = useCallback((nodes: Node[], query: string) => {
if (!query.trim()) return [];
const lowerQuery = query.toLowerCase();
return nodes.filter(
(node) =>
node.data.label.toLowerCase().includes(lowerQuery) ||
node.data.description?.toLowerCase().includes(lowerQuery),
);
}, []);
const navigateToSearchResult = (nodeId: string) => {
// Expand parent nodes
const nodePath = calculateBreadcrumbPath(nodeId, allNodes);
const parentIds = nodePath.slice(0, -1).map((n) => n.id);
setExpandedIds((prev) => new Set([...prev, ...parentIds]));
setSelectedNodeId(nodeId);
// Fit view to node
fitView({ nodes: [{ id: nodeId }], duration: 800 });
};
```
## Performance Tools
### Graph Performance Analyzer
Create a performance analysis script:
```javascript
// scripts/graph-analyzer.js
class GraphAnalyzer {
analyzeCode(content, filePath) {
const analysis = {
metrics: {
nodeCount: this.countNodes(content),
edgeCount: this.countEdges(content),
renderTime: this.estimateRenderTime(content),
memoryUsage: this.estimateMemoryUsage(content),
complexity: this.calculateComplexity(content),
},
issues: [],
optimizations: [],
patterns: this.detectPatterns(content),
};
// Detect performance issues
this.detectPerformanceIssues(analysis);
// Suggest optimizations
this.suggestOptimizations(analysis);
return analysis;
}
countNodes(content) {
const nodePatterns = [
/nodes:\s*\[.*?\]/gs,
/const\s+\w+\s*=\s*\[.*?id:.*?position:/gs,
];
let totalCount = 0;
nodePatterns.forEach((pattern) => {
const matches = content.match(pattern);
if (matches) {
matches.forEach((match) => {
const nodeMatches = match.match(/id:\s*['"`][^'"`]+['"`]/g);
if (nodeMatches) {
totalCount += nodeMatches.length;
}
});
}
});
return totalCount;
}
estimateRenderTime(content) {
const nodeCount = this.countNodes(content);
const edgeCount = this.countEdges(content);
// Base render time estimation (ms)
const baseTime = 5;
const nodeTime = nodeCount * 0.1;
const edgeTime = edgeCount * 0.05;
return baseTime + nodeTime + edgeTime;
}
detectPerformanceIssues(analysis) {
const { metrics } = analysis;
if (metrics.nodeCount > 500) {
analysis.issues.push({
type: "HIGH_NODE_COUNT",
severity: "high",
message: `Too many nodes (${metrics.nodeCount}). Consider virtualization.`,
suggestion: "Implement virtualization or reduce visible nodes",
});
}
if (metrics.renderTime > 16) {
analysis.issues.push({
type: "SLOW_RENDER",
severity: "high",
message: `Render time (${metrics.renderTime.toFixed(2)}ms) exceeds 60fps.`,
suggestion: "Optimize with memoization and incremental rendering",
});
}
}
}
```
## Best Practices
### Performance Guidelines
1. **Use React.memo** for node components to prevent unnecessary re-renders
2. **Implement virtualization** for graphs with 1000+ nodes
3. **Debounce layout calculations** during rapid interactions
4. **Use useCallback** for edge creation and manipulation functions
5. **Implement proper TypeScript types** for nodes and edges
### Memory Management
```typescript
// Use Map for O(1) lookups instead of array.find
const nodesById = useMemo(
() => new Map(allNodes.map((n) => [n.id, n])),
[allNodes],
);
// Cache layout results
const layoutCacheRef = useRef<Map<string, Node[]>>(new Map());
// Proper cleanup in useEffect
useEffect(() => {
return () => {
// Clean up any lingering references
nodesMapRef.current.clear();
edgesMapRef.current.clear();
};
}, []);
```
### State Optimization
```typescript
// Use useRef for objects that shouldn't trigger re-renders
const autoSaveDataRef = useRef({
nodes: [],
edges: [],
lastSaved: Date.now(),
});
// Update properties without breaking reference
const updateAutoSaveData = (newNodes: Node[], newEdges: Edge[]) => {
autoSaveDataRef.current.nodes = newNodes;
autoSaveDataRef.current.edges = newEdges;
autoSaveDataRef.current.lastSaved = Date.now();
};
```
## Common Problems & Solutions
### Performance Issues
- **Problem**: Lag during node expansion
- **Solution**: Implement incremental rendering with change detection
- **Problem**: Memory usage increases over time
- **Solution**: Proper cleanup in useEffect hooks and use WeakMap for temporary data
### Layout Conflicts
- **Problem**: Manual positioning conflicts with auto-layout
- **Solution**: Use controlled positioning state and separate layout modes
### Rendering Issues
- **Problem**: Excessive re-renders
- **Solution**: Use memo, useMemo, and useCallback with stable dependencies
- **Problem**: Slow layout calculations
- **Solution**: Debounce layout calculations and cache results
## Complete Example
```typescript
import React, { useState, useCallback, useMemo, useRef } from 'react';
import ReactFlow, { Node, Edge, useReactFlow } from 'reactflow';
import dagre from 'dagre';
import { debounce } from 'lodash';
interface GraphState {
nodes: Node[];
edges: Edge[];
selectedNodeId: string | null;
expandedNodeIds: Set<string>;
history: GraphState[];
historyIndex: number;
}
export default function InteractiveGraph() {
const [state, setState] = useState<GraphState>({
nodes: [],
edges: [],
selectedNodeId: null,
expandedNodeIds: new Set(),
history: [],
historyIndex: 0,
});
const { fitView } = useReactFlow();
const layoutCacheRef = useRef<Map<string, Node[]>>(new Map());
// Memoized styled edges
const styledEdges = useMemo(() => {
return state.edges.map(edge => ({
...edge,
style: {
...edge.style,
strokeWidth: state.selectedNodeId === edge.source || state.selectedNodeId === edge.target ? 3 : 2,
stroke: state.selectedNodeId === edge.source || state.selectedNodeId === edge.target ? '#3b82f6' : '#94a3b8',
},
animated: state.selectedNodeId === edge.source || state.selectedNodeId === edge.target,
}));
}, [state.edges, state.selectedNodeId]);
// Debounced layout calculation
const debouncedLayout = useMemo(
() => debounce((nodes: Node[], edges: Edge[]) => {
const cacheKey = generateLayoutCacheKey(nodes, edges);
if (layoutCacheRef.current.has(cacheKey)) {
return layoutCacheRef.current.get(cacheKey)!;
}
const layouted = applyDagreLayout(nodes, edges);
layoutCacheRef.current.set(cacheKey, layouted);
return layouted;
}, 150),
[]
);
const handleNodeClick = useCallback((event: React.MouseEvent, node: Node) => {
setState(prev => ({
...prev,
selectedNodeId: node.id,
}));
}, []);
const handleToggleExpand = useCallback((nodeId: string) => {
setState(prev => {
const newExpanded = new Set(prev.expandedNodeIds);
if (newExpanded.has(nodeId)) {
newExpanded.delete(nodeId);
} else {
newExpanded.add(nodeId);
}
return {
...prev,
expandedNodeIds: newExpanded,
};
});
}, []);
return (
<ReactFlow
nodes={state.nodes}
edges={styledEdges}
onNodeClick={handleNodeClick}
fitView
/>
);
}
```
This comprehensive skill provides everything needed to build production-ready ReactFlow applications with hierarchical navigation, performance optimization, and advanced state management patterns.

View File

@@ -3923,6 +3923,15 @@
"risk": "safe",
"source": "https://github.com/playwright-community/playwright-go"
},
{
"id": "go-rod-master",
"path": "skills/go-rod-master",
"category": "uncategorized",
"name": "go-rod-master",
"description": "Comprehensive guide for browser automation and web scraping with go-rod (Chrome DevTools Protocol) including stealth anti-bot-detection patterns.",
"risk": "safe",
"source": "https://github.com/go-rod/rod"
},
{
"id": "godot-gdscript-patterns",
"path": "skills/godot-gdscript-patterns",
@@ -4418,6 +4427,24 @@
"risk": "unknown",
"source": "vibeship-spawner-skills (Apache 2.0)"
},
{
"id": "laravel-expert",
"path": "skills/laravel-expert",
"category": "uncategorized",
"name": "laravel-expert",
"description": "Senior Laravel Engineer role for production-grade, maintainable, and idiomatic Laravel solutions. Focuses on clean architecture, security, performance, and modern standards (Laravel 10/11+).",
"risk": "safe",
"source": "community"
},
{
"id": "laravel-security-audit",
"path": "skills/laravel-security-audit",
"category": "uncategorized",
"name": "laravel-security-audit",
"description": "Security auditor for Laravel applications. Analyzes code for vulnerabilities, misconfigurations, and insecure practices using OWASP standards and Laravel security best practices.",
"risk": "safe",
"source": "community"
},
{
"id": "last30days",
"path": "skills/last30days",
@@ -5759,6 +5786,15 @@
"risk": "unknown",
"source": "unknown"
},
{
"id": "react-flow-architect",
"path": "skills/react-flow-architect",
"category": "uncategorized",
"name": "react-flow-architect",
"description": "Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements.",
"risk": "unknown",
"source": "unknown"
},
{
"id": "react-flow-node-ts",
"path": "skills/react-flow-node-ts",