cjmellor/mella-marketplace/tree/main/plugins/artisan-dev
artisan-dev
A Claude Code plugin that runs and manages a Laravel app's `php artisan dev` processes from a pane with per-process logs, restart/stop controls, port override and tunnel detection.
About this mod
artisan-dev is a Claude Code plugin for Laravel projects. /dev starts every process php artisan dev would, opens a pane with per-process logs and controls, and shows a one-line status band above the prompt while they run. Subcommands cover start/stop/restart/status, opening the site, attaching server state to a prompt (/dev ask), clearing or copying logs, error-only filtering, and copying a detected public tunnel URL. The port is resolved from the running server line, a --port override, SERVER_PORT in .env, then Laravel's default, and the override stays session-only. The pane supports process selection, toolbar actions (stop/start/restart/open/copy tunnel/copy log/ask Claude), colored and wrapped logs, and error/warning filtering; error counting uses strict severity markers. The plugin watches the main checkout across worktree enter/exit and restarts servers if the branch or worktree set changes, runs each process in its own process group with retry limits, and detects tunnels from output of Cloudflare, ngrok, Expose, Herd share, localtunnel, localhost.run, Serveo, Pinggy, Tailscale funnel and Dev Tunnels. Settings include projectDir and extra tunnelHosts. Requires a Claude Code build that loads plugin modules and a Laravel app whose Artisan has dev and dev:list; macOS launches processes via perl and opens the site with open. Licensed MIT.
Installation
Check the author's README for the marketplace and plugin name first. Commands may change as the repository evolves.
claude plugin marketplace add cjmellor/mella-marketplace claude plugin install artisan-dev
Original text / README
artisan-dev
Run a Laravel app's php artisan dev from inside Claude Code and manage it without leaving the session.
artisan-dev is a Claude Code mod. /dev starts every process php artisan dev would, opens a pane with their logs and controls, and keeps a one-line status band above the prompt while they run.
Requirements
- A Claude Code build that loads plugin modules (mods).
- A Laravel app whose Artisan has
devanddev:list. - macOS: processes are launched through
perl(preinstalled) and the site is opened withopen.
Usage
/dev starts the processes and opens the pane. Add a subcommand to do one thing:
| Command | What it does |
|---------|--------------|
| /dev | Start everything and open the pane |
| /dev start | Start everything, no pane |
| /dev stop | Stop everything and clear the log |
| /dev restart [name] | Restart everything, or one process by name or number |
| /dev status | Show what is running |
| /dev site | Open the site |
| /dev ask [name] | Attach the server state and recent output to your next prompt |
| /dev clear | Clear the log |
| /dev errors | Toggle showing only errors and warnings |
| /dev copy [name] | Copy a process log (or the all view) to the clipboard |
| /dev tunnel | Show and copy the public tunnel URL |
| /dev help | List the commands |
Port
The port comes from, in order: a live Server running on [http://host:PORT] line from the app, a --port override, SERVER_PORT in the project's .env, then Laravel's default.
Override it for the session with --port=8111, -p 8111 or port=8111 on /dev, /dev start or /dev restart. If the servers are running, they restart on the new port. port=default (or port=reset) drops the override. A port can't be combined with restarting a single process, because it applies to every process.
The override lives in the session only. It is never written to .env, and it stays in place until you reset it or the session ends.
The site opens at APP_URL from the .env of the checkout the session is in, so inside a worktree it is that worktree's site. A loopback APP_URL (localhost or 127.0.0.1) gets the real port; any other host is used as written. The band link is labelled with that host (kandu.test ↗), or :port ↗ for a loopback APP_URL. In a worktree with a hosted APP_URL, the worktree name in the band is the link instead.
The pane
- Processes —
0shows the combined log in arrival order;1–9pick a process. The up and down arrows move between process names only. - Toolbar —
xStop all (orsStart all),rRestart all,tRestart one (the selected process),oOpen site,uCopy tunnel (shown once a tunnel URL is known),cCopy log,aAsk Claude (attaches the state and recent output to your next prompt; the button then readsasked ✓and drops it). - Log — keeps each process's own colours, wraps long lines, and scrolls with the wheel, page keys, Home and End.
e(or the button in the Log divider) shows only errors and warnings. - Band above the prompt — status dot, a clickable site link (see Port above), how many processes are up, an error count, the git branch (
⎇) and, inside a linked git worktree, its name (⌂).+and−open and close the pane.
Errors
A line counts as an error only when it carries a severity marker where its tool puts one: a log level such as Laravel's local.ERROR: or a Pail ERROR badge, an exception class at the start of the message, or a phrase such as Fatal error, Uncaught or Vite's Internal server error:. A word like error inside a file name, path or ordinary sentence doesn't count. Matching lines raise the band's error count, turn red in the log and show a toast.
Crashes and restarts
While the servers run, the mod checks the project's main checkout right after Claude enters or exits a worktree, and every few seconds otherwise. If its branch changes, or a git worktree is added or removed, it restarts everything and shows a toast naming the cause. The servers always run from the main checkout, even when the session itself has moved into a worktree.
Each process runs in its own process group, so stopping or restarting one kills everything it started. A process that exits with a non-zero code or is killed from outside is restarted up to five times; a process that dies within a second of starting is not retried. The budget resets after a minute of healthy running or when you press Start all. Toasts report starts, crashes, restarts and giving up.
Reloading the mod or ending the session stops the servers. Anything left over from an earlier load is cleaned up when the session starts, but only if its process group still carries this mod's marker.
Tunnels
When a process prints a public tunnel URL (Cloudflare, ngrok, Expose and Herd share, localtunnel, localhost.run, Serveo, Pinggy, Tailscale funnel, Dev Tunnels and similar), the mod shows a toast and offers Copy tunnel. Detection reads process output, so a tunnel started outside the dev processes, such as from Herd's own Share button, isn't seen.
Settings
| Setting | Default | Purpose |
|---------|---------|---------|
| projectDir | empty | Absolute path of the Laravel app. Empty uses the session's folder; when the session starts inside a worktree, the same folder in the main checkout. |
| tunnelHosts | empty | Extra comma-separated domains to treat as a tunnel, for providers not built in. |
Development
The pure logic (argument parsing, .env reading, ANSI handling, layout, exit policy) is covered by hooks/register.test.ts:
claude plugin validate plugins/artisan-dev
claude plugin test plugins/artisan-dev
The process lifecycle (starting, stopping, restarting) isn't covered by tests, because the test kit can't mock process spawning.
License
MIT
