PHPackages                             llm/skills - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. llm/skills

ActiveComposer-plugin[Utility &amp; Helpers](/categories/utility)

llm/skills
==========

AI skills discovery and management system for LLM agents

1.4.0(1w ago)212.8k↑342.6%1[1 issues](https://github.com/roxblnfk/skills/issues)3BSD-3-ClausePHPPHP &gt;=8.2CI passing

Since May 13Pushed 1w ago2 watchersCompare

[ Source](https://github.com/roxblnfk/skills)[ Packagist](https://packagist.org/packages/llm/skills)[ Fund](https://boosty.to/roxblnfk)[ RSS](/packages/llm-skills/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (10)Dependencies (10)Versions (14)Used By (3)

llm/skills
==========

[](#llmskills)

Distribute AI Skills as Composer dependencies

[![Support on Boosty](https://camo.githubusercontent.com/eca37b381ee1cc5abb7bbc819eb3792929666505c31ebc775962992648d00b92/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f7374796c653d666f722d7468652d6261646765266c6162656c3d266d6573736167653d53706f6e736f7273686970266c6f676f3d426f6f737479266c6f676f436f6c6f723d776869746526636f6c6f723d253233463135463243)](https://boosty.to/roxblnfk)

A **Composer plugin** that copies AI Skills shipped inside vendor packages into a project-local directory (default `.agents/skills/`).

An *AI Skill* is a directory containing a `SKILL.md` plus any auxiliary files (templates, examples, fixtures). The directory name is the skill's identity; coding-agent tools read `SKILL.md` to learn project-specific instructions, conventions, and recipes.

`llm/skills` distributes those instruction bundles as ordinary Composer dependencies and assembles them in the consumer project — on demand or automatically on `composer install` / `update`.

Install
-------

[](#install)

```
composer require --dev llm/skills
```

[![PHP](https://camo.githubusercontent.com/20a6262d1fb609ed389a0d68d33759633e03591c58fdc926c56bd11079b5bcae/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6c6c6d2f736b696c6c732e7376673f7374796c653d666c61742d737175617265266c6f676f3d706870)](https://packagist.org/packages/llm/skills)[![Latest Version on Packagist](https://camo.githubusercontent.com/d9740fed2dc63bc0fdf0cdd4b177ce7b68f62e06bfab979e9b0abee4b3633e64/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c6c6d2f736b696c6c732e7376673f7374796c653d666c61742d737175617265266c6f676f3d7061636b6167697374)](https://packagist.org/packages/llm/skills)[![License](https://camo.githubusercontent.com/6fa53df94013013dcf335916358c98f3185486a6fc6caa454a5040f78d8f32e3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6c6c6d2f736b696c6c732e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Total Downloads](https://camo.githubusercontent.com/ed1db3b0a0c3ab137cd6327bba106c1c6ffe0b401c6be233a84470e85a0b9a66/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c6c6d2f736b696c6c732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/llm/skills/stats)

Composer will prompt to allow the plugin during install — answer **y**. (For non-interactive setups, pre-allow with `"config": { "allow-plugins": { "llm/skills": true } }` in `composer.json`.)

Then bootstrap your project's config — this is the one command to run first:

```
composer skills:init
```

An interactive wizard walks you through target dir, aliases, trusted vendors, and auto-sync, and writes a `skills.json` you commit alongside `composer.json`. See [Project configuration](#project-configuration) for the full reference. The plugin still works without it — defaults are sensible — but committing an explicit `skills.json` is what makes your skill setup reproducible across the team.

Auto-sync after every `composer install` / `update` is **on by default**, so after `init` you get fresh skills with no further setup. To opt out, set `"auto-sync": false` in `skills.json`; `composer install --no-scripts` also suppresses the auto-run for a single invocation without changing the config.

### Global installation

[](#global-installation)

Install once and use the `skills:*` commands in any project:

```
composer global require llm/skills
```

Then from any project root:

```
composer skills:show
composer skills:update
```

Project-level settings (`target`, `trusted`, `discovery`, …) live in the consumer project's `skills.json` at the project root. See [Project configuration](#project-configuration) for the full reference.

Commands
--------

[](#commands)

```
composer skills:init   [options]                  # alias: skills:i
composer skills:update [...] [options]   # alias: skills:u
composer skills:show   [...] [options]   # alias: skills:s
composer skills:add     [options]          # alias: skills:a

```

`skills:update` copies skills into the target directory. `skills:show` is read-only — it lists every donor, the per-skill sync status, and what is being skipped and why. `skills:init`bootstraps a [`skills.json`](#project-configuration) at the project root and (when `composer.json` carries legacy inline project keys) migrates them out. `skills:add` registers a donor that lives outside Composer (e.g. a GitHub repository) and immediately fetches its skills — see [Remote sources](#remote-sources).

OptionWhereDescription`...`bothRestrict to matching donors. Exact (`acme/foo`) or wildcard (`acme/*`, `*`). Listed packages are treated as **trusted** for this run (see [Trust](#trust)).`--target=PATH`, `-t`bothOverride the configured target directory for this run.`--alias=PATH`updateExtra path mirrored at the target via a junction/symlink (repeatable). Passing `--alias` at all replaces the configured aliases entirely. See [Aliases](#aliases).`--trust=PATTERN`bothTrust an extra pattern for this run (repeatable).`--discovery`bothInclude packages that ship a `skills/` directory but do not declare `extra.skills`.`--from=ID`updateScope the sync to a single provider id (`composer`, `github`, …). See [Remote sources](#remote-sources).`--dry-run`updatePrint actions; no files written.Short flag `-d` for `--discovery` is registered only by the standalone `bin/skills` binary; inside Composer it is reserved for `--working-dir`.

### Examples

[](#examples)

```
composer skills:update                                   # sync everything that is trusted
composer skills:update acme/skills-basic                  # sync one package (implicit trust)
composer skills:update 'acme/*'                           # sync an entire vendor namespace
composer skills:update --discovery                        # also include packages without extra.skills
composer skills:update --alias=.claude/skills             # mirror target via a junction/symlink
composer skills:update --from=github                      # only refresh remote GitHub donors
composer skills:update --dry-run                          # preview, write nothing
composer skills:show                                      # inspect: per-skill status, what is skipped
composer skills:init                                      # create skills.json (migrating inline keys)
composer skills:add acme/skills                           # register a GitHub donor and sync it (github is the default)
composer skills:add acme/skills \
        --skill=code-review --skill=refactor              # narrow a donor to two skills
```

Shipping skills (vendor side)
-----------------------------

[](#shipping-skills-vendor-side)

A donor package declares a directory whose immediate subdirectories are its skills:

```
// vendor/acme/skills-pro/composer.json
{
  "extra": {
    "skills": { "source": "resources/skills" }
  }
}
```

```
acme/skills-pro/
├── composer.json
└── resources/skills/
    ├── refactor/
    │   ├── SKILL.md
    │   └── templates/suggestion.md
    └── migrate/
        └── SKILL.md

```

After `skills:update`, the consumer project gets:

```
/.agents/skills/
├── refactor/{SKILL.md, templates/suggestion.md}
└── migrate/SKILL.md

```

- `source` is relative to the package root.
- Each immediate subdirectory of `source` is one skill, copied recursively.
- Loose files at the root of `source` (e.g. `README.md`) are ignored.
- A package without `extra.skills` is not a donor by default — see [Auto-discovery](#auto-discovery).

Project configuration
---------------------

[](#project-configuration)

Project-level settings live in a dedicated **`skills.json`** at the project root. The file is the single source of truth for everything the plugin does in your project — what to copy, where to put it, who to trust, whether to auto-sync.

```
// /skills.json
{
  "$schema": "https://raw.githubusercontent.com/roxblnfk/skills/master/resources/skills.schema.json",
  "target": ".agents/skills",
  "aliases": [".claude/skills", ".cursor/skills"],
  "trusted": ["acme/*", "myorg/skills-internal"],
  "trusted-replace": false,
  "discovery": false,
  "auto-sync": true,

  "local":  { "composer": true },
  "remote": [
    { "from": "github", "package": "acme/skills", "ref": "^1.2.0" },
    { "from": "github", "package": "team/skills-pack", "ref": "^2",
      "skills": ["code-review", "refactor"] }
  ]
}
```

KeyTypeDefaultDescription`target`string`.agents/skills`Destination directory, relative to the project root.`aliases`string\[\]`[]`Mirror paths (junction/symlink) pointing at `target`. See [Aliases](#aliases).`trusted`string\[\]`[]`Extra trust patterns (see [Trust](#trust)).`trusted-replace`bool`false`When `true`, the built-in trust list and direct-dependency auto-trust are both ignored.`discovery`bool`false`When `true`, auto-discovery is on by default (CLI overrides).`auto-sync`bool`true`Run `skills:update` after `composer install` / `update`. Set to `false` to opt out.`local`object`{}`Per-local-provider on/off map. Keys: `composer` (default `true`), `npm`/`go` (future, default `false`). See [Remote sources](#remote-sources).`remote`object\[\]`[]`Explicit remote donor refs. Managed by `skills:add`; documented in [Remote sources](#remote-sources).`.agents/skills/` is tool-agnostic so Claude Code, Cursor, Aider, … can read the same directory. Redirect to `.claude/skills`, `.cursor/skills`, etc. for single-agent projects.

The fastest way to get a valid `skills.json` is `composer skills:init` (see below). Bootstrap it once and commit it alongside `composer.json`.

### Strict shape

[](#strict-shape)

`skills.json` is **strict**:

- Unknown top-level keys fail the run.
- `$schema` is the only metadata key accepted (and silently stripped from the parsed config).
- A nested `config-file` key is rejected — the file is the config, not a pointer to one.

The PHP mapper is the authoritative validator at runtime; the [`resources/skills.schema.json`](resources/skills.schema.json) document mirrors it for IDE / editor support. A malformed `skills.json` is **fatal**; a malformed `extra.skills` block in a *donor* package is skipped with a `-v` warning so one bad vendor never blocks the rest.

### `skills:init` — bootstrap and migrate

[](#skillsinit--bootstrap-and-migrate)

```
composer skills:init                  # migrate eagerly (same effect as a future skills:update)
composer skills:init --force          # overwrite an existing skills.json
composer skills:init --path=PATH      # non-default location (won't be auto-discovered)
```

`skills:init` is the explicit version of the migration that `skills:update` runs implicitly. It exists for two cases:

- Pre-`skills:update` setup — bootstrap `skills.json` before the first sync.
- Standalone projects (no `composer.json` at cwd) — write a stub `skills.json` with the `$schema` pointer so editors can pick up the schema; nothing else is touched.

Refusal semantics:

- Refuses to overwrite an existing `skills.json` without `--force`.
- Refuses if the inline `extra.skills` block is malformed — fix `composer.json` first, then rerun.
- Refuses if `--path` points at an existing non-file (a directory etc.) with a clear error.

`--path=PATH` honours the project-root containment rule. Subsequent commands only auto-discover `skills.json` at the project root, so a non-default `--path` also emits a notice telling the user to move the file.

Note

**Upgrading from inline `extra.skills`?** Early versions of `llm/skills` kept project settings under `extra.skills` in `composer.json`. That surface is deprecated. Starting with **1.3.0**, the first write-mode run (`skills:update`, `skills:init`, or the `post-update-cmd` auto-sync hook) moves the project keys into `skills.json` automatically and prints a `[migrate]` line. `skills:show` and `post-install-cmd` stay read-only and just emit a one-line notice. Donor-side `extra.skills.source` is never touched.

Aliases
-------

[](#aliases)

A single project often needs the same skills directory available to several coding agents at once — Claude Code at `.claude/skills`, Cursor at `.cursor/skills`, plus an agent-agnostic `.agents/skills`. Copying the same bytes into N places wastes disk and forces them out of sync.

`aliases` keeps **one** real directory (`target`) and creates additional paths as OS-level mirrors:

- **POSIX** — symbolic links via `symlink(2)`.
- **Windows** — directory **junctions** via `mklink /J`. Junctions work without admin/dev-mode privilege, unlike `SeCreateSymbolicLink`. Cross-volume junctions are refused with a non-zero exit; the plugin never silently degrades to a copy.

```
// /skills.json
{
  "target":  ".agents/skills",
  "aliases": [".claude/skills", ".cursor/skills"]
}
```

`skills:update` produces one real `.agents/skills/` plus two link paths pointing at it. Reads through any path see the same files.

### Behaviour

[](#behaviour)

- **Idempotent.** A second run sees the existing link and treats it as already-correct.
- **Non-destructive.** If the alias path already exists as a real directory, the run fails with a non-zero exit and leaves the directory untouched. To convert it, remove the directory manually and re-run — the plugin never destroys user content.
- **Stale aliases not pruned.** Removing an entry from `aliases` does not delete the junction/symlink on disk. Clean it up manually if needed.
- **CLI override is total.** `--alias=PATH` (repeatable) replaces the configured `aliases`for that run — there is no merging.

```
composer skills:update --alias=.claude/skills --alias=.cursor/skills
```

### Git

[](#git)

Alias paths are build artefacts and typically belong in `.gitignore`:

```
.claude/skills
.cursor/skills
```

On Windows, `git status` reads junctions transparently — but committing a junction is rarely what you want, so the ignore line is the safer default.

Trust
-----

[](#trust)

AI skills are Markdown instructions executed by an agent. A malicious package could ship a prompt-injection payload, so the plugin does not copy skills from a donor unless it is **trusted**.

Effective trust list:

```
builtin ∪ project.trusted ∪ --trust= ∪ direct-deps

```

`project.trusted` is the `trusted` array from `skills.json`. `direct-deps` is the set of packages declared under `require` and `require-dev` in the consumer's root `composer.json`. Setting `trusted-replace: true` drops both implicit sources (`builtin` and `direct-deps`) from the union, leaving only project trust and `--trust=` — the explicit-only mode.

PatternMatches`vendor/package`Exact package name.`vendor/*`Any package in that vendor namespace.`*`Every installed package.Bare `vendor` without `/` is rejected as ambiguous.

### Shortcuts

[](#shortcuts)

- **Named on the CLI is implicit trust.** `composer skills:update acme/foo` syncs `acme/foo`without consulting the trust list. Naming a vendor wildcard (`acme/*`) extends the grant to every package matching the pattern.
- **Named is also implicit auto-discovery.** If the named package does not declare `extra.skills`, the plugin still scans its `skills/` directory — discovery is enabled for that package only.
- **Direct dependencies are implicit trust.** A package the consumer chose to depend on (`require` / `require-dev`) does not need a trust pattern: the dependency declaration is already a trust decision. Transitive dependencies are still gated by the trust list. Setting `trusted-replace: true` turns this off for projects that want explicit-only trust.

### Built-in trusted vendors

[](#built-in-trusted-vendors)

Shipped in [`resources/trusted-composer.txt`](resources/trusted-composer.txt); extended by PR. Other registries (npm, go) will ship their own per-ecosystem files when the corresponding local providers land — see [`spec-remote.md`](spec-remote.md) §8.

Remote sources
--------------

[](#remote-sources)

`llm/skills` reads donors from two axes:

- **Local providers** — walk a manifest the project already owns. Today only `composer`; `npm` and `go` are reserved in the vocabulary but ship later.
- **Remote providers** — fetch an explicit ref from a URL (currently GitHub; the format is forward-compatible with GitLab, Bitbucket, npm registry, Go module proxy, private Packagist, `http`/`zip`).

Both axes coexist. When the same package name arrives via both, the **remote entry wins** (you typed it; the transitive Composer pickup is treated as stale) and the displaced donor is logged under `-v`.

### `skills:add` — register a remote donor

[](#skillsadd--register-a-remote-donor)

```
composer skills:add acme/skills                               # latest stable, write "^X.Y.Z" — github is the default
composer skills:add acme/skills --ref=v1.2.3                  # pinned tag
composer skills:add 'acme/skills@main'                        # branch HEAD
composer skills:add https://github.com/acme/skills            # full URL; adapter inferred from host
composer skills:add team/skills --from=gitlab                 # use a different adapter
composer skills:add team/skills \
        --host=https://github.corp.example.com                # GitHub Enterprise
composer skills:add acme/skills \
        --skill=code-review --skill=refactor                  # only these two skills
composer skills:add acme/skills --no-sync                     # only edit skills.json
```

`--from` defaults to `github` for shorthand input (`owner/repo`). Pass it explicitly only when targeting a different adapter, or override it when the URL host is ambiguous. Full URLs still resolve the adapter from the host — `--from` is only consulted as an override.

The command:

1. parses the input via the resolved adapter (currently `github`);
2. resolves the ref — explicit value wins verbatim; without `--ref` the adapter picks the highest stable tag, falling back to the highest prerelease tag, then to the default branch HEAD;
3. downloads the archive into `vendor/llm-skills/cache/...` (gitignored by virtue of vendor);
4. validates that the archive ships a `composer.json` with `extra.skills.source`;
5. upserts the entry into `skills.json` `remote[]` (stable-sorted by `(from, host, package)`, atomic write — falls back to `unlink + rename` on Windows where `rename()` refuses to overwrite an existing destination);
6. runs a single-entry sync so the new skills land in the target right away — same ergonomics as `composer require`. Suppress with `--no-sync`.

OptionDescription``Shorthand `owner/repo`, shorthand with `@ref`, or a full URL.`--from=ID`Adapter id. Required for shorthand; inferred from the URL host when omitted with a full URL.`--host=URL`Override the adapter's default host (GitHub Enterprise, self-hosted GitLab, private Packagist).`--ref=REF`Pin a tag, branch, SHA, or Composer-style constraint (`^1.2.3`). Without this, the cascade above runs.`--skill=NAME`Restrict the donor to a specific skill directory. Repeatable. Names accumulate across consecutive `skills:add` calls. Without the flag, every skill the donor ships is synced.`--no-sync`Skip the automatic single-entry sync after writing `skills.json`.Stored entries look like:

```
{
  "remote": [
    { "from": "github", "package": "acme/skills", "ref": "^1.2.0" },
    { "from": "github", "package": "team/internal-skills",
      "host": "https://github.corp.example.com", "ref": "^1",
      "skills": ["code-review", "refactor"] }
  ]
}
```

The composite key is `(from, host, package | url)`: same triplet = upsert in place, different = append. Manual edits are fine — the next `skills:add` normalises the order.

#### Per-entry skill allowlist

[](#per-entry-skill-allowlist)

A donor often ships more skills than you want in a given project. The optional `skills` field on each `remote[]` entry narrows the donor to a named subset:

- **Absent / omitted** → sync every skill the donor ships (legacy behaviour).
- **Non-empty list of names** → only those skills are copied; the rest are silently skipped.
- **Empty list (`"skills": []`)** → the donor is registered but no skills are pulled from it. Useful for staging a donor before opting into its content or for temporarily disabling a donor without deleting the entry.
- Names that do not exist in the fetched archive emit a `-v` warning (`skill "X" declared in remote.skills but not found in the donor`) so typos surface without aborting the sync.

`skills:add --skill=NAME` is the CLI surface: pass `--skill` repeatedly to build the list. The flag is **additive on upsert** — running `skills:add` again on the same entry adds the new names to whatever was already stored. A follow-up `skills:add` without `--skill` does **not** touch the existing allowlist (whether it was a populated list or an explicit empty one). Removing a name or clearing the allowlist entirely is a manual edit of `skills.json`.

### Authentication

[](#authentication)

Remote adapters reuse Composer's `auth.json` / `COMPOSER_AUTH` plumbing — no new credential surfaces. A GitHub token configured for `composer require` works as-is for `skills:add`.

### Archive safety

[](#archive-safety)

Remote archives are downloaded from a user-configurable `host`, so every zip entry name is validated **before** extraction. Absolute paths (`/foo`, `C:/foo`), `..` segments (`../etc/passwd`), backslash-rooted paths (`\\server\share`), and NUL bytes are rejected as a malformed archive; the fetcher emits a per-ref `-v` warning and never writes to disk. The scratch directory used during extraction is cleaned in a `finally` regardless of success.

### `--from=ID` filter on sync

[](#--fromid-filter-on-sync)

```
composer skills:update --from=composer    # only local Composer donors
composer skills:update --from=github      # only remote GitHub donors
```

The id matches `local.{id}` keys and `remote[].from` values. Each donor's provenance is set at the source: `ComposerProvider` tags `composer`; `RemoteProvider` tags the entry's `from`. The filter is a simple equality check on that tag.

### Local provider toggles

[](#local-provider-toggles)

```
{ "local": { "composer": false } }    // disable Composer discovery entirely
```

`local.composer` defaults to `true` (preserves the pre-`local` behaviour). When set to `false`, transitive Composer packages are no longer scanned — useful when the project wants its donors purely from `remote[]`.

For the full architectural rationale, the version-resolution cascade, the cache layout, and the multi-registry trust model, see [`spec-remote.md`](spec-remote.md).

Auto-discovery
--------------

[](#auto-discovery)

When a package does not declare `extra.skills` but ships a `skills/` directory at its install root, `llm/skills` can still pick up the skills inside. Opt in one of three ways:

- `--discovery` flag on the command line (for a single run);
- `"discovery": true` in `skills.json` (always on);
- Name the package as a positional argument (implicit, per-package — see [Shortcuts](#shortcuts)).

```
acme/skills-undeclared/
├── composer.json   # no extra.skills
└── skills/
    └── auto-skill/SKILL.md

```

```
composer skills:update --discovery            # picks up auto-skill
composer skills:update acme/skills-undeclared # also picks up auto-skill (named ⇒ trust + discovery)
```

Auto-discovered donors still pass through the trust filter unless they were named on the CLI. A junction or symlink that escapes the package root is silently rejected.

Sync behaviour
--------------

[](#sync-behaviour)

- **Non-destructive merge.** Files inside the target directory that the donor does *not* ship are left alone (your local notes survive). Files the donor *does* ship are overwritten — the donor is the source of truth.
- **Idempotent.** Running `skills:update` twice produces the same state with no errors.
- **Transactional on conflicts.** If two donors declare a skill with the same directory name, sync aborts *before* touching the filesystem; nothing is written. Every offending package is listed in the output.
- **Grouped output.** Copied skills are grouped by donor package; trailing `[skip]` and `[hint]` blocks summarise what was left out and how to opt in.

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance97

Actively maintained with recent releases

Popularity33

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

10

Last Release

12d ago

Major Versions

0.3.0 → 1.0.02026-05-14

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/773481?v=4)[Pavel Buchnev](/maintainers/butschster)[@butschster](https://github.com/butschster)

![](https://www.gravatar.com/avatar/110fa17dca123e71e4ef4132d1d6a66d20058a07fc6118e716dd67dd4316e886?d=identicon)[roxblnfk](/maintainers/roxblnfk)

---

Top Contributors

[![roxblnfk](https://avatars.githubusercontent.com/u/4152481?v=4)](https://github.com/roxblnfk "roxblnfk (46 commits)")

---

Tags

aiai-skillsclaude-codecomposercomposer-pluginllmphpdevaiagentsskillsllmclaude-codeai-agentsai-skillsllm-agents

###  Code Quality

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/llm-skills/health.svg)

```
[![Health](https://phpackages.com/badges/llm-skills/health.svg)](https://phpackages.com/packages/llm-skills)
```

###  Alternatives

[vizra/vizra-adk

Vizra Agent Development Kit - A comprehensive Laravel package for building intelligent AI agents.

29431.7k](/packages/vizra-vizra-adk)[cognesy/instructor-php

The complete AI toolkit for PHP: unified LLM API, structured outputs, agents, and coding agent control

317117.1k1](/packages/cognesy-instructor-php)[anilcancakir/laravel-ai-sdk-skills

A skill system for Laravel AI SDK agents. Define reusable AI capabilities with SKILL.md files.

205.2k](/packages/anilcancakir-laravel-ai-sdk-skills)[ardagnsrn/ollama-php

This is a PHP library for Ollama. Ollama is an open-source project that serves as a powerful and user-friendly platform for running LLMs on your local machine. It acts as a bridge between the complexities of LLM technology and the desire for an accessible and customizable AI experience.

21074.5k](/packages/ardagnsrn-ollama-php)[symfony/ai-agent

PHP library for building agentic applications.

31746.8k81](/packages/symfony-ai-agent)[mischasigtermans/laravel-altitude

Claude Code agents for the TALL stack, powered by Laravel Boost

12113.7k](/packages/mischasigtermans-laravel-altitude)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
