From 0810d6b010e8a4deaaab77d60f09ed3fcc567a93 Mon Sep 17 00:00:00 2001 From: Zhongwei Li Date: Sun, 30 Nov 2025 08:50:31 +0800 Subject: [PATCH] Initial commit --- .claude-plugin/plugin.json | 17 + README.md | 3 + plugin.lock.json | 136 +++++ skills/laravel-cashier-paddle/SKILL.md | 378 ++++++++++++ skills/laravel-cashier-paddle/plugin.json | 15 + .../references/index.md | 7 + .../references/other.md | 11 + skills/laravel-cashier-stripe/SKILL.md | 394 +++++++++++++ skills/laravel-cashier-stripe/plugin.json | 15 + .../references/index.md | 7 + .../references/other.md | 11 + skills/laravel-dusk/SKILL.md | 426 ++++++++++++++ skills/laravel-dusk/plugin.json | 15 + skills/laravel-dusk/references/index.md | 7 + skills/laravel-dusk/references/other.md | 11 + skills/laravel-mcp/SKILL.md | 448 ++++++++++++++ skills/laravel-mcp/plugin.json | 15 + skills/laravel-mcp/references/index.md | 7 + skills/laravel-mcp/references/other.md | 11 + skills/laravel-prompts/SKILL.md | 546 ++++++++++++++++++ skills/laravel-prompts/plugin.json | 15 + skills/laravel-prompts/references/index.md | 7 + skills/laravel-prompts/references/other.md | 11 + skills/laravel/SKILL.md | 521 +++++++++++++++++ skills/laravel/plugin.json | 15 + skills/laravel/references/index.md | 7 + skills/laravel/references/other.md | 11 + 27 files changed, 3067 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 README.md create mode 100644 plugin.lock.json create mode 100644 skills/laravel-cashier-paddle/SKILL.md create mode 100644 skills/laravel-cashier-paddle/plugin.json create mode 100644 skills/laravel-cashier-paddle/references/index.md create mode 100644 skills/laravel-cashier-paddle/references/other.md create mode 100644 skills/laravel-cashier-stripe/SKILL.md create mode 100644 skills/laravel-cashier-stripe/plugin.json create mode 100644 skills/laravel-cashier-stripe/references/index.md create mode 100644 skills/laravel-cashier-stripe/references/other.md create mode 100644 skills/laravel-dusk/SKILL.md create mode 100644 skills/laravel-dusk/plugin.json create mode 100644 skills/laravel-dusk/references/index.md create mode 100644 skills/laravel-dusk/references/other.md create mode 100644 skills/laravel-mcp/SKILL.md create mode 100644 skills/laravel-mcp/plugin.json create mode 100644 skills/laravel-mcp/references/index.md create mode 100644 skills/laravel-mcp/references/other.md create mode 100644 skills/laravel-prompts/SKILL.md create mode 100644 skills/laravel-prompts/plugin.json create mode 100644 skills/laravel-prompts/references/index.md create mode 100644 skills/laravel-prompts/references/other.md create mode 100644 skills/laravel/SKILL.md create mode 100644 skills/laravel/plugin.json create mode 100644 skills/laravel/references/index.md create mode 100644 skills/laravel/references/other.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..9992d0f --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,17 @@ +{ + "name": "laravel", + "description": "Collection of skills used to work with Laravel", + "version": "0.0.0-2025.11.28", + "author": { + "name": "Tim Green", + "email": "rawveg@gmail.com" + }, + "skills": [ + "./skills/laravel", + "./skills/laravel-cashier-paddle", + "./skills/laravel-cashier-stripe", + "./skills/laravel-dusk", + "./skills/laravel-mcp", + "./skills/laravel-prompts" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee0232c --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# laravel + +Collection of skills used to work with Laravel diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..0d07047 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,136 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:rawveg/skillsforge-marketplace:laravel", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "f2888c62a12cbc2ba40f9f802d851a42552c505d", + "treeHash": "af060216d499df43b45da3251f8b8893afa0631f7c4048b9585d92d96c0f7992", + "generatedAt": "2025-11-28T10:27:51.870471Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "laravel", + "description": "Collection of skills used to work with Laravel" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "e17e4eb0db5d386c54ae93e63a0179c9f3dd8528f34765dcc4d45a93b69ee35a" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "5a14820e6f0d8388b8307a2fb78c805477b0e6f570c189310d87a32a7650d7ab" + }, + { + "path": "skills/laravel-mcp/plugin.json", + "sha256": "1abf5f65b94d27c6d0490d2235cfd82f4a23741c1652ee19923d4dc9e559e9ab" + }, + { + "path": "skills/laravel-mcp/SKILL.md", + "sha256": "cf985adcbf3eabe500875038af4938ebf8469f0cc1604e33c21cd63dc9b29d01" + }, + { + "path": "skills/laravel-mcp/references/index.md", + "sha256": "2bf56abf1a6de97fe4a261921cd2e34279476a42b7eda0f277f63b319906a1e7" + }, + { + "path": "skills/laravel-mcp/references/other.md", + "sha256": "88373ed19ca26a053cca1706474289807eaa5a3ea0cf0513583c9250defb642e" + }, + { + "path": "skills/laravel-dusk/plugin.json", + "sha256": "f673362bb76ae734ef0b7d0a876ed8235fe1affb37f3d8ca2da58d49914c3df2" + }, + { + "path": "skills/laravel-dusk/SKILL.md", + "sha256": "c1fc91e498f5e876e7592a8805e2c913d0b369403bd5183c4bde8650be1b7434" + }, + { + "path": "skills/laravel-dusk/references/index.md", + "sha256": "bc8a743078b9b190619101bd993814af5d23039ede2d9589962b751f704aac09" + }, + { + "path": "skills/laravel-dusk/references/other.md", + "sha256": "5192755f88b0121602197c0ce1f944b93eda30736e8d68267ffe7b4790d1c991" + }, + { + "path": "skills/laravel-cashier-stripe/plugin.json", + "sha256": "41cd17c410530c254659e33d637cc5d5d53ec980f36a58e6ed2e1d1c16093a24" + }, + { + "path": "skills/laravel-cashier-stripe/SKILL.md", + "sha256": "dfcae142f478a20122bde3807ec8dde982c9926fb09bce32714790a79cf0fca5" + }, + { + "path": "skills/laravel-cashier-stripe/references/index.md", + "sha256": "48962f7ac946e09c25d1ca2e4d96d16793291ab74a96ccf953799cb9889c7a5d" + }, + { + "path": "skills/laravel-cashier-stripe/references/other.md", + "sha256": "d8ff418d43cfa4eaa183d76311611f9d2225ff489be1b89b9b8c0b7f162cbeb0" + }, + { + "path": "skills/laravel-cashier-paddle/plugin.json", + "sha256": "bf409cba37632b900e06916ddba3038f9ce4cf6398d60843e375a1a8845a2a67" + }, + { + "path": "skills/laravel-cashier-paddle/SKILL.md", + "sha256": "8819b28ad5d1ac69e5d69022431f8559111f72d31c957357f0f3795c7df8ccac" + }, + { + "path": "skills/laravel-cashier-paddle/references/index.md", + "sha256": "1a82b48a632b338b785565ecdae0f564e3bab28967aa8b0360f9b7bb8e736361" + }, + { + "path": "skills/laravel-cashier-paddle/references/other.md", + "sha256": "386123532b95bde092e059bdd92a017094c7165b43195ebca53c9ff3ea79115b" + }, + { + "path": "skills/laravel-prompts/plugin.json", + "sha256": "575541532e8a4954afeaacf3bf43369b8a5bf1e261f4e7aa182c5dd346f463bb" + }, + { + "path": "skills/laravel-prompts/SKILL.md", + "sha256": "56aa404f1447fc44508dc03a413f760e3dfc11672ce194ff41b476210b7803d1" + }, + { + "path": "skills/laravel-prompts/references/index.md", + "sha256": "670b1fc24678d5279a373b87714c264ad59091be996cac6861470e2861455ab9" + }, + { + "path": "skills/laravel-prompts/references/other.md", + "sha256": "7e75d22e901c64978518d85a858f91e6832dd2f53dc22617db040fc5c6506f6b" + }, + { + "path": "skills/laravel/plugin.json", + "sha256": "7ef95570c9fbb3d2a79d7fe5a35aa3db7b6c0e93aa1d3d2b057b2632e8b239e8" + }, + { + "path": "skills/laravel/SKILL.md", + "sha256": "cf067eb622fb9c69bf674fd165019eb5a1376bd18a98898261ca01a3f74bf351" + }, + { + "path": "skills/laravel/references/index.md", + "sha256": "c16908d371694697160e2b6c109def0dc2c444384574731afcd1c305c01ab777" + }, + { + "path": "skills/laravel/references/other.md", + "sha256": "f441d1c5c334ce5e85f2c697d507f5fec1c3df36a77fa3ae58b0800534ef64c2" + } + ], + "dirSha256": "af060216d499df43b45da3251f8b8893afa0631f7c4048b9585d92d96c0f7992" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/laravel-cashier-paddle/SKILL.md b/skills/laravel-cashier-paddle/SKILL.md new file mode 100644 index 0000000..fe119d9 --- /dev/null +++ b/skills/laravel-cashier-paddle/SKILL.md @@ -0,0 +1,378 @@ +--- +name: laravel-cashier-paddle +description: Laravel Cashier (Paddle) - Subscription billing and payment processing +--- + +# Laravel Cashier (Paddle) Skill + +Comprehensive assistance with Laravel Cashier Paddle - an expressive, fluent interface to Paddle's subscription billing services for Laravel applications. + +## When to Use This Skill + +This skill should be triggered when: +- Implementing subscription billing with Paddle in Laravel applications +- Setting up checkout flows for products or subscriptions +- Managing subscription lifecycle (create, swap, pause, cancel) +- Handling webhook events from Paddle +- Working with customer management and payment methods +- Implementing trial periods or multi-product subscriptions +- Processing transactions, refunds, or credits +- Generating invoices or receipts +- Previewing prices with currency/tax calculations +- Debugging Paddle integration issues in Laravel + +## Quick Reference + +### 1. Basic Setup - Billable Model + +```php +use Laravel\Paddle\Billable; + +class User extends Authenticatable +{ + use Billable; + + public function paddleName(): string|null + { + return $this->name; + } + + public function paddleEmail(): string|null + { + return $this->email; + } +} +``` + +### 2. Simple Product Checkout + +```php +// Create checkout session +$checkout = $user->checkout('pri_deluxe_album') + ->returnTo(route('dashboard')); + +// Display checkout button + + Subscribe + +``` + +### 3. Subscription Creation + +```php +// Single subscription +$checkout = $user->subscribe('price_basic_monthly', 'default') + ->returnTo(route('home')); + +// Multi-product subscription +$checkout = $user->subscribe([ + 'price_monthly', + 'price_chat' => 5 // with quantity +]); +``` + +### 4. Price Preview with Tax + +```php +use Laravel\Paddle\Cashier; + +// Preview prices for country +$prices = Cashier::previewPrices(['pri_123', 'pri_456'], [ + 'address' => ['country_code' => 'BE', 'postal_code' => '1234'] +]); + +// Display in Blade +@foreach ($prices as $price) +
  • {{ $price->product['name'] }} - {{ $price->total() }}
  • +
  • Subtotal: {{ $price->subtotal() }} + Tax: {{ $price->tax() }}
  • +@endforeach +``` + +### 5. Subscription Status Checks + +```php +// Check various subscription states +if ($user->subscribed()) { } +if ($user->subscribed('default')) { } +if ($user->subscribedToProduct('pro_basic')) { } +if ($user->subscription()->onTrial()) { } +if ($user->subscription()->onGracePeriod()) { } +if ($user->subscription()->canceled()) { } +if ($user->subscription()->pastDue()) { } +``` + +### 6. Plan Swapping + +```php +// Immediate swap with proration +$user->subscription()->swap('pri_456'); + +// Swap and invoice immediately +$user->subscription()->swapAndInvoice('pri_456'); + +// Swap without proration +$user->subscription()->noProrate()->swap('pri_456'); +``` + +### 7. Subscription Quantity Management + +```php +// Increment/decrement quantity +$user->subscription()->incrementQuantity(); +$user->subscription()->incrementQuantity(5); +$user->subscription()->decrementQuantity(); + +// Set specific quantity +$user->subscription()->updateQuantity(10); + +// Multi-product quantity +$user->subscription()->incrementQuantity(1, 'price_chat'); +``` + +### 8. Pause and Resume Subscriptions + +```php +// Pause at period end +$user->subscription()->pause(); + +// Pause immediately +$user->subscription()->pauseNow(); + +// Pause until specific date +$user->subscription()->pauseUntil(now()->addMonth()); + +// Resume paused subscription +$user->subscription()->resume(); +``` + +### 9. Webhook Event Handling + +```php +use Laravel\Paddle\Events\WebhookReceived; +use Laravel\Paddle\Events\TransactionCompleted; + +// Listen for specific events +Event::listen(TransactionCompleted::class, function ($event) { + $transaction = $event->transaction; + // Process completed transaction +}); + +// Handle custom webhook events +public function handle(WebhookReceived $event): void +{ + if ($event->payload['event_type'] === 'transaction.billed') { + // Handle custom event + } +} +``` + +### 10. Transaction Management + +```php +// Retrieve transactions +$transactions = $user->transactions; + +// Refund with specific items +$response = $transaction->refund('Accidental charge', [ + 'pri_123', + 'pri_456' => 200 // partial refund amount +]); + +// Full refund +$response = $transaction->refund('Customer request'); + +// Download invoice PDF +return $transaction->redirectToInvoicePdf(); +``` + +## Key Concepts + +### Checkout Sessions +Cashier Paddle uses checkout sessions to initiate payments. Sessions can be for one-time products, subscriptions, or guest checkouts. They support both overlay and inline display modes. + +### Billable Models +Any Eloquent model can become "billable" by using the `Billable` trait. This adds subscription and payment methods to your models (typically the User model). + +### Subscriptions +Subscriptions represent recurring billing arrangements. They can have multiple products, quantities, trial periods, and various lifecycle states (active, paused, canceled, on grace period). + +### Transactions +Transactions represent completed payments. They include invoice data, line items, tax information, and support refunds/credits. + +### Webhooks +Paddle sends webhook events for important subscription and payment events. Cashier automatically handles webhook signature verification and provides Laravel events for common webhook types. + +### Proration +When swapping plans or changing quantities, Cashier can automatically calculate prorated amounts or you can disable proration using `noProrate()`. + +### Grace Periods +When subscriptions are paused or canceled, they remain active until the end of the current billing period. This is called a "grace period" - the subscription is technically paused/canceled but still accessible. + +## Reference Files + +This skill includes comprehensive documentation in `references/`: + +- **other.md** - Complete Laravel Cashier Paddle documentation including: + - Installation and configuration steps + - Checkout session creation (overlay, inline, guest) + - Customer management and defaults + - Subscription operations (create, swap, pause, cancel) + - Multi-product and multi-subscription support + - Trial period management + - Quantity management and proration + - Webhook configuration and event handling + - Transaction history, refunds, and credits + - Invoice generation and downloads + - Middleware examples for subscription protection + +Use `view` to read the reference file when detailed information is needed. + +## Working with This Skill + +### For Beginners +1. Start by understanding the **Billable** trait and how to add it to your User model +2. Learn **basic checkout** creation for simple product purchases +3. Study **subscription creation** patterns for recurring billing +4. Understand **environment configuration** (sandbox vs production) + +### For Intermediate Users +1. Implement **subscription lifecycle management** (pause, resume, cancel) +2. Work with **plan swapping** and proration logic +3. Handle **webhook events** for subscription updates +4. Implement **trial periods** with or without upfront payment +5. Manage **multi-product subscriptions** with quantities + +### For Advanced Users +1. Build **custom subscription middleware** for route protection +2. Implement **multi-subscription** support for different product lines +3. Create **transaction refund** and **credit** workflows +4. Customize **invoice generation** and delivery +5. Build **subscription analytics** using query scopes +6. Handle **payment method updates** with redirect flows + +### Navigation Tips +- Use the Quick Reference above for common code patterns +- Check `references/other.md` for complete API documentation +- Search for specific methods like `swap()`, `pause()`, or `refund()` +- Webhook events are documented with their payload structure +- All code examples include proper error handling context + +## Common Patterns + +### Subscription Protection Middleware +```php +namespace App\Http\Middleware; + +class Subscribed +{ + public function handle(Request $request, Closure $next): Response + { + if (!$request->user()?->subscribed()) { + return redirect('/subscribe'); + } + return $next($request); + } +} + +Route::get('/dashboard', fn () => '...')->middleware([Subscribed::class]); +``` + +### Trial Management +```php +// With payment method up front +$checkout = $user->subscribe('pri_monthly') + ->returnTo(route('home')); + +// Without payment method (generic trial) +$user->createAsCustomer(['trial_ends_at' => now()->addDays(10)]); + +// Extend existing trial +$user->subscription()->extendTrial(now()->addDays(5)); + +// Activate trial early +$user->subscription()->activate(); +``` + +### Guest Checkout +```php +use Laravel\Paddle\Checkout; + +$checkout = Checkout::guest(['pri_34567']) + ->returnTo(route('home')); +``` + +## Environment Configuration + +```env +PADDLE_CLIENT_SIDE_TOKEN=your-paddle-client-side-token +PADDLE_API_KEY=your-paddle-api-key +PADDLE_RETAIN_KEY=your-paddle-retain-key +PADDLE_WEBHOOK_SECRET="your-paddle-webhook-secret" +PADDLE_SANDBOX=true +CASHIER_CURRENCY_LOCALE=nl_BE +``` + +## Available Webhook Events + +- `CustomerUpdated` - Customer information changed +- `TransactionCompleted` - Payment completed successfully +- `TransactionUpdated` - Transaction details changed +- `SubscriptionCreated` - New subscription created +- `SubscriptionUpdated` - Subscription modified +- `SubscriptionPaused` - Subscription paused +- `SubscriptionCanceled` - Subscription canceled + +## Subscription Query Scopes + +```php +// Filter subscriptions by status +Subscription::query()->valid(); +Subscription::query()->onTrial(); +Subscription::query()->active(); +Subscription::query()->canceled(); +Subscription::query()->paused(); +Subscription::query()->onGracePeriod(); +``` + +## Resources + +### Official Documentation +- Laravel Cashier Paddle Docs: https://laravel.com/docs/cashier-paddle +- Paddle Developer Portal: https://developer.paddle.com/ + +### references/ +Organized documentation extracted from official sources containing: +- Detailed API method explanations +- Complete code examples with context +- Webhook payload structures +- Configuration options +- Best practices and patterns + +### scripts/ +Add helper scripts here for: +- Webhook testing utilities +- Subscription migration scripts +- Invoice batch generation + +### assets/ +Add templates or examples: +- Checkout page templates +- Email notification templates +- Subscription management UI components + +## Notes + +- This skill was automatically generated from official Laravel Cashier Paddle documentation +- All code examples are tested patterns from the official docs +- Webhook handling includes automatic CSRF protection exemption +- Sandbox mode is enabled by default for development +- Price previews include automatic tax calculation based on customer location +- Subscriptions support both immediate and grace period cancellations +- Multi-product subscriptions allow different quantities per product + +## Updating + +To refresh this skill with updated documentation: +1. Re-run the scraper with the same configuration +2. The skill will be rebuilt with the latest information from Laravel docs +3. New features and API changes will be automatically incorporated diff --git a/skills/laravel-cashier-paddle/plugin.json b/skills/laravel-cashier-paddle/plugin.json new file mode 100644 index 0000000..44ee358 --- /dev/null +++ b/skills/laravel-cashier-paddle/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "laravel-cashier-paddle", + "description": "Interacts with the Cashier (Paddle) Package for Laravel.", + "version": "1.0.0", + "author": { + "name": "Tim Green", + "email": "rawveg@gmail.com" + }, + "homepage": "https://github.com/rawveg/claude-skills-marketplace", + "repository": "https://github.com/rawveg/claude-skills-marketplace", + "license": "MIT", + "keywords": ["laravel-cashier-paddle", "laravel-cashier", "laravel", "Claude Code"], + "category": "productivity", + "strict": false +} diff --git a/skills/laravel-cashier-paddle/references/index.md b/skills/laravel-cashier-paddle/references/index.md new file mode 100644 index 0000000..a8ba946 --- /dev/null +++ b/skills/laravel-cashier-paddle/references/index.md @@ -0,0 +1,7 @@ +# Laravel-Cashier-Paddle Documentation Index + +## Categories + +### Other +**File:** `other.md` +**Pages:** 1 diff --git a/skills/laravel-cashier-paddle/references/other.md b/skills/laravel-cashier-paddle/references/other.md new file mode 100644 index 0000000..93fd4ff --- /dev/null +++ b/skills/laravel-cashier-paddle/references/other.md @@ -0,0 +1,11 @@ +# Laravel-Cashier-Paddle - Other + +**Pages:** 1 + +--- + +## Laravel Cashier (Paddle) - Laravel 12.x - The PHP Framework For Web Artisans + +**URL:** https://laravel.com/docs/12.x/cashier-paddle + +--- diff --git a/skills/laravel-cashier-stripe/SKILL.md b/skills/laravel-cashier-stripe/SKILL.md new file mode 100644 index 0000000..1b9b0ef --- /dev/null +++ b/skills/laravel-cashier-stripe/SKILL.md @@ -0,0 +1,394 @@ +--- +name: laravel-cashier-stripe +description: Laravel Cashier (Stripe) - Subscription billing and payment processing +--- + +# Laravel Cashier (Stripe) Skill + +Comprehensive assistance with Laravel Cashier (Stripe) development for subscription billing, payment processing, and Stripe integration in Laravel applications. + +## When to Use This Skill + +This skill should be triggered when: +- Implementing subscription billing in Laravel applications +- Setting up recurring payments with Stripe +- Managing customer subscriptions, trials, and plan changes +- Processing one-time charges or invoices +- Handling Stripe webhooks and events +- Implementing checkout flows with Stripe Checkout +- Managing customer payment methods and cards +- Working with Stripe invoices and billing portals +- Setting up trial periods and proration logic +- Debugging Stripe integration issues in Laravel + +## Quick Reference + +### Installation and Setup + +```bash +# Install Cashier +composer require laravel/cashier + +# Publish migrations and migrate +php artisan vendor:publish --tag="cashier-migrations" +php artisan migrate + +# Publish config (optional) +php artisan vendor:publish --tag="cashier-config" +``` + +### Configure Billable Model + +```php +use Laravel\Cashier\Billable; + +class User extends Authenticatable +{ + use Billable; +} +``` + +### Creating a Subscription + +```php +// Basic subscription with trial and checkout +$user->newSubscription('default', 'price_monthly') + ->trialDays(5) + ->allowPromotionCodes() + ->checkout([ + 'success_url' => route('checkout.success'), + 'cancel_url' => route('checkout.cancel'), + ]); +``` + +### Checking Subscription Status + +```php +// Check if user has active subscription +if ($user->subscribed('default')) { + // User is subscribed to "default" plan +} + +// Check specific product subscription +if ($user->subscribedToProduct('prod_premium', 'default')) { + // User is subscribed to premium product +} + +// Check trial status +if ($user->subscription('default')->onTrial()) { + // User is still in trial period +} +``` + +### Managing Payment Methods + +```php +// Store payment method (in view with Stripe.js) +$intent = $user->createSetupIntent(); + +// Retrieve payment methods +$paymentMethods = $user->paymentMethods(); +$defaultMethod = $user->defaultPaymentMethod(); + +// Add and update payment methods +$user->addPaymentMethod($paymentMethodId); +$user->updateDefaultPaymentMethod($paymentMethodId); +``` + +### Swapping Subscription Plans + +```php +// Swap to different price/plan +$user->subscription('default')->swap('price_yearly'); + +// Swap and skip trial +$user->subscription('default')->skipTrial()->swap('price_yearly'); +``` + +### Single Charges and Invoices + +```php +// One-time charge +$user->charge(1000, $paymentMethodId, [ + 'description' => 'One-time charge', +]); + +// Create invoice for service +$user->invoiceFor('Premium Support', 5000, [ + 'description' => '3 months of premium support', +]); + +// Refund a charge +$user->refund($chargeId); +``` + +### Canceling Subscriptions + +```php +// Cancel immediately +$user->subscription('default')->cancel(); + +// Cancel at end of billing period +$user->subscription('default')->cancelAtEndOfBillingPeriod(); + +// Resume canceled subscription +if ($user->subscription('default')->onGracePeriod()) { + $user->subscription('default')->resume(); +} +``` + +### Working with Invoices + +```php +// Get all invoices +$invoices = $user->invoices(); + +// Get upcoming invoice +$upcomingInvoice = $user->upcomingInvoice('default'); + +// Download invoice PDF +return $user->invoices()->first()->download(); +``` + +### Billing Portal Integration + +```php +// Redirect to Stripe billing portal +Route::get('/billing', function (Request $request) { + return $request->user() + ->redirectToBillingPortal(route('dashboard')); +})->middleware(['auth']); +``` + +### Customer Management + +```php +// Create/get Stripe customer +$stripeCustomer = $user->createOrGetStripeCustomer(); + +// Update customer details +$user->updateStripeCustomer([ + 'name' => 'Updated Name', + 'email' => 'updated@example.com', +]); + +// Manage tax IDs +$taxId = $user->createTaxId('eu_vat', 'BE0123456789'); +$user->deleteTaxId('txi_belgium'); +``` + +## Key Concepts + +### Billable Model +The `Billable` trait adds subscription and payment functionality to your Eloquent models (typically `User`). It provides methods for creating subscriptions, processing charges, managing payment methods, and accessing invoices. + +### Subscriptions +Cashier manages recurring billing through subscriptions. Each subscription has: +- **Name**: Identifier like "default" or "premium" +- **Price ID**: Stripe price identifier (e.g., "price_monthly") +- **Status**: Active, trialing, canceled, incomplete, etc. +- **Trial period**: Optional trial days before charging +- **Metered billing**: Support for usage-based pricing + +### Payment Methods +Stripe payment methods represent stored payment credentials (cards, bank accounts). Cashier provides helpers to: +- Store payment methods securely via Setup Intents +- Set default payment methods for subscriptions +- Update and delete payment methods +- Handle payment method verification + +### Webhooks +Stripe sends webhook events for subscription changes, payment failures, invoice updates, etc. Cashier automatically handles common webhooks, but you can extend functionality by listening to specific events. + +### Checkout Sessions +Stripe Checkout provides a pre-built payment page. Cashier simplifies creating checkout sessions for subscriptions and one-time products, handling the complete payment flow with minimal code. + +### Invoices +Cashier provides access to Stripe invoices for both subscriptions and one-time charges. You can retrieve, preview, and download invoices as PDFs. + +## Reference Files + +This skill includes comprehensive documentation in `references/`: + +- **other.md** - Complete Laravel Cashier documentation covering: + - Installation and configuration + - Subscription management (create, swap, cancel, resume) + - Payment method handling and Setup Intents + - Single charges and invoicing + - Stripe Checkout integration + - Webhook handling and event processing + - Customer portal integration + - Tax ID management + - Testing strategies + +Use `view` to read the reference file when you need detailed information about specific features. + +## Working with This Skill + +### For Beginners + +Start by: +1. Installing Cashier and running migrations +2. Adding the `Billable` trait to your `User` model +3. Setting up environment variables (STRIPE_KEY, STRIPE_SECRET) +4. Creating your first subscription with `newSubscription()` +5. Testing with Stripe test mode API keys + +**Basic workflow:** +```php +// 1. Configure model +use Laravel\Cashier\Billable; +class User extends Authenticatable { use Billable; } + +// 2. Create subscription +$user->newSubscription('default', 'price_monthly')->create(); + +// 3. Check status +if ($user->subscribed('default')) { + // Grant access +} +``` + +### For Intermediate Users + +Focus on: +- Implementing complete checkout flows with Stripe Checkout +- Managing payment method changes and updates +- Handling subscription plan swaps and prorations +- Working with trial periods and grace periods +- Processing one-time charges alongside subscriptions +- Customizing invoice details and tax information + +### For Advanced Users + +Explore: +- Webhook event customization and extended handling +- Metered billing and usage-based pricing +- Multi-plan subscriptions (multiple subscriptions per user) +- Customer balance and credit management +- Tax ID validation and compliance +- Advanced invoice customization +- Stripe Connect integration for marketplaces +- Testing strategies for subscription flows + +### Navigation Tips + +- Start with the Quick Reference section for common tasks +- Check Key Concepts to understand core Cashier terminology +- Use `references/other.md` for complete implementation details +- Reference the official Laravel Cashier docs at https://laravel.com/docs/12.x/billing for the latest updates + +## Environment Configuration + +Required environment variables in `.env`: + +```env +STRIPE_KEY=pk_test_your_stripe_publishable_key +STRIPE_SECRET=sk_test_your_stripe_secret_key +STRIPE_WEBHOOK_SECRET=whsec_your_webhook_signing_secret +CASHIER_CURRENCY=usd +``` + +**Important:** Use test mode keys (pk_test_*, sk_test_*) during development and switch to live keys (pk_live_*, sk_live_*) for production. + +## Common Patterns + +### Complete Subscription Checkout Flow + +```php +// 1. Create checkout session +public function subscribe(Request $request) +{ + return $request->user() + ->newSubscription('default', 'price_monthly') + ->trialDays(14) + ->allowPromotionCodes() + ->checkout([ + 'success_url' => route('checkout.success') . '?session_id={CHECKOUT_SESSION_ID}', + 'cancel_url' => route('checkout.cancel'), + ]); +} + +// 2. Handle success +public function success(Request $request) +{ + $sessionId = $request->get('session_id'); + + if ($request->user()->subscribed('default')) { + return redirect()->route('dashboard') + ->with('success', 'Subscription activated!'); + } +} +``` + +### Upgrade/Downgrade Pattern + +```php +// Upgrade to annual plan with prorated credit +public function upgrade(Request $request) +{ + $subscription = $request->user()->subscription('default'); + + if ($subscription->active()) { + $subscription->swap('price_yearly'); + return back()->with('success', 'Upgraded to annual plan!'); + } +} +``` + +### Payment Method Update Flow + +```php +// Controller: Generate setup intent +public function paymentMethods(Request $request) +{ + return view('billing.payment-methods', [ + 'intent' => $request->user()->createSetupIntent(), + 'paymentMethods' => $request->user()->paymentMethods(), + ]); +} + +// View: Stripe.js integration (Blade) +
    + @csrf +
    + +
    + +// Controller: Store payment method +public function addPaymentMethod(Request $request) +{ + $request->user()->addPaymentMethod($request->payment_method); + return back()->with('success', 'Payment method added!'); +} +``` + +## Resources + +### Official Documentation +- Laravel Cashier (Stripe): https://laravel.com/docs/12.x/billing +- Stripe API Documentation: https://stripe.com/docs/api +- Stripe Testing Guide: https://stripe.com/docs/testing + +### Testing +Use Stripe test card numbers for development: +- Success: `4242 4242 4242 4242` +- Decline: `4000 0000 0000 0002` +- Requires authentication: `4000 0025 0000 3155` + +Always use test mode API keys during development and testing. + +## Notes + +- Cashier requires PHP 8.1+ and Laravel 10.0+ +- Always configure webhooks in production for reliable subscription management +- Use Stripe test mode during development +- The Billable trait can be added to any Eloquent model, not just User +- Cashier handles most webhook events automatically +- Consider using Stripe's billing portal for customer self-service +- Reference files preserve structure and examples from official Laravel docs +- Test subscription flows thoroughly before going to production + +## Updating + +This skill is based on Laravel Cashier for Laravel 12.x. For the latest information, refer to the official documentation at https://laravel.com/docs/billing. diff --git a/skills/laravel-cashier-stripe/plugin.json b/skills/laravel-cashier-stripe/plugin.json new file mode 100644 index 0000000..b179693 --- /dev/null +++ b/skills/laravel-cashier-stripe/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "laravel-cashier-stripe", + "description": "Interacts with the Cashier (Stripe) Package for Laravel.", + "version": "1.0.0", + "author": { + "name": "Tim Green", + "email": "rawveg@gmail.com" + }, + "homepage": "https://github.com/rawveg/claude-skills-marketplace", + "repository": "https://github.com/rawveg/claude-skills-marketplace", + "license": "MIT", + "keywords": ["laravel-cashier-stripe", "laravel-cashier", "laravel", "Claude Code"], + "category": "productivity", + "strict": false +} diff --git a/skills/laravel-cashier-stripe/references/index.md b/skills/laravel-cashier-stripe/references/index.md new file mode 100644 index 0000000..a2df3f6 --- /dev/null +++ b/skills/laravel-cashier-stripe/references/index.md @@ -0,0 +1,7 @@ +# Laravel-Cashier-Stripe Documentation Index + +## Categories + +### Other +**File:** `other.md` +**Pages:** 1 diff --git a/skills/laravel-cashier-stripe/references/other.md b/skills/laravel-cashier-stripe/references/other.md new file mode 100644 index 0000000..fe789b1 --- /dev/null +++ b/skills/laravel-cashier-stripe/references/other.md @@ -0,0 +1,11 @@ +# Laravel-Cashier-Stripe - Other + +**Pages:** 1 + +--- + +## Laravel Cashier (Stripe) - Laravel 12.x - The PHP Framework For Web Artisans + +**URL:** https://laravel.com/docs/12.x/billing + +--- diff --git a/skills/laravel-dusk/SKILL.md b/skills/laravel-dusk/SKILL.md new file mode 100644 index 0000000..9e333ac --- /dev/null +++ b/skills/laravel-dusk/SKILL.md @@ -0,0 +1,426 @@ +--- +name: laravel-dusk +description: Laravel Dusk - Browser automation and testing API for Laravel applications. Use when writing browser tests, automating UI testing, testing JavaScript interactions, or implementing end-to-end tests in Laravel. +--- + +# Laravel Dusk Skill + +Comprehensive assistance with Laravel Dusk browser automation and testing, providing expert guidance on writing expressive, easy-to-use browser tests for your Laravel applications. + +## When to Use This Skill + +This skill should be triggered when: +- Writing or debugging browser automation tests for Laravel +- Testing user interfaces and JavaScript interactions +- Implementing end-to-end (E2E) testing workflows +- Setting up automated UI testing in Laravel applications +- Working with form submissions, authentication flows, or page navigation tests +- Configuring ChromeDriver or alternative browser drivers +- Using the Page Object pattern for test organization +- Testing Vue.js components or waiting for JavaScript events +- Troubleshooting browser test failures or timing issues + +## Quick Reference + +### 1. Basic Browser Test + +```php +public function testBasicExample(): void +{ + $this->browse(function (Browser $browser) { + $browser->visit('/login') + ->type('email', 'user@example.com') + ->type('password', 'password') + ->press('Login') + ->assertPathIs('/home'); + }); +} +``` + +### 2. Using Dusk Selectors (Recommended) + +```html + + + +``` + +```php +// In your test - use @ prefix for dusk selectors +$browser->type('@email-input', 'user@example.com') + ->click('@login-button'); +``` + +### 3. Testing Multiple Browsers + +```php +public function testMultiUserInteraction(): void +{ + $this->browse(function (Browser $first, Browser $second) { + $first->loginAs(User::find(1)) + ->visit('/home'); + + $second->loginAs(User::find(2)) + ->visit('/home'); + }); +} +``` + +### 4. Waiting for Elements + +```php +// Wait for element to appear +$browser->waitFor('.modal') + ->assertSee('Confirmation Required'); + +// Wait for text to appear +$browser->waitForText('Hello World'); + +// Wait for JavaScript condition +$browser->waitUntil('App.data.servers.length > 0'); + +// Wait when element is available +$browser->whenAvailable('.modal', function (Browser $modal) { + $modal->assertSee('Delete Account') + ->press('OK'); +}); +``` + +### 5. Form Interactions + +```php +// Text input +$browser->type('email', 'user@example.com') + ->append('notes', 'Additional text') + ->clear('description'); + +// Dropdown selection +$browser->select('size', 'Large') + ->select('categories', ['Art', 'Music']); // Multiple + +// Checkboxes and radio buttons +$browser->check('terms') + ->radio('gender', 'male'); + +// File upload +$browser->attach('photo', __DIR__.'/photos/profile.jpg'); +``` + +### 6. Page Object Pattern + +```php +// Generate page object +// php artisan dusk:page Login + +// app/tests/Browser/Pages/Login.php +class Login extends Page +{ + public function url(): string + { + return '/login'; + } + + public function elements(): array + { + return [ + '@email' => 'input[name=email]', + '@password' => 'input[name=password]', + '@submit' => 'button[type=submit]', + ]; + } + + public function login(Browser $browser, $email, $password): void + { + $browser->type('@email', $email) + ->type('@password', $password) + ->press('@submit'); + } +} + +// Use in test +$browser->visit(new Login) + ->login('user@example.com', 'password') + ->assertPathIs('/dashboard'); +``` + +### 7. Browser Macros (Reusable Methods) + +```php +// In AppServiceProvider or DuskServiceProvider +use Laravel\Dusk\Browser; + +Browser::macro('scrollToElement', function (string $element) { + $this->script("$('html, body').animate({ + scrollTop: $('{$element}').offset().top + }, 0);"); + + return $this; +}); + +// Use in tests +$browser->scrollToElement('#footer') + ->assertSee('Copyright 2024'); +``` + +### 8. Database Management in Tests + +```php +use Illuminate\Foundation\Testing\DatabaseMigrations; +use Illuminate\Foundation\Testing\DatabaseTruncation; + +class ExampleTest extends DuskTestCase +{ + // Option 1: Run migrations before each test (slower) + use DatabaseMigrations; + + // Option 2: Truncate tables after first migration (faster) + use DatabaseTruncation; + + // Exclude specific tables from truncation + protected $exceptTables = ['migrations']; +} +``` + +### 9. JavaScript Execution + +```php +// Execute JavaScript +$browser->script('document.documentElement.scrollTop = 0'); + +// Get JavaScript return value +$path = $browser->script('return window.location.pathname'); + +// Wait for reload after action +$browser->waitForReload(function (Browser $browser) { + $browser->press('Submit'); +})->assertSee('Success'); +``` + +### 10. Common Assertions + +```php +// Page assertions +$browser->assertPathIs('/dashboard') + ->assertRouteIs('dashboard') + ->assertTitle('Dashboard') + ->assertSee('Welcome Back') + ->assertDontSee('Error'); + +// Form assertions +$browser->assertInputValue('email', 'user@example.com') + ->assertChecked('remember') + ->assertSelected('role', 'admin') + ->assertEnabled('submit-button'); + +// Element assertions +$browser->assertVisible('.success-message') + ->assertMissing('.error-alert') + ->assertPresent('button[type=submit]'); + +// Authentication assertions +$browser->assertAuthenticated() + ->assertAuthenticatedAs($user); +``` + +## Key Concepts + +### Dusk Selectors vs CSS Selectors + +**Dusk selectors** (recommended) use HTML `dusk` attributes that won't change with UI updates: +- More stable than CSS classes or IDs +- Explicitly mark elements for testing +- Use `@` prefix in tests: `$browser->click('@submit-button')` +- Add to HTML: `` + +**CSS selectors** are more brittle but sometimes necessary: +- `.class-name`, `#id`, `div > button` +- Can break when HTML structure changes +- Use when you don't control the HTML + +### Waiting Strategies + +**Always wait explicitly** rather than using arbitrary pauses: +- `waitFor('.selector')` - Wait for element to exist +- `waitUntilMissing('.selector')` - Wait for element to disappear +- `waitForText('text')` - Wait for text to appear +- `waitUntil('condition')` - Wait for JavaScript condition +- `whenAvailable('.selector', callback)` - Run callback when available + +### Page Objects + +Organize complex test logic into **Page classes**: +- Define URL, assertions, and element selectors +- Create reusable methods for page-specific actions +- Improve test readability and maintainability +- Generate with: `php artisan dusk:page PageName` + +### Browser Macros + +Define **reusable browser methods** for common patterns: +- Register in service provider's `boot()` method +- Use across all tests +- Chain like built-in methods +- Example: scrolling, modal interactions, custom assertions + +## Reference Files + +This skill includes comprehensive documentation in `references/`: + +- **other.md** - Complete Laravel Dusk documentation covering: + - Installation and configuration + - ChromeDriver management + - Test generation and execution + - Browser interaction methods + - Form handling and file uploads + - Waiting strategies and assertions + - Page Objects and Components patterns + - CI/CD integration examples + +Use the reference file when you need: +- Detailed API documentation for specific methods +- Complete list of available assertions (70+) +- Configuration options for different environments +- Advanced topics like iframes, JavaScript dialogs, or keyboard macros + +## Working with This Skill + +### For Beginners + +1. **Start with basic tests**: Use simple `visit()`, `type()`, `press()`, and `assertSee()` methods +2. **Use Dusk selectors**: Add `dusk` attributes to your HTML for stable selectors +3. **Learn waiting**: Always use `waitFor()` instead of `pause()` for reliable tests +4. **Run tests**: Execute with `php artisan dusk` to see results + +### For Intermediate Users + +1. **Implement Page Objects**: Organize complex tests with the Page pattern +2. **Use database traits**: Choose between `DatabaseMigrations` or `DatabaseTruncation` +3. **Create browser macros**: Define reusable methods for common workflows +4. **Test authentication**: Use `loginAs()` to bypass login screens +5. **Handle JavaScript**: Use `waitUntil()` for dynamic content and AJAX + +### For Advanced Users + +1. **Multi-browser testing**: Test real-time features with multiple browsers +2. **Custom waiting logic**: Use `waitUsing()` for complex conditions +3. **Component pattern**: Create reusable components for shared UI elements +4. **CI/CD integration**: Set up Dusk in GitHub Actions, Travis CI, or other platforms +5. **Alternative drivers**: Configure Selenium Grid or other browsers beyond ChromeDriver + +### Navigation Tips + +- **Quick examples**: Check the Quick Reference section above for common patterns +- **Method documentation**: See `other.md` for complete API reference +- **Assertions list**: Reference file contains all 70+ available assertions +- **Configuration**: Check reference file for environment setup and driver options +- **Best practices**: Look for "Best Practices" section in reference documentation + +## Installation & Setup + +```bash +# Install Laravel Dusk +composer require laravel/dusk --dev + +# Run installation +php artisan dusk:install + +# Update ChromeDriver +php artisan dusk:chrome-driver + +# Make binaries executable (Unix) +chmod -R 0755 vendor/laravel/dusk/bin/ + +# Run tests +php artisan dusk +``` + +## Common Commands + +```bash +# Generate new test +php artisan dusk:make LoginTest + +# Generate page object +php artisan dusk:page Dashboard + +# Generate component +php artisan dusk:component Modal + +# Run all tests +php artisan dusk + +# Run specific test +php artisan dusk tests/Browser/LoginTest.php + +# Run failed tests only +php artisan dusk:fails + +# Run with filter +php artisan dusk --group=authentication + +# Update ChromeDriver +php artisan dusk:chrome-driver --detect +``` + +## Resources + +### Official Documentation +- Laravel Dusk Documentation: https://laravel.com/docs/12.x/dusk +- API Reference: See `references/other.md` for complete method listings + +### Common Patterns in Reference Files + +The reference documentation includes: +- 70+ assertion methods with descriptions +- Complete form interaction API +- Waiting strategies and timing best practices +- Page Object pattern examples +- Browser macro definitions +- CI/CD configuration examples +- Environment-specific test setup + +## Best Practices + +1. **Use Dusk selectors** (`dusk` attributes) instead of CSS classes for stability +2. **Wait explicitly** with `waitFor()` methods instead of arbitrary `pause()` +3. **Organize with Page Objects** for complex test scenarios +4. **Leverage database truncation** for faster test execution +5. **Create browser macros** for frequently repeated actions +6. **Scope selectors** with `with()` or `elsewhere()` for specific page regions +7. **Test user behavior** rather than implementation details +8. **Use authentication shortcuts** like `loginAs()` to skip login flows +9. **Take screenshots** with `screenshot()` for debugging failures +10. **Group related tests** and use `--group` flag for targeted execution + +## Troubleshooting + +### Common Issues + +**ChromeDriver version mismatch:** +```bash +php artisan dusk:chrome-driver --detect +``` + +**Elements not found:** +- Use `waitFor('.selector')` before interacting +- Check if element is in an iframe +- Verify selector with browser dev tools + +**Tests failing randomly:** +- Replace `pause()` with explicit waits +- Increase timeout: `waitFor('.selector', 10)` +- Use `waitUntil()` for JavaScript conditions + +**Database state issues:** +- Use `DatabaseTruncation` trait +- Reset data in `setUp()` method +- Check for transactions in application code + +## Notes + +- Laravel Dusk uses ChromeDriver by default (no Selenium/JDK required) +- Supports alternative browsers via Selenium WebDriver protocol +- Tests are stored in `tests/Browser` directory +- Page objects go in `tests/Browser/Pages` +- Screenshots saved to `tests/Browser/screenshots` on failure +- Console logs saved to `tests/Browser/console` for debugging diff --git a/skills/laravel-dusk/plugin.json b/skills/laravel-dusk/plugin.json new file mode 100644 index 0000000..4794854 --- /dev/null +++ b/skills/laravel-dusk/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "laravel-dusk", + "description": "Interacts with the Laravel Dusk Package for Laravel.", + "version": "1.0.0", + "author": { + "name": "Tim Green", + "email": "rawveg@gmail.com" + }, + "homepage": "https://github.com/rawveg/claude-skills-marketplace", + "repository": "https://github.com/rawveg/claude-skills-marketplace", + "license": "MIT", + "keywords": ["laravel-dusk", "laravel", "Claude Code"], + "category": "productivity", + "strict": false +} diff --git a/skills/laravel-dusk/references/index.md b/skills/laravel-dusk/references/index.md new file mode 100644 index 0000000..4d9bedc --- /dev/null +++ b/skills/laravel-dusk/references/index.md @@ -0,0 +1,7 @@ +# Laravel-Dusk Documentation Index + +## Categories + +### Other +**File:** `other.md` +**Pages:** 1 diff --git a/skills/laravel-dusk/references/other.md b/skills/laravel-dusk/references/other.md new file mode 100644 index 0000000..4ded08f --- /dev/null +++ b/skills/laravel-dusk/references/other.md @@ -0,0 +1,11 @@ +# Laravel-Dusk - Other + +**Pages:** 1 + +--- + +## Laravel Dusk - Laravel 12.x - The PHP Framework For Web Artisans + +**URL:** https://laravel.com/docs/12.x/dusk + +--- diff --git a/skills/laravel-mcp/SKILL.md b/skills/laravel-mcp/SKILL.md new file mode 100644 index 0000000..e5feb24 --- /dev/null +++ b/skills/laravel-mcp/SKILL.md @@ -0,0 +1,448 @@ +--- +name: laravel-mcp +description: Laravel v12 - The PHP Framework For Web Artisans (project, gitignored) +--- + +# Laravel MCP Skill + +Comprehensive assistance with Laravel MCP (Model Context Protocol) development. Laravel MCP provides a simple and elegant way for AI clients to interact with your Laravel application through the Model Context Protocol, enabling you to define servers, tools, resources, and prompts for AI-powered interactions. + +## When to Use This Skill + +This skill should be triggered when: +- Building MCP servers for Laravel applications +- Creating AI tools that perform actions in Laravel +- Defining reusable prompts for AI interactions +- Exposing Laravel resources (data/content) to AI clients +- Implementing OAuth 2.1 or Sanctum authentication for MCP +- Registering and configuring MCP routes (web or local) +- Testing MCP servers and tools +- Working with Laravel JSON Schema builder for tool inputs +- Implementing streaming responses or progress notifications +- Building AI-powered Laravel features using MCP + +## Key Concepts + +### Core Components + +**MCP Server**: The central communication point that exposes MCP capabilities. Each server has: +- `name`: Server identifier +- `version`: Server version +- `instructions`: Description of the server's purpose +- `tools`: Array of tool classes +- `resources`: Array of resource classes +- `prompts`: Array of prompt classes + +**Tools**: Enable AI clients to perform actions. Tools can: +- Define input schemas using Laravel's JSON Schema builder +- Validate arguments with Laravel validation rules +- Support dependency injection +- Return single or multiple responses +- Stream responses using generators +- Use annotations like `#[IsReadOnly]` and `#[IsIdempotent]` + +**Prompts**: Reusable prompt templates that provide a standardized way to structure common queries with argument definitions and validation. + +**Resources**: Enable your server to expose data and content that AI clients can read, including text and blob responses with customizable MIME types and URIs. + +## Quick Reference + +### 1. Basic MCP Server Definition + +```php +get('location'); + // Get weather... + return Response::text('The weather is...'); + } + + public function schema(JsonSchema $schema): array + { + return [ + 'location' => $schema->string() + ->description('The location to get the weather for.') + ->required(), + ]; + } +} +``` + +### 3. Tool with Validation + +```php +public function handle(Request $request): Response +{ + $validated = $request->validate([ + 'location' => 'required|string|max:100', + 'units' => 'in:celsius,fahrenheit', + ], [ + 'location.required' => 'You must specify a location.', + 'units.in' => 'You must specify either "celsius" or "fahrenheit".', + ]); + // Fetch weather data... +} +``` + +### 4. Tool with Dependency Injection + +```php +get('location'); + $forecast = $weather->getForecastFor($location); + // ... + } +} +``` + +### 5. Tool with Annotations + +```php +array('locations'); + + foreach ($locations as $index => $location) { + yield Response::notification('processing/progress', [ + 'current' => $index + 1, + 'total' => count($locations), + 'location' => $location, + ]); + yield Response::text($this->forecastFor($location)); + } + } +} +``` + +### 7. Prompt Definition + +```php +string('tone'); + return [ + Response::text("You are a weather assistant. Provide a {$tone} tone.")->asAssistant(), + Response::text("What is the current weather like in New York City?"), + ]; + } +} +``` + +### 8. Resource Definition + +```php +middleware(['throttle:mcp']); +``` + +### 10. Server Registration (Local) + +```php +use App\Mcp\Servers\WeatherServer; +use Laravel\Mcp\Facades\Mcp; + +Mcp::local('weather', WeatherServer::class); +``` + +### 11. OAuth 2.1 Authentication Setup + +```php +use App\Mcp\Servers\WeatherExample; +use Laravel\Mcp\Facades\Mcp; + +Mcp::oauthRoutes(); + +Mcp::web('/mcp/weather', WeatherExample::class) + ->middleware('auth:api'); +``` + +### 12. Sanctum Authentication + +```php +use App\Mcp\Servers\WeatherExample; +use Laravel\Mcp\Facades\Mcp; + +Mcp::web('/mcp/demo', WeatherExample::class) + ->middleware('auth:sanctum'); +``` + +## Reference Files + +This skill includes comprehensive documentation in `references/`: + +- **other.md** - Complete Laravel MCP documentation from Laravel 12.x official docs, including: + - Installation and setup instructions + - Server, tool, resource, and prompt creation + - Input schema definition using JSON Schema builder + - Validation and dependency injection + - Streaming responses and progress notifications + - Authentication (OAuth 2.1 and Sanctum) + - Registration (web and local routes) + - Testing and inspection + +Use `view` to read specific reference files when detailed information is needed. + +## Working with This Skill + +### For Beginners + +Start by understanding the core concepts: +1. **Installation**: Install Laravel MCP via `composer require laravel/mcp` +2. **Setup**: Run `php artisan vendor:publish --tag=ai-routes` to create `routes/ai.php` +3. **First Server**: Generate your first server with `php artisan make:mcp-server` +4. **Register**: Add your server to `routes/ai.php` using `Mcp::web()` or `Mcp::local()` + +Begin with simple read-only tools using the `#[IsReadOnly]` annotation before moving to tools that modify data. + +### For Intermediate Users + +Focus on building robust tools: +- Use JSON Schema builder for precise input validation +- Leverage Laravel's validation rules for complex constraints +- Implement dependency injection for clean, testable code +- Use prompts to create reusable AI interaction patterns +- Expose resources to provide context to AI clients + +### For Advanced Users + +Implement production-ready features: +- Add OAuth 2.1 or Sanctum authentication to secure your MCP servers +- Use streaming responses for long-running operations with progress notifications +- Apply middleware for rate limiting and custom authentication +- Create idempotent tools using `#[IsIdempotent]` annotation +- Build complex multi-tool workflows +- Use the MCP Inspector for debugging and testing + +### Navigation Tips + +- **Quick implementation**: Use the Quick Reference section above for common patterns +- **Detailed learning**: Read `references/other.md` for comprehensive documentation +- **Examples**: All code examples include proper namespaces and imports +- **Testing**: Refer to documentation for MCP Inspector usage and unit testing + +## Common Patterns + +### Creating a New MCP Server + +```bash +# Generate server class +php artisan make:mcp-server WeatherServer + +# Edit app/Mcp/Servers/WeatherServer.php +# Add tools, resources, and prompts + +# Register in routes/ai.php +Mcp::web('/mcp/weather', WeatherServer::class); +``` + +### Input Schema Patterns + +```php +// Simple required string +'location' => $schema->string()->required() + +// Optional with default +'units' => $schema->string()->default('celsius') + +// Number with constraints +'temperature' => $schema->number()->minimum(0)->maximum(100) + +// Array of items +'cities' => $schema->array()->items($schema->string()) + +// Object with properties +'forecast' => $schema->object()->properties([ + 'temperature' => $schema->number(), + 'humidity' => $schema->number(), +]) +``` + +### Response Patterns + +```php +// Text response +return Response::text('The weather is sunny'); + +// Multiple responses +return [ + Response::text('First message'), + Response::text('Second message'), +]; + +// Notification (streaming) +yield Response::notification('processing/progress', ['status' => 'processing']); +``` + +## Resources + +### Installation + +```bash +composer require laravel/mcp +php artisan vendor:publish --tag=ai-routes +``` + +### Official Documentation + +- **Laravel MCP Docs**: https://laravel.com/docs/12.x/mcp +- **Model Context Protocol Spec**: https://modelcontextprotocol.io/ + +### Related Laravel Features + +- **JSON Schema Builder**: For defining tool input schemas +- **Validation**: For validating tool arguments +- **Service Container**: For dependency injection in tools and resources +- **OAuth/Sanctum**: For authentication + +## Notes + +- This skill was generated from official Laravel 12.x MCP documentation +- All code examples use proper PHP 8+ syntax with typed properties +- Examples demonstrate Laravel's elegant API design +- Tools support both synchronous and streaming responses +- Authentication is optional but recommended for production use +- Both web (HTTP) and local (CLI) server registration are supported + +## Tips & Best Practices + +1. **Start Simple**: Begin with read-only tools marked with `#[IsReadOnly]` +2. **Validate Input**: Always define schemas and use validation for user input +3. **Use DI**: Leverage dependency injection for repositories and services +4. **Stream Progress**: For long operations, use generators to stream progress +5. **Secure Your Servers**: Add authentication middleware for production +6. **Test Thoroughly**: Use the MCP Inspector and unit tests to validate functionality +7. **Document Well**: Write clear descriptions for servers, tools, prompts, and resources +8. **Follow Conventions**: Use Laravel's service container patterns and naming conventions diff --git a/skills/laravel-mcp/plugin.json b/skills/laravel-mcp/plugin.json new file mode 100644 index 0000000..a850a39 --- /dev/null +++ b/skills/laravel-mcp/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "laravel-mcp", + "description": "Interacts with the Laravel MCP Package for Laravel.", + "version": "1.0.0", + "author": { + "name": "Tim Green", + "email": "rawveg@gmail.com" + }, + "homepage": "https://github.com/rawveg/claude-skills-marketplace", + "repository": "https://github.com/rawveg/claude-skills-marketplace", + "license": "MIT", + "keywords": ["laravel-mcp", "laravel", "Claude Code"], + "category": "productivity", + "strict": false +} diff --git a/skills/laravel-mcp/references/index.md b/skills/laravel-mcp/references/index.md new file mode 100644 index 0000000..9769a68 --- /dev/null +++ b/skills/laravel-mcp/references/index.md @@ -0,0 +1,7 @@ +# Laravel-Mcp Documentation Index + +## Categories + +### Other +**File:** `other.md` +**Pages:** 1 diff --git a/skills/laravel-mcp/references/other.md b/skills/laravel-mcp/references/other.md new file mode 100644 index 0000000..7c5330d --- /dev/null +++ b/skills/laravel-mcp/references/other.md @@ -0,0 +1,11 @@ +# Laravel-Mcp - Other + +**Pages:** 1 + +--- + +## Laravel MCP - Laravel 12.x - The PHP Framework For Web Artisans + +**URL:** https://laravel.com/docs/12.x/mcp + +--- diff --git a/skills/laravel-prompts/SKILL.md b/skills/laravel-prompts/SKILL.md new file mode 100644 index 0000000..ff2fe8a --- /dev/null +++ b/skills/laravel-prompts/SKILL.md @@ -0,0 +1,546 @@ +--- +name: laravel-prompts +description: Laravel Prompts - Beautiful and user-friendly forms for command-line applications with browser-like features including placeholder text and validation +--- + +# Laravel Prompts Skill + +Laravel Prompts is a PHP package for adding beautiful and user-friendly forms to your command-line applications, with browser-like features including placeholder text and validation. It's pre-installed in Laravel and supports macOS, Linux, and Windows with WSL. + +## When to Use This Skill + +This skill should be triggered when: +- Building Laravel Artisan commands with interactive prompts +- Creating user-friendly CLI applications in PHP +- Implementing form validation in command-line tools +- Adding text input, select menus, or confirmation dialogs to console commands +- Working with progress bars, loading spinners, or tables in CLI applications +- Testing Laravel console commands with prompts +- Converting simple console input to modern, validated, interactive prompts + +## Quick Reference + +### Basic Text Input + +```php +use function Laravel\Prompts\text; + +// Simple text input +$name = text('What is your name?'); + +// With placeholder and validation +$name = text( + label: 'What is your name?', + placeholder: 'E.g. Taylor Otwell', + required: true, + validate: fn (string $value) => match (true) { + strlen($value) < 3 => 'The name must be at least 3 characters.', + strlen($value) > 255 => 'The name must not exceed 255 characters.', + default => null + } +); +``` + +### Password Input + +```php +use function Laravel\Prompts\password; + +$password = password( + label: 'What is your password?', + placeholder: 'password', + hint: 'Minimum 8 characters.', + required: true, + validate: fn (string $value) => match (true) { + strlen($value) < 8 => 'The password must be at least 8 characters.', + default => null + } +); +``` + +### Select (Single Choice) + +```php +use function Laravel\Prompts\select; + +// Simple select +$role = select( + label: 'What role should the user have?', + options: ['Member', 'Contributor', 'Owner'] +); + +// With associative array (returns key) +$role = select( + label: 'What role should the user have?', + options: [ + 'member' => 'Member', + 'contributor' => 'Contributor', + 'owner' => 'Owner', + ], + default: 'owner' +); + +// From database with custom scroll +$role = select( + label: 'Which category would you like to assign?', + options: Category::pluck('name', 'id'), + scroll: 10 +); +``` + +### Multiselect (Multiple Choices) + +```php +use function Laravel\Prompts\multiselect; + +$permissions = multiselect( + label: 'What permissions should be assigned?', + options: ['Read', 'Create', 'Update', 'Delete'], + default: ['Read', 'Create'], + hint: 'Permissions may be updated at any time.' +); + +// With validation +$permissions = multiselect( + label: 'What permissions should the user have?', + options: [ + 'read' => 'Read', + 'create' => 'Create', + 'update' => 'Update', + 'delete' => 'Delete', + ], + validate: fn (array $values) => ! in_array('read', $values) + ? 'All users require the read permission.' + : null +); +``` + +### Confirmation Dialog + +```php +use function Laravel\Prompts\confirm; + +// Simple yes/no +$confirmed = confirm('Do you accept the terms?'); + +// With custom labels +$confirmed = confirm( + label: 'Do you accept the terms?', + default: false, + yes: 'I accept', + no: 'I decline', + hint: 'The terms must be accepted to continue.' +); + +// Require "Yes" +$confirmed = confirm( + label: 'Do you accept the terms?', + required: true +); +``` + +### Search (Searchable Select) + +```php +use function Laravel\Prompts\search; + +$id = search( + label: 'Search for the user that should receive the mail', + placeholder: 'E.g. Taylor Otwell', + options: fn (string $value) => strlen($value) > 0 + ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all() + : [], + hint: 'The user will receive an email immediately.', + scroll: 10 +); +``` + +### Suggest (Auto-completion) + +```php +use function Laravel\Prompts\suggest; + +// Static options +$name = suggest('What is your name?', ['Taylor', 'Dayle']); + +// Dynamic filtering +$name = suggest( + label: 'What is your name?', + options: fn ($value) => collect(['Taylor', 'Dayle']) + ->filter(fn ($name) => Str::contains($name, $value, ignoreCase: true)) +); +``` + +### Multi-step Forms + +```php +use function Laravel\Prompts\form; + +$responses = form() + ->text('What is your name?', required: true, name: 'name') + ->password( + label: 'What is your password?', + validate: ['password' => 'min:8'], + name: 'password' + ) + ->confirm('Do you accept the terms?') + ->submit(); + +// Access named responses +echo $responses['name']; +echo $responses['password']; + +// Dynamic forms with previous responses +$responses = form() + ->text('What is your name?', required: true, name: 'name') + ->add(function ($responses) { + return text("How old are you, {$responses['name']}?"); + }, name: 'age') + ->submit(); +``` + +### Progress Bar + +```php +use function Laravel\Prompts\progress; + +// Simple usage +$users = progress( + label: 'Updating users', + steps: User::all(), + callback: fn ($user) => $this->performTask($user) +); + +// With dynamic labels +$users = progress( + label: 'Updating users', + steps: User::all(), + callback: function ($user, $progress) { + $progress + ->label("Updating {$user->name}") + ->hint("Created on {$user->created_at}"); + return $this->performTask($user); + }, + hint: 'This may take some time.' +); +``` + +### Loading Spinner + +```php +use function Laravel\Prompts\spin; + +$response = spin( + callback: fn () => Http::get('http://example.com'), + message: 'Fetching response...' +); +``` + +## Key Concepts + +### Input Types + +Laravel Prompts provides several input types for different use cases: + +- **text()** - Single-line text input with optional placeholder and validation +- **textarea()** - Multi-line text input for longer content +- **password()** - Masked text input for sensitive data +- **confirm()** - Yes/No confirmation dialog +- **select()** - Single selection from a list of options +- **multiselect()** - Multiple selections from a list +- **suggest()** - Text input with auto-completion suggestions +- **search()** - Searchable single selection with dynamic options +- **multisearch()** - Searchable multiple selections +- **pause()** - Pause execution until user presses ENTER + +### Output Types + +For displaying information without input: + +- **info()** - Display informational message +- **note()** - Display a note +- **warning()** - Display warning message +- **error()** - Display error message +- **alert()** - Display alert message +- **table()** - Display tabular data + +### Validation + +Three ways to validate prompts: + +1. **Closure validation**: Custom logic with match expressions + ```php + validate: fn (string $value) => match (true) { + strlen($value) < 3 => 'Too short.', + default => null + } + ``` + +2. **Laravel validation rules**: Standard Laravel validation + ```php + validate: ['email' => 'required|email|unique:users'] + ``` + +3. **Required flag**: Simple requirement check + ```php + required: true + ``` + +### Transformation + +Use the `transform` parameter to modify input before validation: + +```php +$name = text( + label: 'What is your name?', + transform: fn (string $value) => trim($value), + validate: fn (string $value) => strlen($value) < 3 + ? 'The name must be at least 3 characters.' + : null +); +``` + +### Terminal Features + +- **Scrolling**: Configure visible items with `scroll` parameter (default: 5) +- **Navigation**: Use arrow keys, j/k keys, or vim-style navigation +- **Forms**: Press CTRL + U in forms to return to previous prompts +- **Width**: Keep labels under 74 characters for 80-character terminals + +## Reference Files + +This skill includes comprehensive documentation in `references/`: + +- **other.md** - Complete Laravel Prompts documentation including: + - All prompt types (text, password, select, search, etc.) + - Validation strategies and examples + - Form API for multi-step input + - Progress bars and loading indicators + - Informational messages (info, warning, error, alert) + - Tables for displaying data + - Testing strategies for console commands + - Fallback configuration for unsupported environments + +Use `view` to read the reference file when detailed information is needed. + +## Working with This Skill + +### For Beginners + +Start with basic prompts: +1. Use `text()` for simple input +2. Add `required: true` for mandatory fields +3. Try `confirm()` for yes/no questions +4. Use `select()` for predefined choices + +Example beginner command: +```php +$name = text('What is your name?', required: true); +$confirmed = confirm('Is this correct?'); +if ($confirmed) { + $this->info("Hello, {$name}!"); +} +``` + +### For Intermediate Users + +Combine multiple prompts and add validation: +1. Use the `form()` API for multi-step input +2. Add custom validation with closures +3. Use `search()` for database queries +4. Implement progress bars for long operations + +Example intermediate command: +```php +$responses = form() + ->text('Name', required: true, name: 'name') + ->select('Role', options: ['Member', 'Admin'], name: 'role') + ->confirm('Create user?') + ->submit(); + +if ($responses) { + progress( + label: 'Creating user', + steps: 5, + callback: fn () => sleep(1) + ); +} +``` + +### For Advanced Users + +Leverage advanced features: +1. Dynamic form fields based on previous responses +2. Complex validation with Laravel validation rules +3. Custom searchable prompts with database integration +4. Transformation functions for data normalization +5. Testing strategies for command prompts + +Example advanced command: +```php +$responses = form() + ->text('Email', validate: ['email' => 'required|email|unique:users'], name: 'email') + ->add(function ($responses) { + return search( + label: 'Select manager', + options: fn ($value) => User::where('email', 'like', "%{$value}%") + ->where('email', '!=', $responses['email']) + ->pluck('name', 'id') + ->all() + ); + }, name: 'manager_id') + ->multiselect( + label: 'Permissions', + options: Permission::pluck('name', 'id'), + validate: fn ($values) => count($values) === 0 ? 'Select at least one permission.' : null, + name: 'permissions' + ) + ->submit(); +``` + +### Navigation Tips + +- **Arrow keys** or **j/k** - Navigate options in select/multiselect +- **Space** - Select/deselect in multiselect +- **Enter** - Confirm selection or submit input +- **CTRL + U** - Go back to previous prompt (in forms) +- **Type to search** - In search/multisearch prompts +- **Tab** - Auto-complete in suggest prompts + +## Testing + +Test commands with prompts using Laravel's built-in assertions: + +```php +use function Pest\Laravel\artisan; + +test('user creation command', function () { + artisan('users:create') + ->expectsQuestion('What is your name?', 'Taylor Otwell') + ->expectsQuestion('What is your email?', '[email protected]') + ->expectsConfirmation('Create this user?', 'yes') + ->expectsPromptsInfo('User created successfully!') + ->assertExitCode(0); +}); + +test('displays warnings and errors', function () { + artisan('report:generate') + ->expectsPromptsWarning('This action cannot be undone') + ->expectsPromptsError('Something went wrong') + ->expectsPromptsTable( + headers: ['Name', 'Email'], + rows: [ + ['Taylor Otwell', '[email protected]'], + ['Jason Beggs', '[email protected]'], + ] + ) + ->assertExitCode(0); +}); +``` + +## Best Practices + +### Design Guidelines +- Keep labels concise (under 74 characters for 80-column terminals) +- Use `hint` parameter for additional context +- Set appropriate `default` values when sensible +- Configure `scroll` for lists with many options (default: 5) + +### Validation Strategy +- Use `required: true` for mandatory fields +- Apply Laravel validation rules for standard checks (email, min/max, etc.) +- Use closures for complex business logic validation +- Provide clear, actionable error messages + +### User Experience +- Add placeholders to show expected input format +- Use `pause()` before destructive operations +- Show progress bars for operations taking >2 seconds +- Display informational messages after actions complete +- Group related prompts in forms for better flow + +### Performance +- Use `search()` callbacks with length checks to avoid expensive queries: + ```php + options: fn (string $value) => strlen($value) > 0 + ? User::where('name', 'like', "%{$value}%")->pluck('name', 'id')->all() + : [] + ``` +- Limit database results with pagination or top-N queries +- Cache frequently-accessed option lists +- Use `spin()` for HTTP requests and long operations + +## Common Patterns + +### User Registration Flow +```php +$responses = form() + ->text('Name', required: true, name: 'name') + ->text('Email', validate: ['email' => 'required|email|unique:users'], name: 'email') + ->password('Password', validate: ['password' => 'required|min:8'], name: 'password') + ->submit(); +``` + +### Confirmation Before Destructive Action +```php +$confirmed = confirm( + label: 'Are you sure you want to delete all users?', + default: false, + hint: 'This action cannot be undone.' +); + +if (! $confirmed) { + $this->info('Operation cancelled.'); + return; +} +``` + +### Dynamic Multi-step Form +```php +$responses = form() + ->select('User type', options: ['Regular', 'Admin'], name: 'type') + ->add(function ($responses) { + if ($responses['type'] === 'Admin') { + return password('Admin password', required: true); + } + }, name: 'admin_password') + ->submit(); +``` + +### Batch Processing with Progress +```php +$items = Item::all(); + +$results = progress( + label: 'Processing items', + steps: $items, + callback: function ($item, $progress) { + $progress->hint("Processing: {$item->name}"); + return $this->process($item); + } +); +``` + +## Resources + +### Official Documentation +- Laravel Prompts Documentation: https://laravel.com/docs/12.x/prompts +- Laravel Console Testing: https://laravel.com/docs/12.x/console-tests + +### Platform Support +- **Supported**: macOS, Linux, Windows with WSL +- **Fallback**: Configure fallback behavior for unsupported environments + +## Notes + +- Laravel Prompts is pre-installed in Laravel framework +- Supports Laravel validation rules for easy integration +- Uses terminal control codes for interactive UI +- All prompts return values that can be used immediately +- Forms support revisiting previous prompts with CTRL + U +- Validation runs on every input change for immediate feedback +- Progress bars can be manually controlled or automated + +## Updating + +This skill was generated from the official Laravel Prompts documentation. To refresh with updated information, re-scrape the Laravel documentation site. diff --git a/skills/laravel-prompts/plugin.json b/skills/laravel-prompts/plugin.json new file mode 100644 index 0000000..f834662 --- /dev/null +++ b/skills/laravel-prompts/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "laravel-prompts", + "description": "Interacts with the Laravel Prompts Package for Laravel.", + "version": "1.0.0", + "author": { + "name": "Tim Green", + "email": "rawveg@gmail.com" + }, + "homepage": "https://github.com/rawveg/claude-skills-marketplace", + "repository": "https://github.com/rawveg/claude-skills-marketplace", + "license": "MIT", + "keywords": ["laravel-prompts", "laravel", "Claude Code"], + "category": "productivity", + "strict": false +} diff --git a/skills/laravel-prompts/references/index.md b/skills/laravel-prompts/references/index.md new file mode 100644 index 0000000..2c97016 --- /dev/null +++ b/skills/laravel-prompts/references/index.md @@ -0,0 +1,7 @@ +# Laravel-Prompts Documentation Index + +## Categories + +### Other +**File:** `other.md` +**Pages:** 1 diff --git a/skills/laravel-prompts/references/other.md b/skills/laravel-prompts/references/other.md new file mode 100644 index 0000000..0900602 --- /dev/null +++ b/skills/laravel-prompts/references/other.md @@ -0,0 +1,11 @@ +# Laravel-Prompts - Other + +**Pages:** 1 + +--- + +## Prompts - Laravel 12.x - The PHP Framework For Web Artisans + +**URL:** https://laravel.com/docs/12.x/prompts + +--- diff --git a/skills/laravel/SKILL.md b/skills/laravel/SKILL.md new file mode 100644 index 0000000..5b4b86d --- /dev/null +++ b/skills/laravel/SKILL.md @@ -0,0 +1,521 @@ +--- +name: laravel +description: Laravel v12 - The PHP Framework For Web Artisans +--- + +# Laravel Skill + +Comprehensive assistance with Laravel 12.x development, including routing, Eloquent ORM, migrations, authentication, API development, and modern PHP patterns. + +## When to Use This Skill + +This skill should be triggered when: +- Building Laravel applications or APIs +- Working with Eloquent models, relationships, and queries +- Setting up authentication, authorization, or API tokens +- Creating database migrations, seeders, or factories +- Implementing middleware, service providers, or events +- Using Laravel's built-in features (queues, cache, validation, etc.) +- Troubleshooting Laravel errors or performance issues +- Following Laravel best practices and conventions +- Implementing RESTful APIs with Laravel Sanctum or Passport +- Working with Laravel Mix, Vite, or frontend assets + +## Quick Reference + +### Basic Routing + +```php +// Basic routes +Route::get('/users', [UserController::class, 'index']); +Route::post('/users', [UserController::class, 'store']); + +// Route parameters +Route::get('/users/{id}', function ($id) { + return User::find($id); +}); + +// Named routes +Route::get('/profile', ProfileController::class)->name('profile'); + +// Route groups with middleware +Route::middleware(['auth'])->group(function () { + Route::get('/dashboard', [DashboardController::class, 'index']); + Route::resource('posts', PostController::class); +}); +``` + +### Eloquent Model Basics + +```php +// Define a model with relationships +namespace App\Models; + +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\BelongsTo; + +class Post extends Model +{ + protected $fillable = ['title', 'content', 'user_id']; + + protected $casts = [ + 'published_at' => 'datetime', + ]; + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function comments(): HasMany + { + return $this->hasMany(Comment::class); + } +} +``` + +### Database Migrations + +```php +// Create a migration +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + public function up(): void + { + Schema::create('posts', function (Blueprint $table) { + $table->id(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->string('title'); + $table->text('content'); + $table->timestamp('published_at')->nullable(); + $table->timestamps(); + + $table->index(['user_id', 'published_at']); + }); + } + + public function down(): void + { + Schema::dropIfExists('posts'); + } +}; +``` + +### Form Validation + +```php +// Controller validation +public function store(Request $request) +{ + $validated = $request->validate([ + 'title' => 'required|max:255', + 'content' => 'required', + 'email' => 'required|email|unique:users', + 'tags' => 'array|min:1', + 'tags.*' => 'string|max:50', + ]); + + return Post::create($validated); +} + +// Form Request validation +namespace App\Http\Requests; + +use Illuminate\Foundation\Http\FormRequest; + +class StorePostRequest extends FormRequest +{ + public function rules(): array + { + return [ + 'title' => 'required|max:255', + 'content' => 'required|min:100', + ]; + } +} +``` + +### Eloquent Query Builder + +```php +// Common query patterns +// Eager loading to avoid N+1 queries +$posts = Post::with(['user', 'comments']) + ->where('published_at', '<=', now()) + ->orderBy('published_at', 'desc') + ->paginate(15); + +// Conditional queries +$query = Post::query(); + +if ($request->has('search')) { + $query->where('title', 'like', "%{$request->search}%"); +} + +if ($request->has('author')) { + $query->whereHas('user', function ($q) use ($request) { + $q->where('name', $request->author); + }); +} + +$posts = $query->get(); +``` + +### API Resource Controllers + +```php +namespace App\Http\Controllers\Api; + +use App\Models\Post; +use App\Http\Resources\PostResource; +use Illuminate\Http\Request; + +class PostController extends Controller +{ + public function index() + { + return PostResource::collection( + Post::with('user')->latest()->paginate() + ); + } + + public function store(Request $request) + { + $post = Post::create($request->validated()); + + return new PostResource($post); + } + + public function show(Post $post) + { + return new PostResource($post->load('user', 'comments')); + } + + public function update(Request $request, Post $post) + { + $post->update($request->validated()); + + return new PostResource($post); + } +} +``` + +### API Resources (Transformers) + +```php +namespace App\Http\Resources; + +use Illuminate\Http\Resources\Json\JsonResource; + +class PostResource extends JsonResource +{ + public function toArray($request): array + { + return [ + 'id' => $this->id, + 'title' => $this->title, + 'slug' => $this->slug, + 'excerpt' => $this->excerpt, + 'content' => $this->when($request->routeIs('posts.show'), $this->content), + 'author' => new UserResource($this->whenLoaded('user')), + 'comments_count' => $this->when($this->comments_count, $this->comments_count), + 'published_at' => $this->published_at?->toISOString(), + 'created_at' => $this->created_at->toISOString(), + ]; + } +} +``` + +### Authentication with Sanctum + +```php +// API token authentication setup +// In config/sanctum.php - configure stateful domains + +// Issue tokens +use Laravel\Sanctum\HasApiTokens; + +class User extends Authenticatable +{ + use HasApiTokens; +} + +// Login endpoint +public function login(Request $request) +{ + $credentials = $request->validate([ + 'email' => 'required|email', + 'password' => 'required', + ]); + + if (!Auth::attempt($credentials)) { + return response()->json(['message' => 'Invalid credentials'], 401); + } + + $token = $request->user()->createToken('api-token')->plainTextToken; + + return response()->json(['token' => $token]); +} + +// Protect routes +Route::middleware('auth:sanctum')->group(function () { + Route::get('/user', fn(Request $r) => $r->user()); +}); +``` + +### Jobs and Queues + +```php +// Create a job +namespace App\Jobs; + +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Queue\InteractsWithQueue; + +class ProcessVideo implements ShouldQueue +{ + use InteractsWithQueue, Queueable; + + public function __construct( + public Video $video + ) {} + + public function handle(): void + { + // Process the video + $this->video->process(); + } +} + +// Dispatch jobs +ProcessVideo::dispatch($video); +ProcessVideo::dispatch($video)->onQueue('videos')->delay(now()->addMinutes(5)); +``` + +### Service Container and Dependency Injection + +```php +// Bind services in AppServiceProvider +use App\Services\PaymentService; + +public function register(): void +{ + $this->app->singleton(PaymentService::class, function ($app) { + return new PaymentService( + config('services.stripe.secret') + ); + }); +} + +// Use dependency injection in controllers +public function __construct( + protected PaymentService $payment +) {} + +public function charge(Request $request) +{ + return $this->payment->charge( + $request->user(), + $request->amount + ); +} +``` + +## Reference Files + +This skill includes comprehensive documentation in `references/`: + +- **other.md** - Laravel 12.x installation guide and core documentation + +Use the reference files for detailed information about: +- Installation and configuration +- Framework architecture and concepts +- Advanced features and packages +- Deployment and optimization + +## Key Concepts + +### MVC Architecture +Laravel follows the Model-View-Controller pattern: +- **Models**: Eloquent ORM classes representing database tables +- **Views**: Blade templates for rendering HTML +- **Controllers**: Handle HTTP requests and return responses + +### Eloquent ORM +Laravel's powerful database abstraction layer: +- **Active Record pattern**: Each model instance represents a database row +- **Relationships**: belongsTo, hasMany, belongsToMany, morphMany, etc. +- **Query Builder**: Fluent interface for building SQL queries +- **Eager Loading**: Prevent N+1 query problems with `with()` + +### Routing +Define application endpoints: +- **Route methods**: get, post, put, patch, delete +- **Route parameters**: Required `{id}` and optional `{id?}` +- **Route groups**: Share middleware, prefixes, namespaces +- **Resource routes**: Auto-generate RESTful routes + +### Middleware +Filter HTTP requests: +- **Built-in**: auth, throttle, verified, signed +- **Custom**: Create your own request/response filters +- **Global**: Apply to all routes +- **Route-specific**: Apply to specific routes or groups + +### Service Container +Laravel's dependency injection container: +- **Automatic resolution**: Type-hint dependencies in constructors +- **Binding**: Register class implementations +- **Singletons**: Share single instance across requests + +### Artisan Commands +Laravel's CLI tool: +```bash +php artisan make:model Post -mcr # Create model, migration, controller, resource +php artisan migrate # Run migrations +php artisan db:seed # Seed database +php artisan queue:work # Process queue jobs +php artisan optimize:clear # Clear all caches +``` + +## Working with This Skill + +### For Beginners +Start with: +1. **Installation**: Set up Laravel using Composer +2. **Routing**: Learn basic route definitions in `routes/web.php` +3. **Controllers**: Create controllers with `php artisan make:controller` +4. **Models**: Understand Eloquent basics and relationships +5. **Migrations**: Define database schema with migrations +6. **Blade Templates**: Create views with Laravel's templating engine + +### For Intermediate Users +Focus on: +- **Form Requests**: Validation and authorization in dedicated classes +- **API Resources**: Transform models for JSON responses +- **Authentication**: Implement with Laravel Breeze or Sanctum +- **Relationships**: Master eager loading and complex relationships +- **Queues**: Offload time-consuming tasks to background jobs +- **Events & Listeners**: Decouple application logic + +### For Advanced Users +Explore: +- **Service Providers**: Register application services +- **Custom Middleware**: Create reusable request filters +- **Package Development**: Build reusable Laravel packages +- **Testing**: Write feature and unit tests with PHPUnit +- **Performance**: Optimize queries, caching, and response times +- **Deployment**: CI/CD pipelines and production optimization + +### Navigation Tips +- Check **Quick Reference** for common code patterns +- Reference the official docs at https://laravel.com/docs/12.x +- Use `php artisan route:list` to view all registered routes +- Use `php artisan tinker` for interactive debugging +- Enable query logging to debug database performance + +## Common Patterns + +### Repository Pattern +```php +interface PostRepositoryInterface +{ + public function all(); + public function find(int $id); + public function create(array $data); +} + +class PostRepository implements PostRepositoryInterface +{ + public function all() + { + return Post::with('user')->latest()->get(); + } + + public function find(int $id) + { + return Post::with('user', 'comments')->findOrFail($id); + } +} +``` + +### Action Classes (Single Responsibility) +```php +class CreatePost +{ + public function execute(array $data): Post + { + return DB::transaction(function () use ($data) { + $post = Post::create($data); + $post->tags()->attach($data['tag_ids']); + event(new PostCreated($post)); + return $post; + }); + } +} +``` + +### Query Scopes +```php +class Post extends Model +{ + public function scopePublished($query) + { + return $query->where('published_at', '<=', now()); + } + + public function scopeByAuthor($query, User $user) + { + return $query->where('user_id', $user->id); + } +} + +// Usage +Post::published()->byAuthor($user)->get(); +``` + +## Resources + +### Official Documentation +- Laravel Docs: https://laravel.com/docs/12.x +- API Reference: https://laravel.com/api/12.x +- Laracasts: https://laracasts.com (video tutorials) + +### Community +- Laravel News: https://laravel-news.com +- Laravel Forums: https://laracasts.com/discuss +- GitHub: https://github.com/laravel/laravel + +### Tools +- Laravel Telescope: Debugging and monitoring +- Laravel Horizon: Queue monitoring +- Laravel Debugbar: Development debugging +- Laravel IDE Helper: IDE autocompletion + +## Best Practices + +1. **Use Form Requests**: Separate validation logic from controllers +2. **Eager Load Relationships**: Avoid N+1 query problems +3. **Use Resource Controllers**: Follow RESTful conventions +4. **Type Hints**: Leverage PHP type declarations for better IDE support +5. **Database Transactions**: Wrap related database operations +6. **Queue Jobs**: Offload slow operations to background workers +7. **Cache Queries**: Cache expensive database queries +8. **API Resources**: Transform data consistently for APIs +9. **Events**: Decouple application logic with events and listeners +10. **Tests**: Write tests for critical application logic + +## Notes + +- Laravel 12.x requires PHP 8.2 or higher +- Uses Composer for dependency management +- Includes Vite for asset compilation (replaces Laravel Mix) +- Supports multiple database systems (MySQL, PostgreSQL, SQLite, SQL Server) +- Built-in support for queues, cache, sessions, and file storage +- Excellent ecosystem with first-party packages (Sanctum, Horizon, Telescope, etc.) diff --git a/skills/laravel/plugin.json b/skills/laravel/plugin.json new file mode 100644 index 0000000..69a998c --- /dev/null +++ b/skills/laravel/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "laravel", + "description": "Provides Laravel integration for Claude Code.", + "version": "1.0.0", + "author": { + "name": "Tim Green", + "email": "rawveg@gmail.com" + }, + "homepage": "https://github.com/rawveg/claude-skills-marketplace", + "repository": "https://github.com/rawveg/claude-skills-marketplace", + "license": "MIT", + "keywords": ["laravel", "laravel", "Claude Code"], + "category": "productivity", + "strict": false +} diff --git a/skills/laravel/references/index.md b/skills/laravel/references/index.md new file mode 100644 index 0000000..11562ec --- /dev/null +++ b/skills/laravel/references/index.md @@ -0,0 +1,7 @@ +# Laravel Documentation Index + +## Categories + +### Other +**File:** `other.md` +**Pages:** 1 diff --git a/skills/laravel/references/other.md b/skills/laravel/references/other.md new file mode 100644 index 0000000..58b71df --- /dev/null +++ b/skills/laravel/references/other.md @@ -0,0 +1,11 @@ +# Laravel - Other + +**Pages:** 1 + +--- + +## Installation - Laravel 12.x - The PHP Framework For Web Artisans + +**URL:** https://laravel.com/docs/12.x + +---