### Angular Component Style Guide Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/angular/architecture/SKILL.md An example of an Angular component adhering to the official style guide, including dependency injection, inputs/outputs, internal state, computed properties, and methods. ```typescript @Component({...}) export class UserProfileComponent { // 1. Injected dependencies private readonly userService = inject(UserService); // 2. Inputs/Outputs readonly userId = input.required(); readonly userSaved = output(); // 3. Internal state private readonly _loading = signal(false); readonly loading = this._loading.asReadonly(); // 4. Computed protected readonly displayName = computed(() => ...); // 5. Methods save(): void { ... } } ``` -------------------------------- ### Create Agent Skills Directory (Manual Installation) Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/README.md Manually create the necessary skills directory for your agent if it does not already exist. This is a prerequisite for manual skill installation. ```bash # Example for Claude Code mkdir -p ~/.claude/skills ``` ```bash # Example for Gemini CLI mkdir -p ~/.gemini/skills ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/github-pr/SKILL.md Illustrates the structure of conventional commits, showing examples of good atomic commits versus a single large commit. ```bash # Good: One thing per commit git commit -m "feat(user): add User model" git commit -m "feat(user): add UserService" git commit -m "test(user): add UserService tests" # Bad: Everything in one commit git commit -m "add user feature" ``` -------------------------------- ### Complete TypeScript Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/SKILL_TEMPLATE.md A complete TypeScript example demonstrating a specific use case. This shows the pattern in action. ```typescript // Complete example showing the pattern in action const completeExample = () => { // Implementation }; ``` -------------------------------- ### Expo Router Navigation Setup Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/react-native/SKILL.md Configure root layout for Expo Router navigation. This example sets up a stack navigator with options for header visibility and screen transitions. ```typescript // app/_layout.tsx import { Stack } from 'expo-router'; import { StatusBar } from 'expo-status-bar'; export default function RootLayout() { return ( <> ); } ``` -------------------------------- ### Skill Frontmatter Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/SKILL_TEMPLATE.md This is the required YAML frontmatter for a skill. Ensure all fields are correctly populated. ```yaml --- name: your-skill-name description: > Brief description of what this skill covers. Trigger: When working with [technology], when building [type of app], when using [library]. metadata: author: your-github-username version: "1.0" --- ``` -------------------------------- ### Another TypeScript Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/SKILL_TEMPLATE.md An alternative TypeScript example for a different use case. Provides variety in implementation. ```typescript // Another example const anotherExample = () => { // Implementation }; ``` -------------------------------- ### Copy Skill Folder (Manual Installation) Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/README.md Manually copy a specific skill folder into your agent's skills directory after ensuring the directory exists. ```bash cp -r curated/react-19 ~/.claude/skills/ ``` -------------------------------- ### Third TypeScript Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/SKILL_TEMPLATE.md A third TypeScript example, offering another perspective on implementation. Useful for diverse scenarios. ```typescript // Third example const thirdExample = () => { // Implementation }; ``` -------------------------------- ### Angular SSR and Client Hydration Setup Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Set up Angular Universal Server-Side Rendering (SSR) with client hydration for improved performance and SEO. This example shows the basic `bootstrapApplication` call with `provideClientHydration()`. ```typescript // ✅ SSR + Client Hydration bootstrapApplication(AppComponent, { providers: [provideClientHydration()] }); ``` -------------------------------- ### Angular Project Structure Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/angular/architecture/SKILL.md Illustrates a recommended project structure for Angular applications, separating features, shared modules, and core functionalities. ```tree features/ shopping-cart/ shopping-cart.ts # Main component = feature name components/ cart-item.ts # Used ONLY by shopping-cart cart-summary.ts # Used ONLY by shopping-cart checkout/ checkout.ts components/ payment-form.ts # Used ONLY by checkout shared/ components/ button.ts # Used by shopping-cart AND checkout modal.ts # Used by multiple features ``` ```tree src/app/ features/ [feature-name]/ [feature-name].ts # Main component (same name as folder) components/ # Feature-specific components services/ # Feature-specific services models/ # Feature-specific types shared/ # ONLY for 2+ feature usage components/ services/ pipes/ core/ # App-wide singletons services/ interceptors/ guards/ app.ts app.config.ts routes.ts main.ts ``` -------------------------------- ### Electron Auto-Updater Setup and IPC Handlers Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/electron/SKILL.md Configures the `electron-updater` service in the main process to check for, download, and install updates. It also sets up IPC handlers to trigger these update actions from the renderer process. ```typescript // main/services/updater.ts import { autoUpdater } from 'electron-updater'; import { BrowserWindow } from 'electron'; import log from 'electron-log'; export function setupAutoUpdater(mainWindow: BrowserWindow) { autoUpdater.logger = log; autoUpdater.autoDownload = false; autoUpdater.autoInstallOnAppQuit = true; autoUpdater.on('checking-for-update', () => { mainWindow.webContents.send('updater:checking'); }); autoUpdater.on('update-available', (info) => { mainWindow.webContents.send('updater:available', info); }); autoUpdater.on('update-not-available', () => { mainWindow.webContents.send('updater:not-available'); }); autoUpdater.on('download-progress', (progress) => { mainWindow.webContents.send('updater:progress', progress); }); autoUpdater.on('update-downloaded', () => { mainWindow.webContents.send('updater:downloaded'); }); autoUpdater.on('error', (error) => { mainWindow.webContents.send('updater:error', error.message); }); // Check for updates on startup (with delay) setTimeout(() => { autoUpdater.checkForUpdates(); }, 5000); } // IPC handlers for updater export function registerUpdaterHandlers() { ipcMain.handle('updater:check', () => autoUpdater.checkForUpdates()); ipcMain.handle('updater:download', () => autoUpdater.downloadUpdate()); ipcMain.handle('updater:install', () => autoUpdater.quitAndInstall()); } ``` -------------------------------- ### Main Process Setup and Window Creation Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/electron/SKILL.md Sets up the main Electron process, creates the primary browser window, and configures web preferences for security. This code handles application lifecycle events and loads the application content. ```typescript // main/index.ts import { app, BrowserWindow, ipcMain } from 'electron'; import path from 'path'; import { registerIpcHandlers } from './ipc/handlers'; let mainWindow: BrowserWindow | null = null; async function createWindow() { mainWindow = new BrowserWindow({ width: 1200, height: 800, minWidth: 800, minHeight: 600, webPreferences: { preload: path.join(__dirname, '../preload/index.js'), contextIsolation: true, // Required for security nodeIntegration: false, // Required for security sandbox: true, // Extra security }, titleBarStyle: process.platform === 'darwin' ? 'hiddenInset' : 'default', trafficLightPosition: { x: 15, y: 10 }, }); // Register IPC handlers registerIpcHandlers(); // Load the app if (process.env.NODE_ENV === 'development') { mainWindow.loadURL('http://localhost:5173'); mainWindow.webContents.openDevTools(); } else { mainWindow.loadFile(path.join(__dirname, '../renderer/index.html')); } mainWindow.on('closed', () => { mainWindow = null; }); } app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } }); ``` -------------------------------- ### Task Linking Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/jira-task/SKILL.md Example of how to link related tasks within a Jira task description using markdown. This includes specifying parent tasks, tasks that are blocked by the current task, and tasks that the current task blocks. ```markdown ## Related Tasks - Parent: [Parent task title/link] (for child tasks) - Blocked by: [API task title/link] - Blocks: [UI task title/link] ``` -------------------------------- ### Conventional Commit Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/SKILL_TEMPLATE.md Example of a conventional commit message format for tracking changes in a project. ```git feat(community): add your-skill-name skill ``` -------------------------------- ### Angular CLI Commands for Project Setup Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/angular/architecture/SKILL.md Common Angular CLI commands for creating a new project, generating components within a feature, creating services, and generating functional guards. ```bash # New project ng new my-app --style=scss --ssr=false # Component in feature ng g c features/products/components/product-card --flat # Service in feature ng g s features/products/services/product --flat # Guard in core ng g g core/guards/auth --functional ``` -------------------------------- ### Pytest Fixtures for Test Setup Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/pytest/SKILL.md Illustrates how to define fixtures for creating test data, setting up authenticated clients, and managing temporary files with cleanup logic. Also shows different fixture scopes. ```python import pytest @pytest.fixture def user(): """Create a test user.""" return User(name="Test User", email="test@example.com") @pytest.fixture def authenticated_client(client, user): """Client with authenticated user.""" client.force_login(user) return client # Fixture with teardown @pytest.fixture def temp_file(): path = Path("/tmp/test_file.txt") path.write_text("test content") yield path # Test runs here path.unlink() # Cleanup after test # Fixture scopes @pytest.fixture(scope="module") # Once per module @pytest.fixture(scope="class") # Once per class @pytest.fixture(scope="session") # Once per test session ``` -------------------------------- ### Next.js Server Component Example Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Demonstrates a default Server Component in Next.js 15, which is async by default and does not require a directive. ```typescript // ✅ Server Component — async by default, no directive needed export default async function Page() { const data = await db.query(); return ; } ``` -------------------------------- ### Server Action for User Creation Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/nextjs-15/SKILL.md Implement Server Actions to handle form submissions and mutations. This example creates a user, revalidates the cache, and redirects. ```typescript // app/actions.ts "use server"; import { revalidatePath } from "next/cache"; import { redirect } from "next/navigation"; export async function createUser(formData: FormData) { const name = formData.get("name") as string; await db.users.create({ data: { name } }); revalidatePath("/users"); redirect("/users"); } // Usage
``` -------------------------------- ### Mocking Dependencies with unittest.mock Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/pytest/SKILL.md Shows how to use `unittest.mock.patch` to mock external services like Stripe for testing payment processing. Includes examples for successful charges and handling payment failures with side effects. ```python from unittest.mock import patch, MagicMock class TestPaymentService: def test_process_payment_success(self): with patch("services.payment.stripe_client") as mock_stripe: mock_stripe.charge.return_value = {"id": "ch_123", "status": "succeeded"} result = process_payment(amount=100) assert result["status"] == "succeeded" mock_stripe.charge.assert_called_once_with(amount=100) def test_process_payment_failure(self): with patch("services.payment.stripe_client") as mock_stripe: mock_stripe.charge.side_effect = PaymentError("Card declined") with pytest.raises(PaymentError): process_payment(amount=100) # MagicMock for complex objects def test_with_mock_object(): mock_user = MagicMock() mock_user.id = "user-123" mock_user.name = "Test User" mock_user.is_active = True result = get_user_info(mock_user) assert result["name"] == "Test User" ``` -------------------------------- ### Complete Error Handling Pattern Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/elixir-antipatterns/assets/extended.md Demonstrates a complete error handling pattern using tagged tuples for various operations within a module, including fetching, finding by email, and creating users. ```elixir # ✅ Complete error handling pattern defmodule UserService do alias MyApp.{Repo, User} @spec fetch_user(String.t()) :: {:ok, User.t()} | {:error, :not_found} def fetch_user(id) do case Repo.get(User, id) do nil -> {:error, :not_found} user -> {:ok, user} end end @spec find_by_email(String.t()) :: {:ok, User.t()} | {:error, :not_found} def find_by_email(email) do case Repo.get_by(User, email: email) do nil -> {:error, :not_found} user -> {:ok, user} end end @spec create(map()) :: {:ok, User.t()} | {:error, Changeset.t()} def create(attrs) do %User{} |> User.changeset(attrs) |> Repo.insert() end end ``` -------------------------------- ### Mermaid Architecture Diagram Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/jira-epic/SKILL.md Example of a Mermaid graph to visualize system architecture, showing components and their interactions. ```mermaid graph TB UI[UI Components] --> API[API Endpoints] API --> SDK[Prowler SDK] SDK --> Cloud[Cloud Providers] ``` -------------------------------- ### Conventional Commits Examples Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/CONTRIBUTING.md Follow the Conventional Commits specification for all commit messages. This includes a type, optional scope, and a description. ```text (): Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert ``` ```text feat(community): add react-native skill ``` ```text fix(curated): correct typo in typescript skill ``` ```text docs: update README installation steps ``` -------------------------------- ### SKILL.md Template Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/skill-creator/SKILL.md Provides a template for the main SKILL.md file, outlining essential sections like frontmatter, usage, patterns, examples, commands, and resources. ```markdown --- name: {skill-name} description: > {One-line description of what this skill does}. Trigger: {When the AI should load this skill}. license: Apache-2.0 metadata: author: gentleman-programming version: "1.0" --- ## When to Use {Bullet points of when to use this skill} ## Critical Patterns {The most important rules - what AI MUST know} ## Code Examples {Minimal, focused examples} ## Commands ```bash {Common commands} ``` ## Resources - **Templates**: See [assets/](assets/) for {description} - **Documentation**: See [references/](references/) for local docs ``` -------------------------------- ### Good TypeScript Example Pattern Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/SKILL_TEMPLATE.md Illustrates a good coding pattern in TypeScript. Use this structure for implementing functionality within your skill. ```typescript // Good example const example = () => { // Your code here }; ``` -------------------------------- ### Client Chat Component Setup with useChat Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/ai-sdk-5/SKILL.md Sets up a React chat component using the `useChat` hook from `@ai-sdk/react`. It includes state management for input, message display, and form submission. ```typescript import { useChat } from "@ai-sdk/react"; import { DefaultChatTransport } from "ai"; import { useState } from "react"; export function Chat() { const [input, setInput] = useState(""); const { messages, sendMessage, isLoading, error } = useChat({ transport: new DefaultChatTransport({ api: "/api/chat" }), }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!input.trim()) return; sendMessage({ text: input }); setInput(""); }; return (
{messages.map((message) => ( ))}
setInput(e.target.value)} placeholder="Type a message..." disabled={isLoading} />
{error &&
Error: {error.message}
}
); } ``` -------------------------------- ### Elixir ExUnit Testing Best Practices Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/elixir-antipatterns/assets/extended.md Demonstrates independent and parallelizable tests using ExUnit. The `async: true` option in `MyApp.DataCase` enables parallel execution, and the `setup` block ensures each test receives fresh data, promoting isolation. ```elixir # ✅ CORRECT - Independent, parallel tests defmodule MyApp.UserServiceTest do use MyApp.DataCase, async: true # Parallel execution alias MyApp.UserService # Each test gets fresh data via setup setup do user = insert(:user, email: "test_#{System.unique_integer()}@example.com") {:ok, user: user} end describe "fetch_user/1" do test "returns user when exists", %{user: user} do assert {:ok, found} = UserService.fetch_user(user.id) assert found.id == user.id assert found.email == user.email end test "returns error when not found" do assert {:error, :not_found} = UserService.fetch_user("nonexistent") end end describe "create_user/1" do test "creates user with valid attributes" do attrs = %{name: "John", email: "john@example.com"} assert {:ok, user} = UserService.create_user(attrs) assert user.name == "John" assert user.email == "john@example.com" end test "returns error with invalid attributes" do attrs = %{name: "", email: "invalid"} assert {:error, changeset} = UserService.create_user(attrs) assert %{name: ["can't be blank"], email: ["invalid format"]} = errors_on(changeset) end end end ``` -------------------------------- ### Basic Reactive Form Setup Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/angular/forms/SKILL.md Reactive Forms are recommended for production applications. Ensure type safety by using `fb.nonNullable.group()` and retrieve typed values with `getRawValue()`. ```typescript import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; @Component({ imports: [ReactiveFormsModule], template: `
` }) export class LoginComponent { private readonly fb = inject(FormBuilder); form = this.fb.nonNullable.group({ email: ['', [Validators.required, Validators.email]], password: ['', [Validators.required, Validators.minLength(8)]], }); submit() { if (this.form.valid) { const { email, password } = this.form.getRawValue(); } } } ``` -------------------------------- ### Elixir Database Table and Index Creation Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Define database tables with appropriate columns and create unique indexes on frequently queried columns to optimize database performance. This example shows creating a `users` table with an `email` column and a unique index on `email`. ```elixir create table(:users) do add :email, :string end create unique_index(:users, [:email]) ``` -------------------------------- ### Streaming with Tools using AI SDK Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/ai-sdk-5/SKILL.md Example of configuring `streamText` to use tools. It defines a `getWeather` tool with parameters and an execution function, allowing the model to call tools during the streaming process. ```typescript import { openai } from "@ai-sdk/openai"; import { streamText, tool } from "ai"; import { z } from "zod"; const result = await streamText({ model: openai("gpt-4o"), messages, tools: { getWeather: tool({ description: "Get weather for a location", parameters: z.object({ location: z.string().describe("City name"), }), execute: async ({ location }) => { // Fetch weather data return { temperature: 72, condition: "sunny" }; }, }), }, }); ``` -------------------------------- ### Basic Signal Form Setup Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/angular/forms/SKILL.md Use Signal Forms for new applications leveraging Angular signals. They offer automatic two-way binding, type-safe access, and schema-based validation. ```typescript import { form, FormField, required, email } from '@angular/forms/signals'; @Component({ imports: [FormField], template: `
` }) export class LoginComponent { readonly loginForm = form({ email: ['', [required, email]], password: ['', required] }); readonly emailField = this.loginForm.controls.email; readonly passwordField = this.loginForm.controls.password; submit() { if (this.loginForm.valid()) { const values = this.loginForm.value(); } } } ``` -------------------------------- ### Shared Fixtures in conftest.py Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/pytest/SKILL.md Demonstrates how to define shared fixtures like database sessions and API clients in a conftest.py file for use across multiple test files. Includes session rollback and API client setup. ```python # tests/conftest.py - Shared fixtures import pytest @pytest.fixture def db_session(): session = create_session() yield session session.rollback() @pytest.fixture def api_client(): return TestClient(app) ``` -------------------------------- ### Next.js Route Handler (API) Example Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Define API endpoints using Route Handlers in the App Router. Supports GET and POST requests. ```typescript // ✅ Route Handler (API) // app/api/users/route.ts import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest) { const users = await db.users.findMany(); return NextResponse.json(users); } export async function POST(request: NextRequest) { const body = await request.json(); const user = await db.users.create({ data: body }); return NextResponse.json(user, { status: 201 }); } ``` -------------------------------- ### PR Creation Quick Reference Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/github-pr/SKILL.md A table summarizing common `gh pr create` commands and options for quick reference. ```bash Create PR | `gh pr create -t "type: desc" -b "body"` Draft PR | `gh pr create --draft` Web editor | `gh pr create --web` Add reviewer | `--reviewer user1,user2` Add label | `--label bug,high-priority` Link issue | `Closes #123` in body View status | `gh pr status` Merge squash | `gh pr merge --squash` ``` -------------------------------- ### Registering a Skill in AGENTS.md Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/skill-creator/SKILL.md Shows how to register a newly created skill by adding an entry to the AGENTS.md file. ```markdown | `{skill-name}` | {Description} | [SKILL.md](skills/{skill-name}/SKILL.md) | ``` -------------------------------- ### AI Assistant Skill Loading Instructions Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/elixir-antipatterns/README.md Provides instructions on how to load the Elixir anti-patterns skill for AI assistants and how to reference extended documentation. ```markdown ## Skills When working with Elixir/Phoenix code, load the `elixir-antipatterns` skill. For comprehensive patterns, reference `extended.md`. ``` -------------------------------- ### Common Grid Patterns Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/tailwind-4/SKILL.md Examples of common Tailwind CSS grid utility classes for layout. ```html
``` -------------------------------- ### Clone Repository and Create Skill Directory Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/CONTRIBUTING.md Clone the Gentleman-Skills repository and create a new directory for your skill within the 'community/' folder. ```bash # Fork the repo on GitHub, then: git clone https://github.com/YOUR_USERNAME/Gentleman-Skills.git cd Gentleman-Skills ``` ```bash mkdir -p community/your-skill-name ``` -------------------------------- ### Common Flexbox Patterns Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/tailwind-4/SKILL.md Examples of common Tailwind CSS flexbox utility classes for layout. ```html
``` -------------------------------- ### Electron main process secure BrowserWindow configuration Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Configure the `BrowserWindow` in the Electron main process with essential security settings: `contextIsolation: true`, `nodeIntegration: false`, and `sandbox: true`. The `preload` script must be correctly specified. ```typescript // ✅ main/index.ts — secure BrowserWindow mainWindow = new BrowserWindow({ webPreferences: { preload: path.join(__dirname, '../preload/index.js'), contextIsolation: true, // REQUIRED nodeIntegration: false, // REQUIRED sandbox: true, // extra security }, }); ``` -------------------------------- ### Pytest Fixtures and Mocking Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Illustrates Pytest fixtures with setup/teardown and scopes, `conftest.py` for shared fixtures, and mocking with `unittest.mock` for isolating dependencies. ```python import pytest from unittest.mock import patch, MagicMock # ✅ Fixtures with teardown and scopes @pytest.fixture def temp_file(): path = Path("/tmp/test_file.txt") path.write_text("test content") yield path # test runs here path.unlink() # cleanup @pytest.fixture(scope="session") # once per test session def db_session(): session = create_session() yield session session.rollback() ``` ```python # ✅ conftest.py — shared fixtures auto-loaded by pytest # tests/conftest.py @pytest.fixture def api_client(): return TestClient(app) ``` ```python # ✅ Mocking class TestPaymentService: def test_process_payment_success(self): with patch("services.payment.stripe_client") as mock_stripe: mock_stripe.charge.return_value = {"id": "ch_123", "status": "succeeded"} result = process_payment(amount=100) assert result["status"] == "succeeded" mock_stripe.charge.assert_called_once_with(amount=100) def test_process_payment_failure(self): with patch("services.payment.stripe_client") as mock_stripe: mock_stripe.charge.side_effect = PaymentError("Card declined") with pytest.raises(PaymentError): process_payment(amount=100) ``` ```python # ✅ Parametrize @pytest.mark.parametrize("email,is_valid", [ ("user@example.com", True), ("invalid-email", False), ("", False), ]) def test_email_validation(email, is_valid): assert validate_email(email) == is_valid ``` ```python # ✅ Markers @pytest.mark.slow def test_large_data_processing(): ... @pytest.mark.skipif(sys.platform == "win32", reason="Unix only") def test_unix_specific(): ... ``` ```python # ✅ Async @pytest.mark.asyncio async def test_async_function(): result = await async_fetch_data() assert result is not None ``` ```bash pytest -v # Verbose pytest -x # Stop on first failure pytest -k "test_user" # Filter by name pytest -m "not slow" # Skip slow tests pytest --cov=src # Coverage pytest -n auto # Parallel (pytest-xdist) ``` -------------------------------- ### Add NativeWind and Tailwind CSS Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/react-native/SKILL.md Install NativeWind and Tailwind CSS for styling in your Expo project. ```bash npx expo install nativewind tailwindcss ``` -------------------------------- ### Create PR using Web Editor Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/github-pr/SKILL.md Open the GitHub web editor to create a Pull Request, allowing for more interactive description writing. ```bash gh pr create --web ``` -------------------------------- ### Mermaid State Diagram Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/jira-epic/SKILL.md Example of a Mermaid state diagram to represent the different states of an entity and the transitions between them. ```mermaid stateDiagram-v2 [*] --> Pending Pending --> InProgress: Start triage InProgress --> Resolved: Mark resolved InProgress --> Pending: Reset Resolved --> [*] ``` -------------------------------- ### Mermaid Entity Relationship Diagram Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/jira-epic/SKILL.md Example of a Mermaid ER diagram to show the relationships between different data entities. ```mermaid erDiagram FINDING ||--o{ RESOURCE : affects FINDING }|--|| CHECK : "belongs to" RESOURCE }|--|| ACCOUNT : "belongs to" ACCOUNT }|--|| PROVIDER : "belongs to" ``` -------------------------------- ### Use SafeAreaInsets Hook Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/react-native/SKILL.md Get safe area insets for layout adjustments using the useSafeAreaInsets hook from react-native-safe-area-context. ```javascript useSafeAreaInsets() ``` -------------------------------- ### Directory Decision Tree: assets/ vs references/ Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/skill-creator/SKILL.md Illustrates when to use the 'assets/' directory for code templates and schemas versus the 'references/' directory for linking to local documentation. ```text Need code templates? → assets/ Need JSON schemas? → assets/ Need example configs? → assets/ Link to existing docs? → references/ Link to external guides? → references/ (with local path) **Key Rule**: `references/` should point to LOCAL files (`docs/developer-guide/*.mdx`), not web URLs. ``` -------------------------------- ### Mermaid Data Flow Diagram Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/jira-epic/SKILL.md Example of a Mermaid sequence diagram to illustrate data flow between different parts of the system. ```mermaid sequenceDiagram User->>UI: Apply filters UI->>API: GET /findings?filters API->>DB: Query findings DB-->>API: Results API-->>UI: JSON response UI-->>User: Render table ``` -------------------------------- ### Create New Expo Project Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/community/react-native/SKILL.md Use this command to create a new Expo project with the tabs template. ```bash npx create-expo-app@latest --template tabs ``` -------------------------------- ### Bad TypeScript Anti-Pattern Example Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/SKILL_TEMPLATE.md Illustrates a bad coding practice in TypeScript, highlighting an anti-pattern to avoid. Use this to understand what not to do. ```typescript // Bad example - DON'T do this const badExample = () => { // What NOT to do }; ``` -------------------------------- ### Common Responsive Design Patterns Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/tailwind-4/SKILL.md Illustrates Tailwind CSS utility classes for creating responsive layouts that adapt to different screen sizes. ```html
``` -------------------------------- ### Decision Tree Logic Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/skill-creator/assets/SKILL-TEMPLATE.md Represents a simple decision-making process for the AI, guiding actions based on sequential questions and outcomes. ```text {Question 1}? → {Action A} {Question 2}? → {Action B} Otherwise → {Default action} ``` -------------------------------- ### Copy Curated Skills to Agent Directory (macOS/Linux) Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/README.md Copy all curated skills to a specific agent's skills directory. Replace with the appropriate path for your agent (e.g., ~/.claude/skills/). ```bash # Example: Claude Code (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.claude/skills/ ``` ```bash # Example: OpenCode (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.config/opencode/skills/ ``` ```bash # Example: Gemini CLI (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.gemini/skills/ ``` ```bash # Example: Cursor (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.cursor/skills/ ``` -------------------------------- ### Common Typography Patterns Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/tailwind-4/SKILL.md Examples of Tailwind CSS utility classes for text styling, including size, weight, color, and case. ```html

``` -------------------------------- ### Clone and Copy Gentleman-Skills to Agent Directory Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Clone the repository and copy curated skills to your AI agent's skills directory. Reference the skill in your agent configuration file. ```bash # Clone the repo git clone https://github.com/Gentleman-Programming/Gentleman-Skills.git # Claude Code (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.claude/skills/ # OpenCode (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.config/opencode/skills/ # Gemini CLI (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.gemini/skills/ # Cursor (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.cursor/skills/ # Windsurf (macOS/Linux) cp -r Gentleman-Skills/curated/* ~/.codeium/windsurf/skills/ # Copy a single skill only cp -r Gentleman-Skills/curated/react-19 ~/.claude/skills/ # Reference it in your agent config (CLAUDE.md, etc.) # "When working with React, read ~/.claude/skills/react-19/SKILL.md first." ``` -------------------------------- ### Text Generation with useCompletion Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/ai-sdk-5/SKILL.md Demonstrates text generation using the `useCompletion` hook. It shows how to set up the transport and trigger a completion request with a prompt. ```typescript import { useCompletion } from "@ai-sdk/react"; import { DefaultCompletionTransport } from "ai"; const { completion, complete, isLoading } = useCompletion({ transport: new DefaultCompletionTransport({ api: "/api/complete" }), }); // Trigger completion await complete("Write a haiku about"); ``` -------------------------------- ### Zod Optional, Nullable, and Defaults Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/zod-4/SKILL.md Shows how to define fields that are optional (undefined), nullable (null), or both (`nullish`). Demonstrates setting default values for schemas, including dynamic defaults using functions. ```typescript // Optional (T | undefined) z.string().optional() // Nullable (T | null) z.string().nullable() // Both (T | null | undefined) z.string().nullish() // Default values z.string().default("unknown") z.number().default(() => Math.random()) ``` -------------------------------- ### Common State and Interaction Patterns Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/curated/tailwind-4/SKILL.md Examples of Tailwind CSS utility classes for styling element states like hover, focus, active, and group states. ```html {error &&

Error: {error.message}
}

); } ``` -------------------------------- ### Angular Zoneless Application Setup Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Configures an Angular application to run without Zone.js, improving performance and reducing bundle size. Use this for new projects or when optimizing existing ones. ```typescript // ✅ Zoneless setup bootstrapApplication(AppComponent, { providers: [provideZonelessChangeDetection()] }); ``` -------------------------------- ### Create Feature Branch and Commit Skill Source: https://github.com/gentleman-programming/gentleman-skills/blob/main/CONTRIBUTING.md Create a new Git branch for your skill, add the skill files, commit them with a conventional commit message, and push to your fork. ```bash git checkout -b add-skill-your-skill-name ``` ```bash git add community/your-skill-name ``` ```bash git commit -m "feat(community): add your-skill-name skill" ``` ```bash git push origin add-skill-your-skill-name ``` -------------------------------- ### Angular Nested Forms and FormArray Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Demonstrates creating nested forms and using `FormArray` in Angular. This example shows a form with a name, a nested address group, and a dynamic list of phone numbers. ```typescript // ✅ Nested Forms & FormArray form = this.fb.nonNullable.group({ name: [''], address: this.fb.group({ street: [''], city: [''] }), phones: this.fb.array([this.fb.control('')]), }); get phones() { return this.form.get('phones') as FormArray; } addPhone() { this.phones.push(this.fb.control('')); } ``` -------------------------------- ### Angular Reactive Forms (Production) Source: https://context7.com/gentleman-programming/gentleman-skills/llms.txt Utilize Reactive Forms with `nonNullable: true` for production-ready Angular applications. Always import `ReactiveFormsModule`. This example shows a login form with email and password validation. ```typescript // ✅ Reactive Forms (production-ready) import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; @Component({ imports: [ReactiveFormsModule], template: `
`}) export class LoginReactiveComponent { private readonly fb = inject(FormBuilder); // ALWAYS nonNullable for type safety form = this.fb.nonNullable.group({ email: ['', [Validators.required, Validators.email]], password: ['', [Validators.required, Validators.minLength(8)]], }); submit() { if (this.form.valid) { const { email, password } = this.form.getRawValue(); // typed } } } ```