Install and manage skill plugins in Laravel applications
Install and manage skill plugins in a Laravel application. Skills are cloned
from Git repositories into a local directory and validated against a
skill.json manifest.
Use it from the console, or drive the SkillManager directly from your own
code.
$skill = app(SkillManager::class)->install('https://github.com/user/example-skill.git'); // ['name' => 'example-skill', 'path' => '/app/.agents/skills/example-skill']Contents
| Dependency | Version |
|---|---|
| PHP | 8.2+ |
| Laravel | 11, 12, or 13 |
git |
available on PATH |
composer require shadman/laravel-skills
The service provider is auto-discovered. Publish the config only if you need to change the defaults:
php artisan vendor:publish --tag=skills-configConsole commands
| Command | Description |
|---|---|
skill:install {repo} |
Clone and validate a skill |
skill:list |
Show installed skills and their validity |
skill:uninstall {name} |
Delete an installed skill |
php artisan skill:install https://github.com/user/example-skill.git
php artisan skill:list
php artisan skill:uninstall example-skill
php artisan skill:uninstall example-skill --force # skip confirmation
skill:uninstall prompts before deleting. Pass --force in scripts and CI.
Resolve SkillManager from the container. It is registered as a singleton and
reads its path and timeout from config:
use Shadman\LaravelSkills\Managers\SkillManager; $manager = app(SkillManager::class);
Or construct it directly to override both:
$manager = new SkillManager('/custom/skills/path', cloneTimeout: 300);
install(string $repo): arrayClones $repo, validates its manifest, and returns the installed skill. The URL
must be https:// or git@ — see Security.
$skill = $manager->install('https://github.com/user/example-skill.git'); // [ // 'name' => 'example-skill', // 'path' => '/app/.agents/skills/example-skill', // ]
The skill name is derived from the last path segment of the URL, minus any
.git suffix. If the clone fails, times out, or the manifest is invalid, the
partial directory is removed before the exception is thrown.
list(): arrayReturns every directory under the skills path, valid or not, so you can surface
broken installs rather than hiding them. Returns [] when the directory does
not exist.
foreach ($manager->list() as $skill) { $skill['name']; // 'example-skill' $skill['path']; // '/app/.agents/skills/example-skill' $skill['valid']; // bool — manifest present and well-formed $skill['manifest']; // decoded skill.json, or null when unreadable }
manifest is the full decoded file, so any extra keys your skills define
(version, description, and so on) are available here.
uninstall(string $name): voidRecursively deletes an installed skill. Throws if $name is not installed, or
is not a valid skill name.
$manager->uninstall('example-skill');
validateManifest(string $path): boolWhether the directory holds a skill.json with a non-empty name and
provider.
$manager->validateManifest('/app/.agents/skills/example-skill'); // true
extractName(string $repo): stringThe skill name a given URL resolves to, without cloning anything. Throws if the URL yields no usable name.
$manager->extractName('https://github.com/user/example-skill.git'); // 'example-skill'Configuration
// config/skills.php return [ // Where cloned skills are stored. 'path' => base_path('.agents/skills'), // Max seconds a `git clone` may run before it is killed. 'clone_timeout' => 120, ];
The skills directory is created on first install.
Manifest formatEach skill repository must contain a skill.json at its root with at least a
name and a provider:
{
"name": "example-skill",
"provider": "anthropic"
}
Additional keys are preserved and returned in list(). A clone whose manifest
is missing or malformed is deleted rather than left half-installed.
mary-ui-skill is a working
skill you can install as-is:
php artisan skill:install https://github.com/shadmanshaikh/mary-ui-skill.git php artisan skill:list
+---------------+-------+-------------------------------------+
| Name | Valid | Path |
+---------------+-------+-------------------------------------+
| mary-ui-skill | Yes | /app/.agents/skills/mary-ui-skill |
+---------------+-------+-------------------------------------+
How it is laid outA skill is a plain Git repository. Only skill.json is required; everything
else is yours to organise:
mary-ui-skill/
├── skill.json # required manifest
├── README.md
├── docs/
│ ├── COMPONENT_REFERENCE.md
│ ├── MARY_UI_GUIDE.md
│ └── PATTERNS.md
└── src/
└── SkillServiceProvider.php
Its manifest carries the two required keys plus its own metadata:
{
"name": "mary-ui-skill",
"version": "1.0.0",
"description": "Mary UI components, patterns, and best practices for Laravel Livewire applications",
"author": "shadman",
"triggers": [
"file.created",
"component.created",
"livewire.component"
],
"requiredEnv": [],
"provider": "Skills\\MaryUI\\SkillServiceProvider"
}
Reading a skill's metadataEvery key you add is returned by list(), so custom fields such as triggers
are available to your own code:
use Shadman\LaravelSkills\Managers\SkillManager; $skills = app(SkillManager::class)->list(); foreach ($skills as $skill) { $skill['manifest']['version']; // '1.0.0' $skill['manifest']['triggers']; // ['file.created', 'component.created', ...] }Creating your own
mkdir my-skill && cd my-skill git init cat > skill.json <<'JSON' { "name": "my-skill", "provider": "anthropic", "version": "1.0.0", "description": "What this skill does" } JSON git add -A && git commit -m "Initial skill" git remote add origin https://github.com/you/my-skill.git git push -u origin main
Then install it by URL. The directory name comes from the repository name, so
my-skill.git installs to .agents/skills/my-skill.
Error handlingNote This package clones and validates skills; it does not autoload or boot them. A
providervalue is stored as metadata and is not registered with Laravel's container. Wiring a skill's code into your application is left to you.
Every failure path throws RuntimeException with a message safe to show the
user, so a single catch covers the API:
use RuntimeException; try { $manager->install($url); } catch (RuntimeException $e) { report($e); return back()->withErrors($e->getMessage()); }
| Condition | Message |
|---|---|
URL is not https:// or git@ |
Repository must be an https:// ... |
| No usable name in the URL | Cannot derive a valid skill name ... |
| Skill directory already exists | Skill "x" already installed. |
git clone failed |
Failed to clone repository: ... |
Clone exceeded clone_timeout |
Timed out cloning "x" after 120s. |
| Manifest missing or malformed | Invalid skill: missing or ... |
| Skills directory not creatable | Could not create skills directory: |
| Uninstalling something absent | Skill "x" is not installed. |
The console commands catch these and return a non-zero exit code.
Securityinstall() runs git clone on the URL you provide. Two guards apply:
https:// and git@. This blocks git
transports such as ext::, which execute arbitrary shell commands, and
rejects arguments beginning with - that git would otherwise parse as
options rather than as a URL.[A-Za-z0-9._-]+, so a crafted URL
cannot traverse out of the configured skills directory.Installing a skill executes nothing on its own, but it does place third-party code inside your project, and there is no signature or checksum verification. Only install skills from sources you trust, and review them as you would any other dependency.
If you find a security issue, please report it privately by email rather than opening a public issue.
Testingcomposer install vendor/bin/phpunit
The suite shells out to git, creating throwaway repositories under the system
temp directory, so git must be on your PATH.
MIT. See LICENSE.md.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | risetechapps/api-key-for-laravel | 0 | 100 | 03-08-2026 |
| 2 | sharpapi/laravel-invoice-manager | 0 | 19.5 | 03-08-2026 |
| 3 | ratts/rih | 0 | 10 | 03-08-2026 |
| 4 | mitantsoa1/metrics-dash-laravel | 0 | 16.67 | 03-08-2026 |
| 5 | apavliukov/laravel-devtools | 0 | 23.93 | 03-08-2026 |
| 6 | daite/laravel-procedures | 0 | 19.09 | 03-08-2026 |
| 7 | anjan-talukdar/laravel-gst-invoice | 0 | 19.93 | 03-08-2026 |
| 8 | expertapps/laravel-abac | 0 | 30 | 03-08-2026 |
| 9 | shelfwatch/shelfwatch | 0 | 10 | 03-08-2026 |
| 10 | djeventplannerhub/djep-php-sdk | 0 | 18.33 | 03-08-2026 |