Appearance
Skills reference
Seven procedures live under .claude/skills/, one directory each, holding a single SKILL.md. They are plain markdown with a frontmatter block naming the skill and describing when it applies:
markdown
---
name: add-a-screen
description: Add one screen to a Laraspring application end to end — route, controller,
Inertia page, English and Spanish strings, a navigation entry and a test. Use when
the user asks for a new page, view, screen, settings tab or dashboard…
---The description is the trigger. Claude Code matches it against what you asked for and loads the file; other agents can be pointed at the path directly. Either way it is the same markdown, so you can read one in ten seconds and decide whether you agree with it.
Every step in every skill cites a real file or a real command in this repository. The first two were walked end to end against the reference edition rather than written from the documentation, which is how three of the notes below came to be there at all.
add-a-feature
Triggers on: a new feature area, module, domain or reusable package.
Starts with the decision the rest depends on: does this belong in your edition, or does it earn a package of its own. The default is the application, and the skill states the three conditions that all have to hold before a package is worth its maintenance cost.
If it is a package, the rest is the full scaffold: composer.json with the auto-discovery entry, the service provider with its publish tags, a renderer contract if it has screens, migrations that resolve the user table through Laraspring\Core\Support\Users rather than naming it, translations, an isolated Testbench suite, the path repository wiring, and the edition-side binding, translation export, page and integration test.
Two things it insists on, both learned by getting them wrong:
- A renderer contract returns
Responsable|Response, notResponsablealone. Every renderer in the kit declares both, and a fixture renderer returning aJsonResponseis a fatal error against the narrower signature. - The package's translation group has to be named in
app/I18n/LaraspringTranslations.phport()renders the dotted key in the browser, with nothing reporting the omission anywhere.
add-a-screen
Triggers on: a new page, view, screen, settings tab or dashboard.
Six steps: route, controller, Inertia page, strings in both languages, a navigation entry, a test. Then the gates.
The notes that matter:
- A page is a default export, unlike every component under
resources/js/components, because Inertia resolves pages throughresolvePageComponent. route()is a global declared inresources/js/app.tsx, orapp.tsin the Vue edition; it is not imported, androute('name', undefined, false)is the relative form the navigation uses.- A settings screen needs its line in
resources/js/layouts/settings/nav.ts, which takes a route name and a translation key and nothing else, so an entry whose route does not exist disappears rather than 404ing.
add-a-billing-plan
Triggers on: a new pricing tier, a price change, a yearly interval, grandfathering, seat limits.
The catalogue is configuration. The skill covers publishing laraspring-billing, the shape of a plan entry, amounts in minor units, the <provider>_price_id per interval coming from environment variables so one catalogue serves test and live keys, and the three special kinds: free, contact-sales and hidden.
It also states the four things not to do, of which the sharpest is: never gate a feature on a price identifier. Billing::subscribed(null, 'team') takes the logical plan id, which is exactly what makes rotating a price in Stripe a one-line change.
add-a-locale
Triggers on: adding a language, translating the app, localizing email.
One file per package under lang/vendor/laraspring-<pkg>/<locale>/, plus Laravel's own validation.php, auth.php, passwords.php and <locale>.json, plus the application's lang/<locale>/app.php.
Its central piece of advice is to drop the new locale's files in without publishing. Publishing copies English and Spanish too, and a published file stops receiving updates, so a key the kit adds later renders as its key. Add only de/ and en keeps updating with the kit.
Finishes at /laraspring/mail, which draws every transactional email in whatever language you are currently in and is the fastest way to read a whole locale's email at once.
customize-emails
Triggers on: email branding, wording, the template, or adding a transactional email.
Four levels in the order to reach for them: configuration, then rewording through translation files, then the mail:: components, then publishing the views. Most installations stop at the first.
It is explicit about two things that are easy to get wrong and expensive to discover late: the logo must be an absolute URL served without authentication, because a mail client fetches it with no session, and the footer address is a legal surface rather than decoration, with a placeholder you are expected to replace before sending anything a recipient could call marketing.
rebrand-the-public-site
Triggers on: a rebrand, a product name, a logo, colours, the landing page copy, or the privacy policy and terms.
Starts from the split that the rest depends on: names, URLs and addresses in config/brand.php, and every sentence in lang/{locale}/app.php, because a name is one string whatever language the page is in and a tagline is one per language.
Three notes it is explicit about. brand.color is the browser theme colour and not the interface palette, which is --primary in app.css and has to be changed in the .dark block as well or the product has a brand in one theme only. A feature in the grid is an icon in code plus its words in every locale, matched by name. And the banner saying the legal pages are a template comes off when a lawyer has read them, not when the page looks finished.
upgrade-safely
Triggers on: taking a new kit version, a conflict in packages/, or asking whether a change will survive an upgrade.
Answers one question in two directions. What is public API and therefore safe to build on: route names, the five laraspring/core contracts, the renderer contracts and their Screens constants, the four registries, the support facades, the configuration keys and the translation keys. And what you take ownership of the moment you publish it, with the cost of each, since a published file stops receiving updates and your copy is the one that wins.
Ends with a symptom table, because most upgrade trouble shows up as a specific recognisable failure rather than as an error naming its cause.
Writing your own
A skill is a directory under .claude/skills/ with a SKILL.md in it. Frontmatter with name and a description that says when it applies, then steps.
What makes the ones here work is that every step names a real path and every claim can be checked by running something. A skill that describes a procedure nobody has walked is worse than none, because it is trusted at exactly the moment it is wrong. Walk it once, then write down what surprised you.