Leaf / skill
For Claude Code, Codex, Gemini CLI, Cursor

A backend your agent knows cold.

One command and your coding agent builds with Leaf 5 the way a Leaf developer would. The real API, the right entry point, the conventions, and none of the boilerplate it would otherwise invent.

$npx skills add leafsphp/skill

Synced from leafphp.dev/ai every morning. MIT.

01 · BEHAVIOUR

Behaves like a Leaf dev

Picks the entry point that fits (Basic, Web App, API), reaches for leaf install auth instead of writing JWT by hand, and keeps your project's names.

02 · REFERENCES

Reads the docs on demand

Sixteen reference files, one per area. The agent loads routing or auth or mail when it needs it, so your context stays small and the answers stay right.

03 · PROOF

Proven by a running example

Register, login and a protected route in one file. CI runs it on every push, so what the skill teaches is something that actually works.

Say it in plain words. Get a Leaf app.

This is the prompt, and this is what a Leaf developer (or an agent with the skill) writes for it. SQLite, tokens, validation, 65 lines.

// index.php
db()->connect(['dbtype' => 'sqlite', 'dbname' => __DIR__ . '/app.sqlite']);

auth()->config('token.secret', getenv('AUTH_TOKEN_SECRET'));
auth()->config('unique', ['email']);

auth()->middleware('auth.required', function () {
    response()->exit(['error' => 'You need to be logged in'], 401);
});

app()->post('/register', function () {
    $data = request()->validate([
        'name' => 'string', 'email' => 'email', 'password' => 'min:8',
    ]);

    if (!$data) return response()->exit(request()->errors(), 400);
    if (!auth()->register($data)) return response()->exit(auth()->errors(), 400);

    response()->json(auth()->data(), 201);
});

app()->post('/login', function () {
    $data = request()->validate(['email' => 'email', 'password' => 'string']);

    if (!$data) return response()->exit(request()->errors(), 400);
    if (!auth()->login($data)) return response()->exit(auth()->errors(), 401);

    response()->json(auth()->data());
});

app()->get('/me', ['middleware' => 'auth.required', function () {
    response()->json(auth()->user()->get());
}]);

app()->run();
The prompt
Build me a Leaf 5 API with register, login and a protected /me route. SQLite, tokens, validation on the inputs.

With the skill loaded, the agent lands on auth()->register(), auth()->login() and a named middleware. If it starts writing its own JWT code or a users migration, the skill is not loaded.

Full file, smoke test and CI: examples/auth-api.

Install

The skills CLI is the quick way. Or clone the repo into the folder your agent reads skills from.

01

Add the skill

npx skills add leafsphp/skill, or git clone https://github.com/leafsphp/skill ~/.claude/skills/leaf.

02

Open your agent

It triggers on its own whenever Leaf 5, leaf install, leaf up or a .leaf/CONTEXT.md comes up.

03

Ask for the app

Describe what you want. Run php -S localhost:5500 index.php. That is the whole loop.

AgentPersonalProject
Claude Code~/.claude/skills/leaf/.claude/skills/leaf/
Codex~/.codex/skills/leaf/.codex/skills/leaf/
Gemini CLI~/.gemini/skills/leaf/.gemini/skills/leaf/
Cursor~/.cursor/skills/leaf/.cursor/skills/leaf/

Anything else: tell your assistant to fetch leafphp.dev/ai/SKILL.md before it starts. New Leaf MVC apps already ship an AGENTS.md that points here.