Claude
Skills
Sign in
Back

starter-kit-upgrade

Included with Lifetime
$97 forever

Selectively pull upstream improvements from a Laravel starter kit (laravel/vue-starter-kit, laravel/react-starter-kit, laravel/svelte-starter-kit, laravel/livewire-starter-kit) into a project bootstrapped from one. Use when the user wants to update, sync, or migrate features from their starter kit. Applies one feature at a time on a dedicated branch; never auto-merges customized files.

Web Devscripts

What this skill does


# Laravel Starter Kit Upgrade

- Users bootstrap from `laravel/vue-starter-kit`, `react-starter-kit`, `svelte-starter-kit`, or `livewire-starter-kit`, then customize. They own the code.
- We pick **specific features** from upstream (e.g. "toast notifications", "2FA autofocus fix"), not "version upgrades."
- The user's git history is unrelated to the kit's. There is no common ancestor. We compare user-now vs upstream-now, byte by byte.
- We never auto-merge a customized file. Customizations are surfaced; the user decides.
- Behavior preservation is the contract: the user's currently-passing tests/typecheck/build must still pass after.

## Safety contract: non-negotiable

Read these to the user before any side effects, and live by them throughout:

1. Working tree must be clean. If `git status --porcelain` is non-empty, refuse and tell the user to commit or stash. Do not "stash for them."
2. All work happens on a dedicated branch (`starter-kit-upgrade/<short-id>`). The user's current branch is never modified.
3. Each applied feature is its own commit. That is how revertability works.
4. Never auto-resolve conflicts. A change touching customized code is surfaced; default action is to skip the file.
5. Never silently overwrite manifests or lockfiles (`composer.json`, `package.json`, `*-lock.*`). Show diffs; let the user decide.
6. Verify behavior preservation. Re-run the user's tests/typecheck/build after applying. A previously-passing check that now fails is a regression. Stop, surface, recommend revert.
7. Detect from unambiguous signals; ask when ambiguous. Concrete evidence (e.g. `config/fortify.php` exists) is fine. Picking a likely answer when signals are mixed or absent is not.

If any of these is violated, abort with a clear message about what went wrong and how to recover.

## Required tools

- `git` (in the user's project)
- `gh` (authenticated; `gh auth status` returns OK)
- `jq` (used by `run_tests.sh`)
- `bash` (for the bundled scripts)

If any is missing, stop in Phase 4 and tell the user how to install.

## Gotchas

Environment-specific behavior the agent will get wrong without being told. Read these before starting the workflow and apply throughout.

- **Parallel implementations.** When a feature has `new` files plus `differs` to call sites, the user may already have an in-house equivalent (their own toast helper, validation rule, etc.). Surface as a whole; don't apply the `new` files in isolation as if they're "safe." Default action is to skip the entire feature; the user can opt to adopt upstream's version and remove theirs later.

- **Renamed paths.** If a `new` path's basename or class name already exists elsewhere in the user's repo, the user has likely renamed/moved it. Surface, don't auto-apply, or you'll create a duplicate. Show them the upstream change and let them apply it to their renamed file by hand or wait for user confirmation.

- **Later upstream edits.** Copying upstream HEAD pulls in _every_ commit since the feature, not just the feature's own changes. Always run the Phase 5 step 2 check before applying. When later edits exist, scope to `<sha>:<path>` instead of `HEAD:<path>`.

- **Transitive imports.** New files often `import` from helpers that are NOT in the same feature commit (Vue/React/Svelte: `@/lib/...`, `@/components/...`; Livewire: `@include`, `<x-...>`, `<livewire:...>`). Phase 5 step 4 covers the scan; never declare a feature applied without it. Uncovered imports show up as runtime/compile errors.

- **Lockfile drift.** Manifests are user-curated. Never overwrite. Walk the user through the upstream diff, let them merge, then regenerate lockfiles via the package manager (Phase 6).

- **Stale node_modules after major bumps.** After Vite v7 → v8, React 18 → 19, etc., `npm install` often fails with `ERESOLVE`. Clean and reinstall (Phase 6).

- **New migrations.** When upstream adds migrations (e.g. "Catch migrations up to Skeleton"), surface them separately. Recommend `php artisan migrate:status` first; applying a new migration on a populated DB can fail loudly.

- **Major framework bumps as features.** Things like Laravel 12 → 13, Livewire 3 → 4, or Inertia v2 → v3 are too large and too breaking for the feature-by-feature flow. Do not attempt them through this skill. Instead, prompt the user to run the corresponding [Laravel Boost](https://github.com/laravel/boost) MCP slash command first, then come back and re-run this skill against the resulting (clean-tree) repo. If Boost is not yet installed: `composer require laravel/boost --dev && php artisan boost:install` (requires Boost `^2.0`). Slash commands:
  - Laravel 12 → 13: `/upgrade-laravel-v13`
  - Livewire 3 → 4: `/upgrade-livewire-v4`
  - Inertia v2 → v3: `/upgrade-inertia-v3`

- **Already-present features.** If Phase 2's pre-filter missed it and Phase 5's classifier reports every file as `already-present`, skip the feature with a note: "every file matches upstream's current; moving on." Don't commit an empty commit.

- **More than ~50 `differs`.** The per-file walkthrough is too tedious to be useful at that scale. Stop, recommend manual upgrade for that feature.

## Workflow

Eight phases, in order. Each phase establishes invariants the next relies on.

### Phase 1: Identify the kit and branch variant

Inspect the user's project:

|                     | vue                                              | react                                            | svelte                                              | livewire                                  |
| ------------------- | ------------------------------------------------ | ------------------------------------------------ | --------------------------------------------------- | ----------------------------------------- |
| Cue                 | `.vue` files in `resources/js/components/ui/`    | `.tsx` files in `resources/js/components/ui/`    | `.svelte` files in `resources/js/components/ui/`    | no `resources/js/components/ui/` dir      |
| `package.json` has  | `"vue"` + `"@inertiajs/vue3"`                    | `"react"` + `"@inertiajs/react"`                 | `"svelte"` + `"@inertiajs/svelte"`                  | n/a                                       |
| `composer.json` has | n/a                                              | n/a                                              | n/a                                                 | `"livewire/livewire"` + `"livewire/flux"` |

State the detected kit out loud. If only one column matches, proceed. If two columns partially match (e.g. both `.vue` and `.tsx` present, or `package.json` lists `vue` and `react`), stop and ask.

Then determine the branch variant. There are four branches per kit, formed by two independent axes:

- **Auth axis** (read `composer.json`):
  - Fortify if `composer.json` has `laravel/fortify`, or `config/fortify.php` exists, or `app/Actions/Fortify/` exists, or `app/Providers/FortifyServiceProvider.php` exists.
  - WorkOS if `composer.json` has `laravel/workos` and none of the Fortify markers are present.
- **Teams axis** (check whether team scaffolding is present):
  - Teams if `app/Models/Team.php` exists (usually accompanied by `Membership.php`, `TeamInvitation.php`, and a `..._create_teams_table.php` migration).
  - Non-teams otherwise.

Combine the two axes to get the branch name:

| Auth    | Teams | Branch          |
| ------- | ----- | --------------- |
| Fortify | no    | `main`          |
| Fortify | yes   | `teams`         |
| WorkOS  | no    | `workos`        |
| WorkOS  | yes   | `workos-teams`  |

State the detected branch out loud. Only ask if signals are contradictory (e.g. Fortify markers present _and_ `laravel/workos` in composer, or a `Team.php` model with no teams migration); that means user customization you can't safely guess at.

### Phase 2: Enumerate available upstream features

The user can't tell you "what version they're on" reliably (and we don't try). Inspect upstream as it exists today and present a fea

Related in Web Dev