Laravel Best Practices
anonaddy/anonaddy
Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code.
Manage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js…
The automated check flagged lines worth reading first. See the safety section below.
$ npx skills add liberusoftware/real-estate-laravel --skill lerd -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install liberusoftware/real-estate-laravel lerd --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/liberusoftware/real-estate-laravel.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/lerd .claude/skills/lerd && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "lerd" agent skill from https://github.com/liberusoftware/real-estate-laravel/tree/main/.claude/skills/lerd into .claude/skills/lerd/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lerd", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/liberusoftware/real-estate-laravel/tree/main/.claude/skills/lerdType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add liberusoftware/real-estate-laravel --skill lerd -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install liberusoftware/real-estate-laravel lerd --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/liberusoftware/real-estate-laravel.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/lerd .agents/skills/lerd && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "lerd" agent skill from https://github.com/liberusoftware/real-estate-laravel/tree/main/.claude/skills/lerd into .agents/skills/lerd/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lerd", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add liberusoftware/real-estate-laravel --skill lerd -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install liberusoftware/real-estate-laravel lerd --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/liberusoftware/real-estate-laravel.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/lerd .cursor/skills/lerd && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "lerd" agent skill from https://github.com/liberusoftware/real-estate-laravel/tree/main/.claude/skills/lerd into .cursor/skills/lerd/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lerd", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/liberusoftware/real-estate-laravel.git --path .claude/skills/lerd--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add liberusoftware/real-estate-laravel --skill lerd -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install liberusoftware/real-estate-laravel lerd --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/liberusoftware/real-estate-laravel.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/lerd .gemini/skills/lerd && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "lerd" agent skill from https://github.com/liberusoftware/real-estate-laravel/tree/main/.claude/skills/lerd into .gemini/skills/lerd/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lerd", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install liberusoftware/real-estate-laravel lerdInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add liberusoftware/real-estate-laravel --skill lerd -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/liberusoftware/real-estate-laravel.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/lerd .github/skills/lerd && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "lerd" agent skill from https://github.com/liberusoftware/real-estate-laravel/tree/main/.claude/skills/lerd into .github/skills/lerd/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lerd", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add liberusoftware/real-estate-laravel --skill lerd -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install liberusoftware/real-estate-laravel lerd --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/liberusoftware/real-estate-laravel.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/lerd .opencode/skills/lerd && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "lerd" agent skill from https://github.com/liberusoftware/real-estate-laravel/tree/main/.claude/skills/lerd into .opencode/skills/lerd/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lerd", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
lerdManage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js…
Lerd is an agent skill from liberusoftware/real-estate-laravel. Manage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js versions, and inspect site status. Also the way to diagnose and optimize a slow site: find N+1 and slow queries, read per-site response-time and slow-route timings, profile requests, and run site health checks, from real captured traffic rather than reading code.
Its SKILL.md is about 7.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs, covering Backend development, MCP servers and Query optimization. It works with PHP, Laravel, Node.js and npm. The repository describes itself as: Real Estate / Estate Agent, solution for your Property Agency. Application written in Laravel 13 / PHP 8.5 using Filament 5. Support for Rightmove, Zoopla, OnTheMarket. The licence is MIT.
Read from SKILL.md and the folder at commit 8d7119e. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
npmcomposerpnpmyarnnvmnodegitFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use npm, pnpm, yarn and git, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
APP_KEYSTRIPE_SECRETSTRIPE_SECRET_KEYSTRIPE_API_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Lerd loads about 7.8k tokens when it runs. Until then it costs about 117 tokens; SKILL.md has 4,150 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found patterns that need a careful read before installing.
red sites); `vendor/`, `node_modules/`, `.env` are seeded from the main checkout. `.lerd.yaml` `env_overrides` declares- `env` returns the recommended `.env` connection keys; `expose` publishes an extra `host:container` port...]` or `all: true`) and repoints each `.env`; source data is left intact#### `env` — .env management- `check` compares `.env` against `.env.example`rride` manages the personal, gitignored `.env.lerd_override` (its `set` KEY=VALUE win over lerd defaults; `LERD_EXTERNAL- Stripe secret is read from `.env` (STRIPE_SECRET / STRIPE_SECRET_KEY / STRIPE_API_KEY); `stripe_config` sets webhook_ph-agent container and loads the host's `~/.ssh/id_*` (or named keys) so passphrase-protected keys work in the FPM contaitouches nginx, domains, certificates or `.env`. This is not the same thing as the `site` tool's `group_*` actions, which`secured`); (3) configure the project's `.env` with service hosts (`lerd-mysql`, etc.) and start needed services via `seAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from liberusoftware/real-estate-laravel at commit 8d7119e, republished under its MIT licence (© liberusoftware). 4,150 words, ~7,826 tokens.
.claude/skills/lerd/SKILL.md (or your agent's skills folder).This project runs on lerd, a Podman-based PHP development environment. It is framework-agnostic: Laravel, Symfony, WordPress, Drupal, Magento, CakePHP and any custom framework are all driven by a framework definition (YAML), never by lerd hardcoding a framework's name. The lerd MCP server is available — use it to manage the environment without leaving the chat.
The MCP surface is twelve grouped tools, each driven by an action argument: site, service, db, env, runtime, worker, exec, framework, diag, logs, worktree, workspace. Always pass action. Most actions also accept an optional path that defaults to the directory the assistant was opened in (then LERD_SITE_PATH if set), so you can usually omit it. Start by calling site with action: "list" to discover sites.
lerd-php<version>-fpm (e.g. lerd-php84-fpm); each container includes composer and node/npm; the PHP version is resolved from .lerd.yaml → .php-version → composer.json require.php constraint (matched against installed versions) → global default*.test domains to the correct PHP-FPM containernode.manager + node.nvm_dir; node:manager/dashboard; nvm keeps PATH, fnm uses shims); per-project version via a .node-version file. The package manager is the project's, not lerd's: a packageManager pin in package.json wins, then the lockfile (pnpm-lock.yaml → pnpm, yarn.lock → yarn, bun.lock* → bun, else npm). pnpm and yarn run through corepack, and installs use the manager's frozen-lockfile mode (pnpm install --frozen-lockfile, yarn install --immutable, npm ci). Never assume npm run dev/npm ci — the worker command and the setup steps follow the detected managerlerd-<worker>-<sitename>; commands are defined per-framework in YAML; Laravel Horizon is auto-detected from composer.json and replaces the queue toggle when installed; Laravel ships with a vite host worker that runs the project's dev script on the host for HMR, through whichever package manager the project pins; workers and setup commands support optional check (file or composer) for conditional visibility; workers with conflicts_with auto-stop conflicting workers on start. Per-worker flags: host: true (run on host via the version manager instead of in FPM container — HMR-sensitive Node tools), per_worktree: true (worker runs independently per worktree under lerd-<worker>-<site>-<branch>), replaces_build: true (worker provides asset manifest while running, so a worktree add skips the static npm run build step when this worker is opted in).lerd.yaml custom_workers) or globally (~/.config/lerd/frameworks/<name>.yaml); use the worker tool's add/remove actions — both survive framework store updatesframework action: "setup"; Laravel has built-in storage:link/migrate/db:seed; custom frameworks can define their own{{mysql_version}}, {{postgres_version}}, {{redis_version}}, {{meilisearch_version}}) are available in framework env vars and resolved from the service image tag at env-setup timeContainerfile.lerd and a container: section in .lerd.yaml with a port; lerd builds a per-project image, runs it as lerd-custom-<sitename>, and nginx reverse-proxies to it; the project directory is volume-mounted at its host path with --workdir set automatically — do NOT add WORKDIR or COPY to the Containerfile; workers exec into the custom container; services are accessible by name on the shared lerd Podman network; hot-reload file watchers must use polling on macOS (inotify does not fire across Podman Machine's virtiofs mount) — nodemon: --legacy-watch, Vite: server.watch.usePolling: true, webpack: watchOptions: { poll: 1000 }Containerfile.lerd (must build FROM lerd-php<ver>-fpm:local) plus a container: section with no port; lerd builds a per-site image (lerd-custom-<site>:local), runs a dedicated FPM container lerd-cfpm-<site>, and serves it by fastcgi instead of the shared lerd-php<ver>-fpm. It is a normal PHP site otherwise (xdebug, dumps, profiler, lerd shell, php/artisan/composer/tinker, queue/horizon all run in the per-site container). The PHP version is fixed by the FROM line (the UI version selector is read-only); lerd rebuild rebuilds the image. Same key as custom containers, the port is the discriminator: with a port it is a reverse-proxied non-PHP app, without a port it is a fastcgi PHP image. runtime for these reports fpm-custom.<branch>.<site>.test subdomain (deep *.<branch>.<site>.test wildcard cert + nginx server_name on secured sites); vendor/, node_modules/, .env are seeded from the main checkout. .lerd.yaml env_overrides declares templated env vars ({{domain}}, {{scheme}}, {{site}}) layered on the default APP_URL rewrite — for multi-tenant apps (per-branch cookies, signed-URL hosts, tenant routing)Lerd has two install-time DNS modes recorded in ~/.config/lerd/config.yaml:
dns.enabled: true, dns.tld: test. Sites at *.test via lerd-dns + mkcert; site tls_enable works.dns.enabled: false, dns.tld: localhost. Sites at *.localhost via RFC 6761; no mkcert CA, TLS toggling unavailable.Read diag action: "status" for dns.tld and dns.enabled instead of assuming .test; do not propose tls_enable when dns.enabled is false.
Twelve grouped tools, each selecting behaviour via action.
site — sites and their configurationActions: list (discover sites — CALL FIRST), link, unlink, domain_add, domain_remove, group_assign, group_unassign, group_label, group_db, group_list, tls_enable, tls_disable, tls_renew, php, node, pause, unpause, restart, rebuild, runtime, nginx_read, nginx_write, nginx_reset, park, unpark.
link registers a directory; non-PHP sites need .lerd.yaml container.port + a Containerfile first, or they register as PHP (wrong)link runs lerd link and returns its output verbatim, so read the reply. It will NOT start a proxy.command dev server (command not approved); ask the user to run lerd link --yesdomain_* take a domain without the .test TLD; you can't remove the last domaingroup_* nest a secondary site under a main's subdomain (one level deep): they identify the secondary by path (defaults to cwd), not by site; group_assign with main + label (+ optional share_db), group_db = share|separategroup_assign under a secured main secures the secondary, tls_enable on a main secures its secondaries too, and tls_disable on a secondary is refused while its main is secured (the main's *.<main> wildcard would answer the subdomain and serve the main's app). Disable the main's TLS firsttls_renew forces it by hand for one sitephp/node take version; pass branch to pin the override on a worktree's checkoutruntime switches fpm ↔ frankenphp (worker: true enables frankenphp worker mode)nginx_write saves a custom override (runs nginx -t, backs up, reloads); branch targets a worktreepark registers a parent dir and auto-registers every PHP project under it; unpark reverses it (project files kept)service — built-in & custom servicesActions: start, stop, restart, pin, unpin, update, rollback, migrate, remove, reinstall, add, expose, port, env, config_read, config_write, config_restore, config_reset, config_list_backups, preset_list, preset_search, preset_install, check_updates, entities, entity_action.
update pulls a newer image (safe, in-strategy); migrate dumps + restores across a cross-strategy upgrade; reinstall with reset_data: true wipes data and reprovisions; remove with remove_data: true renames the data dir asidestop marks the service paused — lerd start skips it until started again; pin keeps it always runningadd registers a custom OCI service (depends_on wires dependencies, init: true for mysql/mariadb); prefer preset_install for anything in preset_list (phpmyadmin, pgadmin, mongo, mongo-express, selenium, stripe-mock, mysql, mariadb…)preset_list returns the installable presets with the metadata each one declares: category (the discovery heading), icon, and admin_for — the services this preset's admin UI administers, which is not depends_on. phpMyAdmin depends on mysql but administers mariadb too, and RedisInsight administers valkey without depending on it. To answer "which dashboard administers this database", read admin_for, not depends_on. preset_search queries the store by name for presets that are not bundled locallyenv returns the recommended .env connection keys; expose publishes an extra host:container portport moves the service's primary published host port (published_port, or reset: true for the default); it stays bound to 127.0.0.1, the container-internal port is unchanged, and a host-proxy site that points at the old port is realigned automaticallyentities lists what a service holds that is not a database: the kinds its preset declares (RustFS buckets today, more later), each kind's rows and the actions it supports. Databases have their own tool, so they are not repeated here. entity_action runs one of those declared actions (kind, entity, entity_action); export and import stream a file and stay on the CLI and the dashboardconfig_* read/write/restore/reset a service's runtime tuning overridedb — databasesActions: list, set, move, create, export, import, snapshot, snapshots, restore, snapshot_delete, extension_list, extension_add.
list reports an engine's databases with sizes; service picks the engine, else it resolves from the project. No introspect command, nothing to reportset picks the project DB (database: sqlite, mysql, postgres, or a family alternate like mariadb / postgres-pgvector / postgres-timescaledb / mysql-5-7); persists to .lerd.yaml, rewrites DB_ keys, starts the service, creates the DB + _testingmove migrates sites between two installed same-family services (from/to, sites: [...] or all: true) and repoints each .env; source data is left intactcreate/export/import auto-detect service and database; pass service to override. import drops a hosted provider's ownership/DEFINER statements (which can never apply here) and creates any extension the dump's types need; pass fresh: true to empty the database first so a dump replaces what is there instead of colliding with it. What an engine can list and act on is declared in its preset, so this is not a mysql/postgres-only setextension_list/extension_add are postgres-only. An import already creates whatever extension the dump's types reach for, so use these to see what the engine offers and what the database has, or to add one (extension: postgis) before any dump arrivessnapshot/snapshots/restore/snapshot_delete are named, restorable snapshots (MySQL/MariaDB/PostgreSQL); restore is destructive; all_databases covers the whole serviceenv — .env managementActions: setup, check, override.
setup configures services, DBs, APP_KEY and APP_URL; on a fresh Laravel clone call db set first to move off sqlite, then env setup, then ALWAYS framework setup or migrations never runcheck compares .env against .env.exampleoverride manages the personal, gitignored .env.lerd_override (its set KEY=VALUE win over lerd defaults; LERD_EXTERNAL_SERVICES=<svc,svc> marks vars lerd writes but won't start)runtime — PHP/Node versions & extensionsActions: versions, node_install, node_uninstall, node_manager, php_list, ext_list, ext_add, ext_remove, ports_list, ports_add, ports_remove, ini_read, ini_write, ini_reset.
ext_add/ext_remove change one declared set applying to EVERY PHP version, so a site keeps its extensions across a version change. They rebuild one version's FPM container now (slow); others rebuild on next use. ext_add accepts apk_deps for extra Alpine build packagesext_list reports the declared set plus, per version: has it, predates the set (rebuild fixes), or cannot load it (rebuild won't). Never assume a declared ext is present: mongodb needs 8.1+, 7.4/8.0 are Alpine 3.16node_manager with no argument reports the version manager lerd drives, whether nvm is present and whether lerd manages Node at all; with manager: fnm|nvm it switches, which also rewrites the PATH shims and regenerates host workersphp_list sets base_update when the published base image a version was built from has been republished (an upstream PHP or Alpine fix); lerd php:rebuild <version> picks it upports_add/ports_remove/ports_list publish extra host ports on a PHP version's shell (FPM) container so a process started in lerd shell is reachable at localhost:PORT. ports_add takes host and optional container (defaults to host); a busy host port shifts to the next free one. Per version and independent, loopback-bound (follows lan:expose), restarts that version's FPM. Prefer host-proxy or a worker+proxy for a single site. CLI: lerd php:ports add/remove/list [--php version]ini_read/ini_write/ini_reset edit php.ini: pass version for a per-version file, or shared: true for the shared file applied to every version. The shared file loads below the per-version one, so a per-version key still wins and an unknown key on some version is ignored (not fatal). Prefer shared for a setting you want everywhere, so a version change never drops it. ini_write takes full content, backs up, and restarts the affected FPM containers. CLI: lerd php:ini [version|shared]lerd php:pkg add/remove/list <packages> (CLI) bakes runtime apk packages (CLI tools, libs) into every FPM image, saved in config under php.packages and re-applied on every rebuild, so they survive php:rebuild and base image updates. One declared set applies to every PHP version. Layered onto the shared image, not the published base.lerd pest:browser install|doctor|remove [version] sets up pestphp/pest-plugin-browser inside the FPM container by baking Alpine's musl chromium into the images. Chromium only, and current PHP versions only (the 7.4/8.0 legacy tier is rejected). Needs the playwright npm package first; re-run install after bumping it. Tests then run through the normal lerd test/lerd pest.bun.lockb/bun.lock/bunfig.toml/packageManager: bun) or when Node is unmanaged, no system Node exists, and bun is present. CLI-only: lerd node:manage/node:unmanage opt in or out of lerd-managed Node (unmanage drops fnm versions, never a user's nvm ones), lerd js:runtime [bun|node|auto] pins one site's runtime, and lerd php:bun install|update|version manages an in-container bun for lerd shell. These are host operations, not container exec actions.worker — background workersActions: list (CALL FIRST), start, stop, add, remove, health, heal, mode_get, mode_set, and the framework workers queue_start, queue_stop, horizon_start, horizon_stop, reverb_start, reverb_stop, schedule_start, schedule_stop, stripe_start, stripe_stop, stripe_config.
list to discover a site's workers before start; pass branch to target a per-worktree unithorizon_* instead of queue_* when laravel/horizon is installed (mutually exclusive); queue_start needs Redis running when QUEUE_CONNECTION=redisadd saves a custom worker to .lerd.yaml (or the user overlay with global: true); does not auto-starthealth reports unhealthy units (read-only); heal resets and restarts them (unit for one, omit for all); mode_get reports the macOS worker runtime, mode_set switches it (mode: exec|container)state is one of failed (the unit died), expected-but-stopped (it should be running and isn't), or unreachable — the unit is happily active but the server it publishes no longer accepts connections, a dev server that wedged without exiting. All three are heal-able; heal restarts the unit. Per-worktree units (lerd-<worker>-<site>-<branch>) are covered by the same pass, so a dead per-worktree Vite heals like any other. A worker with a schedule is a oneshot driven by a timer and is idle between ticks by design, which is healthy.env (STRIPE_SECRET / STRIPE_SECRET_KEY / STRIPE_API_KEY); stripe_config sets webhook_path / secret_env_key in .lerd.yamllerd horizon:reload [on|off] and lerd octane:reload [on|off] (FrankenPHP worker mode) restart workers on file changes; both need the project's chokidar npm packagelerd idle on/off toggles activity-driven suspension globally; suspended workers stop after the idle timeout (lerd idle timeout <dur>) and resume on the next request/CLI/MCP/file-save. lerd idle pin/unpin <site> exempts a site; lerd idle status reports policy and last-active. A worker shown as suspended is healthy, not failed, so do not heal itexec — run tooling in the PHP-FPM containerActions: artisan (Laravel), console (other frameworks), composer, vendor_bins, vendor_run, commands_list, commands_run, command_add, command_remove.
artisan/console/composer take args (array); tinker must use --execute=<code> for non-interactive usevendor_run is the right way to run project tooling (pest, phpunit, pint, phpstan, rector) — call vendor_bins first to discover what's installed, then vendor_run with bin + args; prefer it over composer execcommands_*/command_* list, run, add and remove the on-demand commands in a site's .lerd.yaml commands: block; commands_run needs force: true for confirm-gated commandscomposer needs a private repo reachable only over SSH, lerd auth ssh starts a shared ssh-agent container and loads the host's ~/.ssh/id_* (or named keys) so passphrase-protected keys work in the FPM container; lerd auth ssh --list shows loaded keys, --remove flushes them. Keys live only in agent memory and clear on machine restartframework — framework definitions & scaffoldingActions: list, add, remove, prune, search, update, project_new, setup.
add with name: "laravel" merges custom workers/setup into the built-in frameworkremove refuses to drop a definition a linked site still uses (pass force: true to override); prune removes every framework definition no site usessearch/update use the community store; definitions auto-fetch on link, so update is the manual refresh (no name refreshes the catalogue and all installed definitions; with name it fetches that one, auto-detecting version from composer.lock)project_new scaffolds a new project (requires absolute path, default framework laravel); follow with site link + env setupsetup runs the framework's post-install steps (migrations, storage:link…) — MANDATORY after env setup on new/cloned projects; idempotentdiag — diagnostics & observabilityActions: status, doctor, doctor_fix, site_doctor, which, check, dns_diagnose, bug_report, analyze_queries, route_timing, optimize_route, dumps_recent, dumps_status, dumps_clear, dumps_toggle, profiler_toggle, profiler_status, profiler_clear, profiler_report, xdebug_on, xdebug_off, xdebug_status.
status (DNS/nginx/FPM/watcher/tools health) and doctor (JSON findings, each tagged with a fix tier) are the first stops when something is broken; dns_diagnose walks the DNS chaindoctor_fix applies the safe (non-heavy, non-sudo) automatic repairs for environment findings; package installs, lerd install, and lerd cleanup stay manualsite_doctor runs framework-agnostic app-level checks for one site (env file, env drift, app key, composer/node dependency install + lock, composer audit/npm audit, PHP range, a slow_routes warning for routes whose p95 runs well above the site's typical time or over a second, plus the framework's own checks); pass site (name or domain) or path, defaults to cwd. A failing check carries a severity and, when one applies, a fix naming the command that resolves it — run that yourself (exec, or the named lerd command); site_doctor itself is read-only. slow_routes is the exception: it reads the watcher's request-timing snapshot and has no command fix, the remedy is to profile the route (profiler_toggle)logs tool (below), not herewhich shows resolved PHP/Node/docroot/nginx for a site; check validates .lerd.yamldumps_toggle (enable) → dumps_clear → hit the page → analyze_queries (N+1 / slow-query report with file:line) or dumps_recent (filter by site/branch/ctx/kind/since/limit)route_timing returns the per-site response-time table: the typical (median) time and the routes whose p95 runs well above it (method, example path, p95, multiplier, samples), read from the watcher's request-timing snapshot. Works from recorded traffic alone, no capture needed. site accepts either the site name or its domain, as do analyze_queries, optimize_route, and dumps_recentoptimize_route is the join: each slow route paired with the N+1 and slow-query findings captured against that same route (with the caller file:line), so you get the symptom and its cause in one call. Needs the query capture on (dumps_toggle enable) plus a few real hits. When the SPX profiler was on for the route's traffic, each slow route also carries a profile block, the top functions by exclusive wall time from the freshest capture, distilled to a few outliers (not the raw trace), so a CPU-bound route shows where its time went next to its queriesroute_timing to see which routes are slow → dumps_toggle (enable) and profiler_toggle (enable) → hit the slow route a few times → optimize_route to get its N+1/slow queries with file:line and, from the profiler, the top CPU functions behind it → fix the caller (eager-load, index, cache) or the hot functionoptimize_route, and treat a new N+1 or a slow_routes doctor warning as work to finish rather than noise. On an unfamiliar site, route_timing shows the slow routes worth attention first. The timing panel is a live signal (recent traffic only, in memory), so a route you fixed clears once it stops being slow, but the durable catch is the slow_route push notification that fires the moment a route crosses into slow. Periodic checking belongs to the user's own scheduler (a routine, a cron job), not to lerd.profiler_* toggle the global SPX profiler and surface the flame-graph UI; profiler_report (site + args, e.g. ["artisan","app:heavy-report"]) runs that command under SPX and returns a text flat profile, the top functions by wall time and call count, the CPU-bound analog of analyze_queries for when a slow route's cost is not in its queries (a reproducible CLI command, not a live HTTP request); xdebug_* control Xdebug on port 9003 (mode defaults to debug)bug_report writes an anonymised diagnostic report for a GitHub issuelerd cleanup reclaims podman disk from orphaned lerd images (--dry-run to preview, --deep for the aggressive tier); a daily safe-tier sweep plus post-rebuild/service-change reaping runs automatically, toggled with lerd cleanup auto on|off|statuslogs — read logs from any source, filteredActions: sources, fetch. Debug without opening files by hand.
sources lists every queryable source for the site plus shared infra: app:<file> (framework log files), fpm, worker:<name> (queue/horizon/schedule/custom), and the globals nginx, dns, watcher, ui, services, php<ver>. Call it first to learn the namesfetch source=<name> reads one source. Filter with grep (regex, falls back to literal substring), since/until (relative like 15m/1h/2h30m, or a timestamp), level (app logs only: error/warning/info/debug), and lines (default 50)fetch returns an opaque cursor; call again with since=<cursor> (or cursor=<cursor>) to get only the new lines. The cursor format differs per backend, so treat it as opaque and echo it backsince/level and just return the last N; a not-running container returns partial output, not an errorworktree — git worktreesActions: list, add, remove, wait, db_isolate, db_share.
add installs deps and offers an asset-worker / build-step prompt; secured sites get *.<branch>.<site>.test wildcard cert SANs + nginx server_name automatically. It waits for setup and reports provisioned (false + note means still running, not failed; timeout_seconds default 300)wait is that readiness check alone, for a worktree made with plain git worktree add. Never judge readiness from the tree: node_modules/ exists from the first extracted package and composer fills existing vendor/<org>/ dirs, so both read as finished mid-install, and racing the watcher is how vendor/ ends up with no autoload.phpdb_isolate gives a worktree its own database (seed via source: empty|main|<branch>); db_share points it back at the main; remove keeps an isolated DB unless keep_db: falseadd does that work rather than leaving it to be run by handbranch to route_timing, optimize_route and dumps_recent to read one branch's trafficworkspace — group sites for displayActions: list, create, rename, delete, assign, move.
.env. This is not the same thing as the site tool's group_* actions, which nest a real site under another's subdomain and regenerate vhosts and certs — reach for group_* when a site should be served at <label>.<main>.test, and for workspace when the user just wants their site list organisedassign takes sites (names or domains) and a workspace, creating it if new; workspace: "none" ungroups them. move reorders a workspace with a zero-based positiondelete drops the workspace and ungroups its members; no site is touchedaction on every tool; path is optional on most and defaults to the directory the assistant was opened insite list for sites, worker list for a site's workers, service preset_list before preset_install, exec vendor_bins before vendor_rundb set before env setup to choose a database deliberately, then run framework setupwarnings) and registers the survivors, falling back to <dirname>.<tld>; .lerd.yaml is untouched. domain_add still hard-errorsenv setup writes <scheme>://<primary-domain>; override via app_url in .lerd.yaml (committed) or the per-machine sites.yaml entry, then re-run env setuplerd-<name> (e.g. lerd-mysql, lerd-redis, lerd-postgres); default DB credentials are username root, password lerdContainerfile.lerd); (2) write .lerd.yaml with container: {port: <N>} (plus optional domains, services, secured); (3) configure the project's .env with service hosts (lerd-mysql, etc.) and start needed services via service start; (4) call site link. Never link before steps 1–3 or the site registers as PHP-FPM; if that happens, site unlink, write the files, then link againlerd-<worker>-<site> (per-worktree: lerd-<worker>-<site>-<branch>)diag status reports Composer, fnm and mkcert against the versions lerd pins, and flags any that differ. Applying an update is lerd tools:update, which has no tool here, so tell the user to run it rather than looking for an actionlerd share (ngrok, cloudflared, Expose, serveo, localhost.run, Pinggy) and the dashboard's share menu put a site on the public internet, the same menu's public share serves it through the user's own reverse proxy on a base domain they control instead of a tunnel service, and lerd lan:expose puts it on the local network. None is exposed here, so never claim you can share a site; hand the user the command and let them decide© liberusoftware, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/lerd of liberusoftware/real-estate-laravel.
Open the folder on GitHubat commit 8d7119e
We found 2 copies of this SKILL.md (exact, near-identical or edited) in other folders. This page covers the copy in liberusoftware/real-estate-laravel, which our catalogue first saw on October 7, 2026.
Lerd next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Lerd this skillliberusoftware/real-estate-laravel | 112 | — | ~7.8k | Automated safety check: Warn | MIT | |
| Laravel Best Practicesanonaddy/anonaddy | 4.9k | 13 repos | ~1.2k | Automated safety check: Pass | MIT | |
| MCP Developmentcachethq/core | 230 | — | ~1.4k | Automated safety check: Pass | MIT | |
| Laravel ToolingHoangNguyen0403/agent-skills-standard | 571 | — | ~760 | Automated safety check: Pass | MIT | |
| MCP Developmentcoollabsio/coolify | 63k | 1 repos | ~949 | Automated safety check: Pass | MIT | |
| Configuring Horizoncoollabsio/coolify | 63k | 4 repos | ~898 | Automated safety check: Pass | MIT |
anonaddy/anonaddy
Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code.
cachethq/core
A skill your agent uses for Cachet's Laravel MCP server. An agent skill from cachethq/core.
HoangNguyen0403/agent-skills-standard
Configure Laravel ecosystem with custom Artisan commands, Vite asset bundling, Pint code styling, and Horizon queue monitoring.
coollabsio/coolify
A skill your agent uses for Laravel MCP development. An agent skill from coollabsio/coolify.
coollabsio/coolify
A skill your agent uses whenever the user mentions Horizon by name in a Laravel context.
yaojingang/GEOFlow
Operate/develop GEOFlow CLI/Laravel/admin/API, topics/专题 and topic tasks, theme libraries/replication, sites/leads/Agent, channel sync and legacy yao-geoflow-cli/design/template migration.
liberusoftware/real-estate-laravel
A skill your agent uses for Pest PHP testing in Laravel projects only.
liberusoftware/real-estate-laravel
A skill your agent uses when working with Laravel Octane, a long-running PHP worker server (Swoole, FrankenPHP, RoadRunner) where the application boots once and serves many requests instead of…
Manage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js…. Lerd is an agent skill from liberusoftware/real-estate-laravel.js versions, and inspect site status.
Lerd fits situations like: tasks that involve Backend development; tasks that involve MCP servers; tasks that involve Query optimization.
Run `npx skills add liberusoftware/real-estate-laravel --skill lerd -a claude-code`. Or copy the skill folder (.claude/skills/lerd in liberusoftware/real-estate-laravel) into .claude/skills/lerd in your project. Claude Code loads it when a task matches its description.
Run `npx skills add liberusoftware/real-estate-laravel --skill lerd -a codex`. Or copy the skill folder (.claude/skills/lerd in liberusoftware/real-estate-laravel) into .agents/skills/lerd in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add liberusoftware/real-estate-laravel --skill lerd -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/lerd, .gemini/skills/lerd, .github/skills/lerd and .opencode/skills/lerd in your project.
Going by SKILL.md and its folder, Lerd needs the command-line tools its instructions call (npm, composer, pnpm, yarn, nvm and node) and credentials named APP_KEY, STRIPE_SECRET, STRIPE_SECRET_KEY and STRIPE_API_KEY. Our summary lists: Node.js.
SKILL.md contains no URLs. Its commands use npm and git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md flagged 1 warning(s): mentions a credentials file (ssh keys, cloud or package-manager tokens). Read the flagged lines before installing; the check is not a guarantee either way.
Lerd is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.8k tokens (SKILL.md is roughly 31k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Lerd: Laravel Best Practices (anonaddy/anonaddy, 4.9k stars), MCP Development (cachethq/core, 230 stars), Laravel Tooling (HoangNguyen0403/agent-skills-standard, 571 stars) and MCP Development (coollabsio/coolify, 63k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
liberusoftware (a GitHub organization) maintains it in liberusoftware/real-estate-laravel, which has 112 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 5, 2026.
Source: liberusoftware/real-estate-laravel on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.