Token导航 LogoToken导航

Agent Skill · 前端设计

saloon-for-laravel(saloon FOR Laravel 命令行)

saloon-for-laravel 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

saloon-for-laravel 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描有提醒项,按安装量在前端设计类的 10,216 个 Skill 里排第 8,773。

总安装 261周安装 11GitHub Stars 公开资料未说明下载 92核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:saloon-for-laravel(saloon FOR Laravel 命令行)
来源仓库:https://github.com/whoami15/claude-code-laravel-skills
仓库路径:skills/saloon-for-laravel
安装命令:
npx skills add https://github.com/whoami15/claude-code-laravel-skills --skill saloon-for-laravel
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/whoami15/claude-code-laravel-skills --skill saloon-for-laravel

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。适合围绕仓库状态、代码变更或协作事项进行整理。可结合来源仓库和原始 README 继续核验具体用法。安装前建议确认权限范围和维护状态。saloon-for-laravel 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

注意是否会触发联网、命令执行或文件读写。

来源仓库内路径:skills/saloon-for-laravel

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/whoami15/claude-code-laravel-skills --skill sa…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

saloon-for-laravel 怎么安装?

在终端执行 npx skills add https://github.com/whoami15/claude-code-laravel-skills --skill saloon-for-l…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

saloon-for-laravel 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

saloon-for-laravel 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

saloon-for-laravel 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

saloon-for-laravel 用的人多吗?

公开数据是累计安装 261 次,近一周安装 11 次,下载 92 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

saloon-for-laravel 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
saloon-for-laravel

saloon FOR Laravel 命令行 · 本页

261—接触敏感数据未明确有提醒

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Saloon for Laravel

When to use this skill

Use this skill when working with SaloonPHP in a Laravel 11+ application:

  • Integrating with third-party APIs (REST, JSON, XML)
  • Building API connectors, requests, and handling responses
  • Authenticating API requests (token, basic, OAuth2, custom)
  • Sending request bodies (JSON, form, multipart, XML)
  • Testing API integrations with mocking and faking
  • Implementing pagination, rate limiting, caching, or retries
  • Building reusable SDKs for APIs
  • Working with DTOs from API responses

Core Concepts

  • Connectors define the API base URL and shared configuration (headers, auth, middleware).
  • Requests define individual endpoints, HTTP methods, and request-specific data.
  • Responses provide a rich interface for reading status, headers, and parsed body data.
  • Connectors send Requests and return Responses: $connector->send($request).
  • Use Artisan commands to generate classes — never create them manually from scratch.
  • Store integration classes in app/Http/Integrations/{ServiceName}/ (configurable in config/saloon.php).

Installation

composer require saloonphp/laravel-plugin

This installs both saloonphp/saloon (core) and the Laravel integration. Publish the config file:

php artisan vendor:publish --tag=saloon-config

Optional plugins (install as needed):

composer require saloonphp/pagination-plugin   # Paginated API responses
composer require saloonphp/cache-plugin         # Response caching
composer require saloonphp/rate-limit-plugin    # Rate limit handling
composer require saloonphp/xml-wrangler         # XML reading/writing

File Structure

app/Http/Integrations/
└── Acme/
    ├── AcmeConnector.php
    ├── Requests/
    │   ├── GetUserRequest.php
    │   ├── ListProjectsRequest.php
    │   └── CreateProjectRequest.php
    ├── Responses/
    │   └── AcmeResponse.php
    └── Data/
        └── UserDTO.php

Creating Connectors

Generate with Artisan:

php artisan saloon:connector Acme AcmeConnector

A connector defines the base URL and shared configuration:

namespace App\Http\Integrations\Acme;

use Saloon\Http\Connector;
use Saloon\Traits\Plugins\AcceptsJson;
use Saloon\Traits\Plugins\AlwaysThrowOnErrors;

class AcmeConnector extends Connector
{
    use AcceptsJson;
    use AlwaysThrowOnErrors;

    public function __construct(
        protected readonly string $token,
    ) {}

    public function resolveBaseUrl(): string
    {
        return config('services.acme.base_url');
    }

    protected function defaultHeaders(): array
    {
        return [
            'Authorization' => 'Bearer ' . $this->token,
        ];
    }
}

Creating Requests

Generate with Artisan:

php artisan saloon:request Acme GetUserRequest

Define the HTTP method and endpoint:

namespace App\Http\Integrations\Acme\Requests;

use Saloon\Enums\Method;
use Saloon\Http\Request;

class GetUserRequest extends Request
{
    protected Method $method = Method::GET;

    public function __construct(
        protected readonly string $username,
    ) {}

    public function resolveEndpoint(): string
    {
        return '/users/' . $this->username;
    }
}

Request Body Data

Implement HasBody interface with a body trait on the request:

use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Traits\Body\HasJsonBody;

class CreateProjectRequest extends Request implements HasBody
{
    use HasJsonBody;

    protected Method $method = Method::POST;

    public function __construct(
        protected readonly string $name,
        protected readonly bool $private = false,
    ) {}

    public function resolveEndpoint(): string
    {
        return '/projects';
    }

    protected function defaultBody(): array
    {
        return [
            'name' => $this->name,
            'private' => $this->private,
        ];
    }
}

Available body traits (each requires implementing HasBody):

TraitUse Case
HasJsonBodyJSON payloads (application/json)
HasFormBodyForm data (application/x-www-form-urlencoded)
HasMultipartBodyFile uploads (multipart/form-data)
HasXmlBodyXML payloads
HasStringBodyRaw string body
HasStreamBodyStream/binary body

Sending Requests

$connector = new AcmeConnector(token: config('services.acme.token'));
$request = new GetUserRequest('johndoe');

$response = $connector->send($request);

Using dependency injection in a controller:

class UserController extends Controller
{
    public function show(string $username, AcmeConnector $connector)
    {
        $response = $connector->send(new GetUserRequest($username));

        return $response->json();
    }
}

Register the connector in a service provider for DI:

// AppServiceProvider::register()
$this->app->bind(AcmeConnector::class, function () {
    return new AcmeConnector(token: config('services.acme.token'));
});

Handling Responses

$response = $connector->send($request);

// Status checks
$response->successful();     // 200-299
$response->ok();             // 200
$response->failed();         // 400+
$response->status();         // int

// Reading data
$response->json();           // array
$response->json('user.name'); // nested key access
$response->object();         // stdClass
$response->collect();        // Illuminate\Support\Collection
$response->body();           // raw string

// Headers
$response->headers()->all();
$response->header('Content-Type');

// Error handling
$response->throw();          // throw if failed
$response->onError(fn ($response) => logger()->error('API failed', [
    'status' => $response->status(),
]));

Authentication

Built-in authenticators

use Saloon\Http\Auth\TokenAuthenticator;
use Saloon\Http\Auth\BasicAuthenticator;
use Saloon\Http\Auth\QueryAuthenticator;
use Saloon\Http\Auth\HeaderAuthenticator;

// Bearer token (most common)
$connector->authenticate(new TokenAuthenticator('my-api-token'));

// Basic auth
$connector->authenticate(new BasicAuthenticator('user', 'password'));

// Query parameter auth
$connector->authenticate(new QueryAuthenticator('api_key', 'my-key'));

// Custom header
$connector->authenticate(new HeaderAuthenticator('my-token', 'X-API-Key'));

Default authentication on a connector

class AcmeConnector extends Connector
{
    public function __construct(protected readonly string $token) {}

    protected function defaultAuth(): TokenAuthenticator
    {
        return new TokenAuthenticator($this->token);
    }
}

Error Handling

Use AlwaysThrowOnErrors to throw exceptions automatically on failed responses:

use Saloon\Traits\Plugins\AlwaysThrowOnErrors;

class AcmeConnector extends Connector
{
    use AlwaysThrowOnErrors;
}

Catch specific exceptions:

use Saloon\Exceptions\Request\RequestException;
use Saloon\Exceptions\Request\ClientException;      // 4xx
use Saloon\Exceptions\Request\ServerException;      // 5xx
use Saloon\Exceptions\Request\FatalRequestException; // network failure

try {
    $response = $connector->send($request);
} catch (ClientException $e) {
    // 4xx error — $e->getResponse() gives the Response object
} catch (ServerException $e) {
    // 5xx error
} catch (FatalRequestException $e) {
    // Connection failure, timeout, etc.
}

Custom failure logic on a connector or request:

public function hasRequestFailed(Response $response): ?bool
{
    return $response->json('success') === false;
}

DTOs (Data Transfer Objects)

Implement createDtoFromResponse on a request to cast responses:

use Saloon\Http\Request;
use Saloon\Http\Response;

class GetUserRequest extends Request
{
    // ...

    public function createDtoFromResponse(Response $response): UserDTO
    {
        return new UserDTO(
            name: $response->json('name'),
            email: $response->json('email'),
            avatar: $response->json('avatar_url'),
        );
    }
}

Then use it:

$user = $connector->send(new GetUserRequest('johndoe'))->dto();
$user = $connector->send(new GetUserRequest('johndoe'))->dtoOrFail();

Middleware

Add middleware on connectors or requests to modify the request/response pipeline:

class AcmeConnector extends Connector
{
    public function __construct()
    {
        // Request middleware
        $this->middleware()->onRequest(function (PendingRequest $pendingRequest) {
            $pendingRequest->headers()->add('X-Request-ID', Str::uuid()->toString());
        });

        // Response middleware
        $this->middleware()->onResponse(function (Response $response) {
            logger()->info('Acme API responded', ['status' => $response->status()]);
        });
    }
}

Use the boot method for one-time setup:

public function boot(PendingRequest $pendingRequest): void
{
    $pendingRequest->config()->add('timeout', 60);
}

Testing with Saloon Facade

The Laravel plugin provides a Saloon facade for fluent test mocking:

use Saloon\Laravel\Facades\Saloon;
use Saloon\Http\Faking\MockResponse;

it('fetches a user from the API', function () {
    Saloon::fake([
        GetUserRequest::class => MockResponse::make(
            body: ['name' => 'Sam', 'email' => 'sam@example.com'],
            status: 200,
        ),
    ]);

    $response = $this->get('/api/users/johndoe');

    $response->assertOk();

    Saloon::assertSent(GetUserRequest::class);
    Saloon::assertSentCount(1);
});

Sequence responses

Saloon::fake([
    GetUserRequest::class => MockResponse::sequence([
        MockResponse::make(['attempt' => 1], 500),
        MockResponse::make(['attempt' => 2], 200),
    ]),
]);

Assertions

Saloon::assertSent(GetUserRequest::class);
Saloon::assertSent(fn (Request $request) => $request->resolveEndpoint() === '/users/johndoe');
Saloon::assertNotSent(DeleteUserRequest::class);
Saloon::assertSentCount(2);
Saloon::assertNothingSent();

Prevent stray requests

Ensure all API requests are mocked in tests:

Saloon::fake();
// or
Saloon::allowStrayRequests();

Retry Logic

Set retry properties on connectors or requests:

class AcmeConnector extends Connector
{
    protected int $tries = 3;
    protected int $retryInterval = 500;           // milliseconds
    protected bool $useExponentialBackoff = true;
    protected bool $throwOnMaxTries = true;

    public function handleRetry(FatalRequestException|RequestException $exception, Request $request): bool
    {
        // Return false to stop retrying
        if ($exception instanceof RequestException && $exception->getResponse()->status() === 422) {
            return false;
        }

        return true;
    }
}

Pagination

Install the pagination plugin:

composer require saloonphp/pagination-plugin

Implement the HasPagination interface on your connector:

use Saloon\Http\Connector;
use Saloon\PaginationPlugin\PagedPaginator;
use Saloon\PaginationPlugin\Contracts\HasPagination;

class AcmeConnector extends Connector implements HasPagination
{
    public function paginate(Request $request): PagedPaginator
    {
        return new class(connector: $this, request: $request) extends PagedPaginator
        {
            protected function isLastPage(Response $response): bool
            {
                return empty($response->json('next_page_url'));
            }

            protected function getPageItems(Response $response, Response $originalResponse): array
            {
                return $response->json('data');
            }
        };
    }
}

Use the paginator:

$paginator = $connector->paginate(new ListProjectsRequest);

foreach ($paginator as $response) {
    $projects = $response->json('data');
}

// Or collect all items
$allProjects = $paginator->collect()->all();

Available paginator types: PagedPaginator, OffsetPaginator, CursorPaginator.

Rate Limiting

Install the rate limit plugin:

composer require saloonphp/rate-limit-plugin

Add rate limiting to your connector:

use Saloon\Http\Connector;
use Saloon\RateLimitPlugin\Contracts\RateLimitStore;
use Saloon\RateLimitPlugin\Limit;
use Saloon\RateLimitPlugin\Stores\LaravelCacheStore;
use Saloon\RateLimitPlugin\Traits\HasRateLimits;

class AcmeConnector extends Connector
{
    use HasRateLimits;

    protected function resolveLimits(): array
    {
        return [
            Limit::allow(5000)->everyHour(),
        ];
    }

    protected function resolveRateLimitStore(): RateLimitStore
    {
        return new LaravelCacheStore(cache()->store());
    }
}

Caching Responses

Install the cache plugin:

composer require saloonphp/cache-plugin

Add caching to a request:

use Saloon\CachePlugin\Contracts\Cacheable;
use Saloon\CachePlugin\Contracts\Driver;
use Saloon\CachePlugin\Drivers\LaravelCacheDriver;
use Saloon\CachePlugin\Traits\HasCaching;
use Saloon\Http\Request;

class GetUserRequest extends Request implements Cacheable
{
    use HasCaching;

    public function resolveCacheDriver(): Driver
    {
        return new LaravelCacheDriver(cache()->store());
    }

    public function cacheExpiryInSeconds(): int
    {
        return 3600; // 1 hour
    }
}

Concurrency & Pools

Send multiple requests concurrently:

use Saloon\Http\Response;

$pool = $connector->pool(
    requests: [
        new GetUserRequest('alice'),
        new GetUserRequest('bob'),
        new GetUserRequest('charlie'),
    ],
    concurrency: 5,
    responseHandler: function (Response $response, int $key) {
        logger()->info('User fetched', ['data' => $response->json('name')]);
    },
    exceptionHandler: function (Exception $exception, int $key) {
        logger()->error('Request failed', ['key' => $key]);
    },
);

$pool->send()->wait();

OAuth2 Authentication

Create an OAuth2 connector:

php artisan saloon:connector Acme AcmeOAuthConnector
use Saloon\Http\Connector;
use Saloon\Http\Auth\AccessTokenAuthenticator;
use Saloon\Traits\OAuth2\AuthorizationCodeGrant;

class AcmeOAuthConnector extends Connector
{
    use AuthorizationCodeGrant;

    public function resolveBaseUrl(): string
    {
        return config('services.acme.base_url');
    }

    protected function resolveAccessTokenUrl(): string
    {
        return config('services.acme.base_url') . '/oauth/token';
    }

    protected function resolveAuthorizationUrl(): string
    {
        return config('services.acme.base_url') . '/oauth/authorize';
    }
}

Usage in a controller:

// Redirect to OAuth provider
public function redirect(AcmeOAuthConnector $connector)
{
    return $connector->getAuthorizationUrl(
        scopes: ['read', 'write'],
        state: session()->get('state'),
    );
}

// Handle callback
public function callback(Request $request, AcmeOAuthConnector $connector)
{
    $authenticator = $connector->getAccessToken(
        code: $request->query('code'),
    );

    // Store for later — use encrypted cast on your model
    $user->update(['acme_token' => $authenticator]);
}

Store OAuth tokens with the provided Eloquent cast:

use Saloon\Laravel\Casts\EncryptedOAuthAuthenticatorCast;

class User extends Authenticatable
{
    protected function casts(): array
    {
        return [
            'acme_token' => EncryptedOAuthAuthenticatorCast::class,
        ];
    }
}

Building SDKs

Organize connector methods as a clean SDK interface:

class AcmeConnector extends Connector
{
    public function getUser(string $username): Response
    {
        return $this->send(new GetUserRequest($username));
    }

    public function listProjects(string $username): Response
    {
        return $this->send(new ListProjectsRequest($username));
    }

    public function createProject(string $name, bool $private = false): Response
    {
        return $this->send(new CreateProjectRequest($name, $private));
    }
}

Usage becomes expressive:

$acme = new AcmeConnector(token: config('services.acme.token'));

$user = $acme->getUser('johndoe')->dto();
$projects = $acme->listProjects('johndoe')->collect('data');

Telescope & Pulse Integration

Use the Laravel HTTP sender for Telescope and Pulse visibility:

// config/saloon.php
'default_sender' => \Saloon\Laravel\HttpSender::class,

Common Pitfalls

  • Forgetting to implement HasBody interface when sending request body data.
  • Not using Artisan commands (saloon:connector, saloon:request) to generate classes.
  • Using the wrong HTTP method enum — always use Saloon\Enums\Method.
  • Forgetting to install saloonphp/pagination-plugin for pagination (required in v3).
  • Not setting HttpSender in config when Telescope or Pulse visibility is needed.
  • Not mocking all requests in tests — use Saloon::fake() to prevent stray requests.

平台分布

Codex

35.81%
按下载量换算33

Claude

31.55%
按下载量换算29

Cursor

18.48%
按下载量换算17

Gemini CLI

9.52%
按下载量换算9

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills