[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-laravel-starter-kit-upgrade":3,"mdc--omscq3-key":31,"related-org-laravel-starter-kit-upgrade":3516,"related-repo-laravel-starter-kit-upgrade":3648},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":20,"repoUrl":21,"updatedAt":22,"license":23,"forks":24,"topics":25,"repo":26,"sourceUrl":29,"mdContent":30},"starter-kit-upgrade","upgrade Laravel starter kit projects","Selectively pull upstream improvements from a Laravel starter kit (laravel\u002Fvue-starter-kit, laravel\u002Freact-starter-kit, laravel\u002Fsvelte-starter-kit, laravel\u002Flivewire-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.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"laravel","Laravel","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Flaravel.png",[12,16,19],{"name":13,"slug":14,"type":15},"Maintenance","maintenance","tag",{"name":17,"slug":18,"type":15},"PHP","php",{"name":9,"slug":8,"type":15},665,"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fagent-skills","2026-07-13T06:22:11.972952",null,28,[],{"repoUrl":21,"stars":20,"forks":24,"topics":27,"description":28},[],"Laravel official collection of agent skills","https:\u002F\u002Fgithub.com\u002Flaravel\u002Fagent-skills\u002Ftree\u002FHEAD\u002Flaravel\u002Fskills\u002Fstarter-kit-upgrade","---\nname: starter-kit-upgrade\ndescription: Selectively pull upstream improvements from a Laravel starter kit (laravel\u002Fvue-starter-kit, laravel\u002Freact-starter-kit, laravel\u002Fsvelte-starter-kit, laravel\u002Flivewire-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.\n---\n\n# Laravel Starter Kit Upgrade\n\n- Users bootstrap from `laravel\u002Fvue-starter-kit`, `react-starter-kit`, `svelte-starter-kit`, or `livewire-starter-kit`, then customize. They own the code.\n- We pick **specific features** from upstream (e.g. \"toast notifications\", \"2FA autofocus fix\"), not \"version upgrades.\"\n- 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.\n- We never auto-merge a customized file. Customizations are surfaced; the user decides.\n- Behavior preservation is the contract: the user's currently-passing tests\u002Ftypecheck\u002Fbuild must still pass after.\n\n## Safety contract: non-negotiable\n\nRead these to the user before any side effects, and live by them throughout:\n\n1. 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.\"\n2. All work happens on a dedicated branch (`starter-kit-upgrade\u002F\u003Cshort-id>`). The user's current branch is never modified.\n3. Each applied feature is its own commit. That is how revertability works.\n4. Never auto-resolve conflicts. A change touching customized code is surfaced; default action is to skip the file.\n5. Never silently overwrite manifests or lockfiles (`composer.json`, `package.json`, `*-lock.*`). Show diffs; let the user decide.\n6. Verify behavior preservation. Re-run the user's tests\u002Ftypecheck\u002Fbuild after applying. A previously-passing check that now fails is a regression. Stop, surface, recommend revert.\n7. Detect from unambiguous signals; ask when ambiguous. Concrete evidence (e.g. `config\u002Ffortify.php` exists) is fine. Picking a likely answer when signals are mixed or absent is not.\n\nIf any of these is violated, abort with a clear message about what went wrong and how to recover.\n\n## Required tools\n\n- `git` (in the user's project)\n- `gh` (authenticated; `gh auth status` returns OK)\n- `jq` (used by `run_tests.sh`)\n- `bash` (for the bundled scripts)\n\nIf any is missing, stop in Phase 4 and tell the user how to install.\n\n## Gotchas\n\nEnvironment-specific behavior the agent will get wrong without being told. Read these before starting the workflow and apply throughout.\n\n- **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.\n\n- **Renamed paths.** If a `new` path's basename or class name already exists elsewhere in the user's repo, the user has likely renamed\u002Fmoved 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.\n\n- **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 `\u003Csha>:\u003Cpath>` instead of `HEAD:\u003Cpath>`.\n\n- **Transitive imports.** New files often `import` from helpers that are NOT in the same feature commit (Vue\u002FReact\u002FSvelte: `@\u002Flib\u002F...`, `@\u002Fcomponents\u002F...`; Livewire: `@include`, `\u003Cx-...>`, `\u003Clivewire:...>`). Phase 5 step 4 covers the scan; never declare a feature applied without it. Uncovered imports show up as runtime\u002Fcompile errors.\n\n- **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).\n\n- **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).\n\n- **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.\n\n- **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:\u002F\u002Fgithub.com\u002Flaravel\u002Fboost) 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\u002Fboost --dev && php artisan boost:install` (requires Boost `^2.0`). Slash commands:\n  - Laravel 12 → 13: `\u002Fupgrade-laravel-v13`\n  - Livewire 3 → 4: `\u002Fupgrade-livewire-v4`\n  - Inertia v2 → v3: `\u002Fupgrade-inertia-v3`\n\n- **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.\n\n- **More than ~50 `differs`.** The per-file walkthrough is too tedious to be useful at that scale. Stop, recommend manual upgrade for that feature.\n\n## Workflow\n\nEight phases, in order. Each phase establishes invariants the next relies on.\n\n### Phase 1: Identify the kit and branch variant\n\nInspect the user's project:\n\n|                     | vue                                              | react                                            | svelte                                              | livewire                                  |\n| ------------------- | ------------------------------------------------ | ------------------------------------------------ | --------------------------------------------------- | ----------------------------------------- |\n| Cue                 | `.vue` files in `resources\u002Fjs\u002Fcomponents\u002Fui\u002F`    | `.tsx` files in `resources\u002Fjs\u002Fcomponents\u002Fui\u002F`    | `.svelte` files in `resources\u002Fjs\u002Fcomponents\u002Fui\u002F`    | no `resources\u002Fjs\u002Fcomponents\u002Fui\u002F` dir      |\n| `package.json` has  | `\"vue\"` + `\"@inertiajs\u002Fvue3\"`                    | `\"react\"` + `\"@inertiajs\u002Freact\"`                 | `\"svelte\"` + `\"@inertiajs\u002Fsvelte\"`                  | n\u002Fa                                       |\n| `composer.json` has | n\u002Fa                                              | n\u002Fa                                              | n\u002Fa                                                 | `\"livewire\u002Flivewire\"` + `\"livewire\u002Fflux\"` |\n\nState 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.\n\nThen determine the branch variant. There are four branches per kit, formed by two independent axes:\n\n- **Auth axis** (read `composer.json`):\n  - Fortify if `composer.json` has `laravel\u002Ffortify`, or `config\u002Ffortify.php` exists, or `app\u002FActions\u002FFortify\u002F` exists, or `app\u002FProviders\u002FFortifyServiceProvider.php` exists.\n  - WorkOS if `composer.json` has `laravel\u002Fworkos` and none of the Fortify markers are present.\n- **Teams axis** (check whether team scaffolding is present):\n  - Teams if `app\u002FModels\u002FTeam.php` exists (usually accompanied by `Membership.php`, `TeamInvitation.php`, and a `..._create_teams_table.php` migration).\n  - Non-teams otherwise.\n\nCombine the two axes to get the branch name:\n\n| Auth    | Teams | Branch          |\n| ------- | ----- | --------------- |\n| Fortify | no    | `main`          |\n| Fortify | yes   | `teams`         |\n| WorkOS  | no    | `workos`        |\n| WorkOS  | yes   | `workos-teams`  |\n\nState the detected branch out loud. Only ask if signals are contradictory (e.g. Fortify markers present _and_ `laravel\u002Fworkos` in composer, or a `Team.php` model with no teams migration); that means user customization you can't safely guess at.\n\n### Phase 2: Enumerate available upstream features\n\nThe 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 feature catalog.\n\nFetch raw data. The default window is the **last 100 commits \u002F merged PRs**; tell the user that up front so they know features older than that won't appear in the catalog. If they bootstrapped well before that window, walk back with `&page=2`, `&page=3`, etc. or raise `--limit`.\n\n```bash\ngh api \"repos\u002Flaravel\u002F\u003Ckit>\u002Fcommits?sha=\u003Cbranch>&per_page=100\" \\\n  -q '.[] | {sha: .sha[0:7], date: .commit.author.date[0:10], msg: .commit.message | split(\"\\n\")[0]}'\n\ngh pr list --repo \"laravel\u002F\u003Ckit>\" --state merged --base \"\u003Cbranch>\" --limit 100 \\\n  --json number,title,mergeCommit,mergedAt\n```\n\nCluster commits\u002FPRs into user-facing features. Examples a user would recognize:\n\n- \"Toast notifications across all kits\" (1 commit, several files)\n- \"Password visibility toggle in auth forms\" (1 commit, 3 files)\n- \"2FA autofocus fix\" (1 commit, 1 file)\n- \"Teams support\" (1 PR, many files; flag as large)\n- \"Inertia 3 upgrade\" (lockfile-heavy; flag as needing review)\n- \"Maintenance: formatting \u002F lint config\" (bucket of small commits)\n\nBucket internal\u002Frefactor commits as a single \"Maintenance\" entry. The user usually skips it.\n\nPre-filter: for each candidate feature, run `scripts\u002Fclassify_feature.sh` against its commit. If every file is `already-present`, mark `[!] Already present` and skip by default.\n\n### Phase 3: Present the catalog and get explicit selection\n\n```\nAvailable upstream features (vue-starter-kit, branch: main):\n\n[ ] Toast notifications              · PR #142, 4 files, 1 lockfile\n[ ] Password visibility toggle       · PR #131, 3 files\n[ ] 2FA autofocus fix                · commit 78fda0c, 1 file\n[ ] Teams support                    · PR #98, 23 files (LARGE)\n[~] Inertia 3 upgrade                · PR #110, lockfile-heavy (review carefully)\n[!] Already present: Vite font plugin\n\nWhich would you like to pull in?\n```\n\nWait for the selection. Recap the picks and the affected file counts. Ask one final time before any side effects.\n\n### Phase 4: Preflight, baseline, and workspace setup\n\nRun preflight:\n\n```bash\nscripts\u002Fpreflight.sh \u003Cuser_repo>\n```\n\nIt checks the repo is a git repo, the tree is clean, and that `gh` (authenticated) and `jq` are available. If it exits non-zero, surface the message verbatim and stop.\n\nRecord a verification baseline so Phase 7 can distinguish regressions from pre-existing failures. Use `mktemp` so concurrent runs don't clobber each other:\n\n```bash\nbaseline=$(mktemp -t skup-baseline.XXXXXX.json)\nscripts\u002Frun_tests.sh \u003Cuser_repo> --baseline \"$baseline\"\n```\n\nHold onto `$baseline`; Phase 7 needs it.\n\nFetch the upstream kit and capture its path:\n\n```bash\nkit_dir=$(scripts\u002Ffetch_kit.sh \u003Ckit> \u003Cbranch>)\n```\n\nHold onto `$kit_dir`; Phase 5 needs it. The script is idempotent: re-running with the same args fetches the latest branch tip rather than re-cloning.\n\nCreate the upgrade branch:\n\n```bash\ngit -C \u003Cuser_repo> checkout -b \"starter-kit-upgrade\u002F$(date +%Y%m%d-%H%M)-\u003Cfirst-slug>\"\n```\n\nIf the user is already on a `starter-kit-upgrade\u002F...` branch (a previous run that didn't get cleaned up), `checkout -b` will refuse if the new name collides. Don't auto-resolve: ask whether they want to **resume on that branch** (skip the `checkout -b`, keep going from where they were), **start fresh** (the new timestamped name will already differ by minute, so just retry — or bump to `+%Y%m%d-%H%M%S` if it's the same minute), or **abort** so they can clean up manually. Never delete the existing branch on their behalf.\n\nFrom this point on, every write goes to this branch.\n\n### Phase 5: Apply each selected feature\n\nFor each selected feature, in order:\n\n1. Classify. Run `scripts\u002Fclassify_feature.sh \u003Ckit_dir> \u003Csha> \u003Cuser_repo>`. Statuses:\n\n- `new`: file does not exist in user repo, exists at upstream HEAD. Safe to add.\n- `already-present`: user's file is byte-identical to upstream HEAD. Skip.\n- `differs`: user has the file and bytes differ from upstream HEAD. Surface.\n- `deleted-upstream`: upstream HEAD lacks the file but the user has it. Surface; default is keep theirs.\n- `lockfile`: manifest or lock file. Surface; never auto-merge.\n\nThe classifier compares only against upstream HEAD. The user's git history doesn't trace back to the kit's, so there's no \"before-image\" baseline to merge against; we don't try. The feature commit just enumerates which paths to look at.\n\n2. Later-edits check. Find which feature paths _later_ upstream commits also modified:\n\n```bash\nscripts\u002Flater_edits.sh \u003Ckit_dir> \u003Csha> \u003Cuser_repo>\n```\n\nEach path the script prints is a path where copying upstream HEAD's content pulls _later_ changes in too. Diff `\u003Csha>:\u003Cpath>` against `HEAD:\u003Cpath>`; if a non-whitespace hunk differs, scope to the feature commit (`git -C \u003Ckit_dir> show \u003Csha>:\u003Cpath>`) and note it in the report.\n\n**3. Apply `new` files.** The script writes upstream HEAD's content for each `new` path and stages it; everything else is left for steps 4–5:\n\n```bash\nscripts\u002Fapply_new_files.sh \u003Ckit_dir> \u003Csha> \u003Cuser_repo>\n```\n\nIt prints `applied \u003Cpath>` for each file written so you can collect the list for the feature's commit message and the report.\n\nBefore letting the script run, check for the rename gotcha (see Gotchas → \"Renamed paths\"). If a `new` path's basename already exists at a different location in the user's repo, surface to the user before applying.\n\n**4. Transitive-imports check.** New files often import helpers that aren't in the same feature commit. The script picks the right regex for the kit (Vue\u002FReact\u002FSvelte handle TS\u002FJS imports; Livewire handles Blade includes \u002F `x-` components \u002F `livewire:` tags):\n\n```bash\nscripts\u002Fscan_transitive_imports.sh \u003Ckit> \u003Cnew_files...>\n```\n\nOutput is `\u003Cfile>:\u003Cline>:\u003Cmatch>` per import. For each match, verify the corresponding helper file exists in the user's repo. If not, the new files won't compile\u002Frender; flag the missing target as a follow-up dependency the user needs to fetch (same walkthrough as `differs`).\n\n**5. Walk the user through `differs`, `deleted-upstream`, and `lockfile`.** One file at a time:\n\n- Show what upstream has: `git -C \u003Ckit_dir> show HEAD:\u003Cpath>` (or `\u003Csha>:\u003Cpath>` if `later_edits.sh` flagged this path).\n- Show their current file.\n- Show the diff between the two.\n- Ask the user to pick: take upstream wholesale (lossy; confirm first), keep theirs, or merge by hand (you produce a unified diff for reference; they write the result).\n- If they're unsure, ask once more with the diff in front of them. Still unsure → keep theirs and move on. Don't pick silently.\n- Stage whatever they chose: `git -C \u003Cuser_repo> add \u003Cpath>`.\n\nFor `lockfile`: never overwrite the manifest. Show the upstream diff for `composer.json` \u002F `package.json`, walk them through the relevant change, let them edit the manifest. Lockfile regeneration happens in Phase 6.\n\n**6. Commit the feature as one revertable unit:**\n\n```bash\ngit -C \u003Cuser_repo> commit -m \"starter-kit-upgrade: \u003Cfeature name>\n\nUpstream: laravel\u002F\u003Ckit>@\u003Csha>\nFiles added: \u003Clist>\nFiles updated (took upstream): \u003Clist>\nFiles updated (manual merge): \u003Clist>\nFiles kept as-is: \u003Clist>\"\n```\n\nIf the user wants to bail out at any point, leave the branch as-is. They can drop it with `git branch -D`.\n\n### Phase 6: Reconcile manifests if needed\n\nIf any feature touched a manifest, lockfiles are out of sync. After the user agrees, run:\n\n```bash\nscripts\u002Freconcile_manifests.sh \u003Cuser_repo>\n```\n\nThe script runs `composer install` (when `composer.json` + `composer.lock` are both present), auto-detects the JS package manager from the existing lockfile, runs `\u003Cpm> install`, and on failure (typically `ERESOLVE` after a major bump like Vite v7 → v8 or React 18 → 19) wipes `node_modules` + the lockfile and retries once.\n\nCommit lockfile updates as a separate `starter-kit-upgrade: dependency lockfiles` commit so they can be reverted independently.\n\n### Phase 7: Verify behavior preservation\n\nCompare against the baseline:\n\n```bash\nscripts\u002Frun_tests.sh \u003Cuser_repo> --compare \"$baseline\"\n```\n\nCompare mode runs PHP tests, JS typecheck, JS build (whichever exist) and reports only checks that were passing in the baseline and now fail. Pre-existing failures are not the upgrade's fault and don't block.\n\nIf a regression is reported:\n\n- Show the failing output from the per-check log file the script points to.\n- Recommend `git revert HEAD` first; if that doesn't fix it, revert again.\n- For multi-feature uncertainty, suggest `git bisect start \u003Cupgrade-branch> \u003Cprevious-branch>`.\n- Do not edit code to make the failing check pass; that violates the behavior contract.\n\nIf the project has no discoverable verification commands, say so explicitly in the report. Don't pretend verification happened.\n\n### Phase 8: Write the report\n\nWrite to `\u002Ftmp\u002Fstarter-kit-upgrade-report-\u003Cid>.md` (where `\u003Cid>` matches the upgrade branch's `starter-kit-upgrade\u002F\u003Cid>`) first; never silently into the user's repo. Stamping the id keeps concurrent runs and re-runs from clobbering each other. Show the path and ask whether they want it copied in as `STARTER_KIT_UPGRADE.md` or kept out of tree.\n\n```markdown\n# Starter Kit Upgrade Report\n\n- Date: \u003Cdate>\n- Kit: laravel\u002F\u003Ckit>\n- Branch tracked: \u003Cbranch>\n- Upgrade branch: starter-kit-upgrade\u002F\u003Cid>\n\n## Features applied\n\n- \u003Cfeature name> · laravel\u002F\u003Ckit>@\u003Csha> · \u003CN files>\n  - Applied: \u003Clist>\n  - Skipped: \u003Clist with reasons>\n  - Manual decisions: \u003Cif any, with reasoning>\n  - Later-edit drift avoided: \u003Cif any, with paths scoped manually>\n\n## Lockfile updates\n\n\u003Cwhich lock files were regenerated and how>\n\n## Verification\n\n- Baseline: \u003Cpath or summary>\n- Result: \u003CPASS \u002F REGRESSED:\u003Clist> \u002F NO-CHECKS>\n- Output: \u003Crelevant snippet>\n\n## How to revert\n\n- Drop a single feature: `git revert \u003Ccommit-sha>`\n- Discard everything: `git checkout \u003Cprevious-branch> && git branch -D starter-kit-upgrade\u002F\u003Cid>`\n```\n\n## Out of scope\n\n- Detecting which kit \"version\" the user started from. There is no reliable way; we don't pretend.\n- Reconciling dep version constraints automatically. We show; the user decides.\n- Forks of the starter kits. If the repo's structure isn't recognizable as one of the three official kits, refuse and explain.\n- Cross-kit migration (e.g. Vue → React).\n- Running linters \u002F formatters on applied files. The user runs their own tooling.\n",{"data":32,"body":33},{"name":4,"description":6},{"type":34,"children":35},"root",[36,45,115,122,128,213,218,224,287,292,298,303,606,612,617,624,629,844,883,888,1025,1030,1141,1168,1174,1179,1213,1389,1394,1427,1432,1460,1466,1476,1481,1487,1492,1527,1546,1559,1642,1654,1659,1720,1732,1737,1819,1876,1881,1887,1892,1908,1963,1968,1983,2049,2082,2106,2169,2182,2194,2220,2268,2288,2317,2380,2406,2414,2520,2532,2538,2543,2574,2624,2637,2643,2648,2695,2700,2705,2743,2748,2754,2791,3476,3482,3510],{"type":37,"tag":38,"props":39,"children":41},"element","h1",{"id":40},"laravel-starter-kit-upgrade",[42],{"type":43,"value":44},"text","Laravel Starter Kit Upgrade",{"type":37,"tag":46,"props":47,"children":48},"ul",{},[49,87,100,105,110],{"type":37,"tag":50,"props":51,"children":52},"li",{},[53,55,62,64,70,71,77,79,85],{"type":43,"value":54},"Users bootstrap from ",{"type":37,"tag":56,"props":57,"children":59},"code",{"className":58},[],[60],{"type":43,"value":61},"laravel\u002Fvue-starter-kit",{"type":43,"value":63},", ",{"type":37,"tag":56,"props":65,"children":67},{"className":66},[],[68],{"type":43,"value":69},"react-starter-kit",{"type":43,"value":63},{"type":37,"tag":56,"props":72,"children":74},{"className":73},[],[75],{"type":43,"value":76},"svelte-starter-kit",{"type":43,"value":78},", or ",{"type":37,"tag":56,"props":80,"children":82},{"className":81},[],[83],{"type":43,"value":84},"livewire-starter-kit",{"type":43,"value":86},", then customize. They own the code.",{"type":37,"tag":50,"props":88,"children":89},{},[90,92,98],{"type":43,"value":91},"We pick ",{"type":37,"tag":93,"props":94,"children":95},"strong",{},[96],{"type":43,"value":97},"specific features",{"type":43,"value":99}," from upstream (e.g. \"toast notifications\", \"2FA autofocus fix\"), not \"version upgrades.\"",{"type":37,"tag":50,"props":101,"children":102},{},[103],{"type":43,"value":104},"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.",{"type":37,"tag":50,"props":106,"children":107},{},[108],{"type":43,"value":109},"We never auto-merge a customized file. Customizations are surfaced; the user decides.",{"type":37,"tag":50,"props":111,"children":112},{},[113],{"type":43,"value":114},"Behavior preservation is the contract: the user's currently-passing tests\u002Ftypecheck\u002Fbuild must still pass after.",{"type":37,"tag":116,"props":117,"children":119},"h2",{"id":118},"safety-contract-non-negotiable",[120],{"type":43,"value":121},"Safety contract: non-negotiable",{"type":37,"tag":123,"props":124,"children":125},"p",{},[126],{"type":43,"value":127},"Read these to the user before any side effects, and live by them throughout:",{"type":37,"tag":129,"props":130,"children":131},"ol",{},[132,145,158,163,168,195,200],{"type":37,"tag":50,"props":133,"children":134},{},[135,137,143],{"type":43,"value":136},"Working tree must be clean. If ",{"type":37,"tag":56,"props":138,"children":140},{"className":139},[],[141],{"type":43,"value":142},"git status --porcelain",{"type":43,"value":144}," is non-empty, refuse and tell the user to commit or stash. Do not \"stash for them.\"",{"type":37,"tag":50,"props":146,"children":147},{},[148,150,156],{"type":43,"value":149},"All work happens on a dedicated branch (",{"type":37,"tag":56,"props":151,"children":153},{"className":152},[],[154],{"type":43,"value":155},"starter-kit-upgrade\u002F\u003Cshort-id>",{"type":43,"value":157},"). The user's current branch is never modified.",{"type":37,"tag":50,"props":159,"children":160},{},[161],{"type":43,"value":162},"Each applied feature is its own commit. That is how revertability works.",{"type":37,"tag":50,"props":164,"children":165},{},[166],{"type":43,"value":167},"Never auto-resolve conflicts. A change touching customized code is surfaced; default action is to skip the file.",{"type":37,"tag":50,"props":169,"children":170},{},[171,173,179,180,186,187,193],{"type":43,"value":172},"Never silently overwrite manifests or lockfiles (",{"type":37,"tag":56,"props":174,"children":176},{"className":175},[],[177],{"type":43,"value":178},"composer.json",{"type":43,"value":63},{"type":37,"tag":56,"props":181,"children":183},{"className":182},[],[184],{"type":43,"value":185},"package.json",{"type":43,"value":63},{"type":37,"tag":56,"props":188,"children":190},{"className":189},[],[191],{"type":43,"value":192},"*-lock.*",{"type":43,"value":194},"). Show diffs; let the user decide.",{"type":37,"tag":50,"props":196,"children":197},{},[198],{"type":43,"value":199},"Verify behavior preservation. Re-run the user's tests\u002Ftypecheck\u002Fbuild after applying. A previously-passing check that now fails is a regression. Stop, surface, recommend revert.",{"type":37,"tag":50,"props":201,"children":202},{},[203,205,211],{"type":43,"value":204},"Detect from unambiguous signals; ask when ambiguous. Concrete evidence (e.g. ",{"type":37,"tag":56,"props":206,"children":208},{"className":207},[],[209],{"type":43,"value":210},"config\u002Ffortify.php",{"type":43,"value":212}," exists) is fine. Picking a likely answer when signals are mixed or absent is not.",{"type":37,"tag":123,"props":214,"children":215},{},[216],{"type":43,"value":217},"If any of these is violated, abort with a clear message about what went wrong and how to recover.",{"type":37,"tag":116,"props":219,"children":221},{"id":220},"required-tools",[222],{"type":43,"value":223},"Required tools",{"type":37,"tag":46,"props":225,"children":226},{},[227,238,257,276],{"type":37,"tag":50,"props":228,"children":229},{},[230,236],{"type":37,"tag":56,"props":231,"children":233},{"className":232},[],[234],{"type":43,"value":235},"git",{"type":43,"value":237}," (in the user's project)",{"type":37,"tag":50,"props":239,"children":240},{},[241,247,249,255],{"type":37,"tag":56,"props":242,"children":244},{"className":243},[],[245],{"type":43,"value":246},"gh",{"type":43,"value":248}," (authenticated; ",{"type":37,"tag":56,"props":250,"children":252},{"className":251},[],[253],{"type":43,"value":254},"gh auth status",{"type":43,"value":256}," returns OK)",{"type":37,"tag":50,"props":258,"children":259},{},[260,266,268,274],{"type":37,"tag":56,"props":261,"children":263},{"className":262},[],[264],{"type":43,"value":265},"jq",{"type":43,"value":267}," (used by ",{"type":37,"tag":56,"props":269,"children":271},{"className":270},[],[272],{"type":43,"value":273},"run_tests.sh",{"type":43,"value":275},")",{"type":37,"tag":50,"props":277,"children":278},{},[279,285],{"type":37,"tag":56,"props":280,"children":282},{"className":281},[],[283],{"type":43,"value":284},"bash",{"type":43,"value":286}," (for the bundled scripts)",{"type":37,"tag":123,"props":288,"children":289},{},[290],{"type":43,"value":291},"If any is missing, stop in Phase 4 and tell the user how to install.",{"type":37,"tag":116,"props":293,"children":295},{"id":294},"gotchas",[296],{"type":43,"value":297},"Gotchas",{"type":37,"tag":123,"props":299,"children":300},{},[301],{"type":43,"value":302},"Environment-specific behavior the agent will get wrong without being told. Read these before starting the workflow and apply throughout.",{"type":37,"tag":46,"props":304,"children":305},{},[306,339,356,390,445,455,481,499,572,590],{"type":37,"tag":50,"props":307,"children":308},{},[309,314,316,322,324,330,332,337],{"type":37,"tag":93,"props":310,"children":311},{},[312],{"type":43,"value":313},"Parallel implementations.",{"type":43,"value":315}," When a feature has ",{"type":37,"tag":56,"props":317,"children":319},{"className":318},[],[320],{"type":43,"value":321},"new",{"type":43,"value":323}," files plus ",{"type":37,"tag":56,"props":325,"children":327},{"className":326},[],[328],{"type":43,"value":329},"differs",{"type":43,"value":331}," 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 ",{"type":37,"tag":56,"props":333,"children":335},{"className":334},[],[336],{"type":43,"value":321},{"type":43,"value":338}," 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.",{"type":37,"tag":50,"props":340,"children":341},{},[342,347,349,354],{"type":37,"tag":93,"props":343,"children":344},{},[345],{"type":43,"value":346},"Renamed paths.",{"type":43,"value":348}," If a ",{"type":37,"tag":56,"props":350,"children":352},{"className":351},[],[353],{"type":43,"value":321},{"type":43,"value":355}," path's basename or class name already exists elsewhere in the user's repo, the user has likely renamed\u002Fmoved 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.",{"type":37,"tag":50,"props":357,"children":358},{},[359,364,366,372,374,380,382,388],{"type":37,"tag":93,"props":360,"children":361},{},[362],{"type":43,"value":363},"Later upstream edits.",{"type":43,"value":365}," Copying upstream HEAD pulls in ",{"type":37,"tag":367,"props":368,"children":369},"em",{},[370],{"type":43,"value":371},"every",{"type":43,"value":373}," 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 ",{"type":37,"tag":56,"props":375,"children":377},{"className":376},[],[378],{"type":43,"value":379},"\u003Csha>:\u003Cpath>",{"type":43,"value":381}," instead of ",{"type":37,"tag":56,"props":383,"children":385},{"className":384},[],[386],{"type":43,"value":387},"HEAD:\u003Cpath>",{"type":43,"value":389},".",{"type":37,"tag":50,"props":391,"children":392},{},[393,398,400,406,408,414,415,421,423,429,430,436,437,443],{"type":37,"tag":93,"props":394,"children":395},{},[396],{"type":43,"value":397},"Transitive imports.",{"type":43,"value":399}," New files often ",{"type":37,"tag":56,"props":401,"children":403},{"className":402},[],[404],{"type":43,"value":405},"import",{"type":43,"value":407}," from helpers that are NOT in the same feature commit (Vue\u002FReact\u002FSvelte: ",{"type":37,"tag":56,"props":409,"children":411},{"className":410},[],[412],{"type":43,"value":413},"@\u002Flib\u002F...",{"type":43,"value":63},{"type":37,"tag":56,"props":416,"children":418},{"className":417},[],[419],{"type":43,"value":420},"@\u002Fcomponents\u002F...",{"type":43,"value":422},"; Livewire: ",{"type":37,"tag":56,"props":424,"children":426},{"className":425},[],[427],{"type":43,"value":428},"@include",{"type":43,"value":63},{"type":37,"tag":56,"props":431,"children":433},{"className":432},[],[434],{"type":43,"value":435},"\u003Cx-...>",{"type":43,"value":63},{"type":37,"tag":56,"props":438,"children":440},{"className":439},[],[441],{"type":43,"value":442},"\u003Clivewire:...>",{"type":43,"value":444},"). Phase 5 step 4 covers the scan; never declare a feature applied without it. Uncovered imports show up as runtime\u002Fcompile errors.",{"type":37,"tag":50,"props":446,"children":447},{},[448,453],{"type":37,"tag":93,"props":449,"children":450},{},[451],{"type":43,"value":452},"Lockfile drift.",{"type":43,"value":454}," 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).",{"type":37,"tag":50,"props":456,"children":457},{},[458,463,465,471,473,479],{"type":37,"tag":93,"props":459,"children":460},{},[461],{"type":43,"value":462},"Stale node_modules after major bumps.",{"type":43,"value":464}," After Vite v7 → v8, React 18 → 19, etc., ",{"type":37,"tag":56,"props":466,"children":468},{"className":467},[],[469],{"type":43,"value":470},"npm install",{"type":43,"value":472}," often fails with ",{"type":37,"tag":56,"props":474,"children":476},{"className":475},[],[477],{"type":43,"value":478},"ERESOLVE",{"type":43,"value":480},". Clean and reinstall (Phase 6).",{"type":37,"tag":50,"props":482,"children":483},{},[484,489,491,497],{"type":37,"tag":93,"props":485,"children":486},{},[487],{"type":43,"value":488},"New migrations.",{"type":43,"value":490}," When upstream adds migrations (e.g. \"Catch migrations up to Skeleton\"), surface them separately. Recommend ",{"type":37,"tag":56,"props":492,"children":494},{"className":493},[],[495],{"type":43,"value":496},"php artisan migrate:status",{"type":43,"value":498}," first; applying a new migration on a populated DB can fail loudly.",{"type":37,"tag":50,"props":500,"children":501},{},[502,507,509,518,520,526,528,534,536],{"type":37,"tag":93,"props":503,"children":504},{},[505],{"type":43,"value":506},"Major framework bumps as features.",{"type":43,"value":508}," 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 ",{"type":37,"tag":510,"props":511,"children":515},"a",{"href":512,"rel":513},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fboost",[514],"nofollow",[516],{"type":43,"value":517},"Laravel Boost",{"type":43,"value":519}," MCP slash command first, then come back and re-run this skill against the resulting (clean-tree) repo. If Boost is not yet installed: ",{"type":37,"tag":56,"props":521,"children":523},{"className":522},[],[524],{"type":43,"value":525},"composer require laravel\u002Fboost --dev && php artisan boost:install",{"type":43,"value":527}," (requires Boost ",{"type":37,"tag":56,"props":529,"children":531},{"className":530},[],[532],{"type":43,"value":533},"^2.0",{"type":43,"value":535},"). Slash commands:",{"type":37,"tag":46,"props":537,"children":538},{},[539,550,561],{"type":37,"tag":50,"props":540,"children":541},{},[542,544],{"type":43,"value":543},"Laravel 12 → 13: ",{"type":37,"tag":56,"props":545,"children":547},{"className":546},[],[548],{"type":43,"value":549},"\u002Fupgrade-laravel-v13",{"type":37,"tag":50,"props":551,"children":552},{},[553,555],{"type":43,"value":554},"Livewire 3 → 4: ",{"type":37,"tag":56,"props":556,"children":558},{"className":557},[],[559],{"type":43,"value":560},"\u002Fupgrade-livewire-v4",{"type":37,"tag":50,"props":562,"children":563},{},[564,566],{"type":43,"value":565},"Inertia v2 → v3: ",{"type":37,"tag":56,"props":567,"children":569},{"className":568},[],[570],{"type":43,"value":571},"\u002Fupgrade-inertia-v3",{"type":37,"tag":50,"props":573,"children":574},{},[575,580,582,588],{"type":37,"tag":93,"props":576,"children":577},{},[578],{"type":43,"value":579},"Already-present features.",{"type":43,"value":581}," If Phase 2's pre-filter missed it and Phase 5's classifier reports every file as ",{"type":37,"tag":56,"props":583,"children":585},{"className":584},[],[586],{"type":43,"value":587},"already-present",{"type":43,"value":589},", skip the feature with a note: \"every file matches upstream's current; moving on.\" Don't commit an empty commit.",{"type":37,"tag":50,"props":591,"children":592},{},[593,604],{"type":37,"tag":93,"props":594,"children":595},{},[596,598,603],{"type":43,"value":597},"More than ~50 ",{"type":37,"tag":56,"props":599,"children":601},{"className":600},[],[602],{"type":43,"value":329},{"type":43,"value":389},{"type":43,"value":605}," The per-file walkthrough is too tedious to be useful at that scale. Stop, recommend manual upgrade for that feature.",{"type":37,"tag":116,"props":607,"children":609},{"id":608},"workflow",[610],{"type":43,"value":611},"Workflow",{"type":37,"tag":123,"props":613,"children":614},{},[615],{"type":43,"value":616},"Eight phases, in order. Each phase establishes invariants the next relies on.",{"type":37,"tag":618,"props":619,"children":621},"h3",{"id":620},"phase-1-identify-the-kit-and-branch-variant",[622],{"type":43,"value":623},"Phase 1: Identify the kit and branch variant",{"type":37,"tag":123,"props":625,"children":626},{},[627],{"type":43,"value":628},"Inspect the user's project:",{"type":37,"tag":630,"props":631,"children":632},"table",{},[633,665],{"type":37,"tag":634,"props":635,"children":636},"thead",{},[637],{"type":37,"tag":638,"props":639,"children":640},"tr",{},[641,645,650,655,660],{"type":37,"tag":642,"props":643,"children":644},"th",{},[],{"type":37,"tag":642,"props":646,"children":647},{},[648],{"type":43,"value":649},"vue",{"type":37,"tag":642,"props":651,"children":652},{},[653],{"type":43,"value":654},"react",{"type":37,"tag":642,"props":656,"children":657},{},[658],{"type":43,"value":659},"svelte",{"type":37,"tag":642,"props":661,"children":662},{},[663],{"type":43,"value":664},"livewire",{"type":37,"tag":666,"props":667,"children":668},"tbody",{},[669,737,804],{"type":37,"tag":638,"props":670,"children":671},{},[672,678,695,710,725],{"type":37,"tag":673,"props":674,"children":675},"td",{},[676],{"type":43,"value":677},"Cue",{"type":37,"tag":673,"props":679,"children":680},{},[681,687,689],{"type":37,"tag":56,"props":682,"children":684},{"className":683},[],[685],{"type":43,"value":686},".vue",{"type":43,"value":688}," files in ",{"type":37,"tag":56,"props":690,"children":692},{"className":691},[],[693],{"type":43,"value":694},"resources\u002Fjs\u002Fcomponents\u002Fui\u002F",{"type":37,"tag":673,"props":696,"children":697},{},[698,704,705],{"type":37,"tag":56,"props":699,"children":701},{"className":700},[],[702],{"type":43,"value":703},".tsx",{"type":43,"value":688},{"type":37,"tag":56,"props":706,"children":708},{"className":707},[],[709],{"type":43,"value":694},{"type":37,"tag":673,"props":711,"children":712},{},[713,719,720],{"type":37,"tag":56,"props":714,"children":716},{"className":715},[],[717],{"type":43,"value":718},".svelte",{"type":43,"value":688},{"type":37,"tag":56,"props":721,"children":723},{"className":722},[],[724],{"type":43,"value":694},{"type":37,"tag":673,"props":726,"children":727},{},[728,730,735],{"type":43,"value":729},"no ",{"type":37,"tag":56,"props":731,"children":733},{"className":732},[],[734],{"type":43,"value":694},{"type":43,"value":736}," dir",{"type":37,"tag":638,"props":738,"children":739},{},[740,750,767,783,799],{"type":37,"tag":673,"props":741,"children":742},{},[743,748],{"type":37,"tag":56,"props":744,"children":746},{"className":745},[],[747],{"type":43,"value":185},{"type":43,"value":749}," has",{"type":37,"tag":673,"props":751,"children":752},{},[753,759,761],{"type":37,"tag":56,"props":754,"children":756},{"className":755},[],[757],{"type":43,"value":758},"\"vue\"",{"type":43,"value":760}," + ",{"type":37,"tag":56,"props":762,"children":764},{"className":763},[],[765],{"type":43,"value":766},"\"@inertiajs\u002Fvue3\"",{"type":37,"tag":673,"props":768,"children":769},{},[770,776,777],{"type":37,"tag":56,"props":771,"children":773},{"className":772},[],[774],{"type":43,"value":775},"\"react\"",{"type":43,"value":760},{"type":37,"tag":56,"props":778,"children":780},{"className":779},[],[781],{"type":43,"value":782},"\"@inertiajs\u002Freact\"",{"type":37,"tag":673,"props":784,"children":785},{},[786,792,793],{"type":37,"tag":56,"props":787,"children":789},{"className":788},[],[790],{"type":43,"value":791},"\"svelte\"",{"type":43,"value":760},{"type":37,"tag":56,"props":794,"children":796},{"className":795},[],[797],{"type":43,"value":798},"\"@inertiajs\u002Fsvelte\"",{"type":37,"tag":673,"props":800,"children":801},{},[802],{"type":43,"value":803},"n\u002Fa",{"type":37,"tag":638,"props":805,"children":806},{},[807,816,820,824,828],{"type":37,"tag":673,"props":808,"children":809},{},[810,815],{"type":37,"tag":56,"props":811,"children":813},{"className":812},[],[814],{"type":43,"value":178},{"type":43,"value":749},{"type":37,"tag":673,"props":817,"children":818},{},[819],{"type":43,"value":803},{"type":37,"tag":673,"props":821,"children":822},{},[823],{"type":43,"value":803},{"type":37,"tag":673,"props":825,"children":826},{},[827],{"type":43,"value":803},{"type":37,"tag":673,"props":829,"children":830},{},[831,837,838],{"type":37,"tag":56,"props":832,"children":834},{"className":833},[],[835],{"type":43,"value":836},"\"livewire\u002Flivewire\"",{"type":43,"value":760},{"type":37,"tag":56,"props":839,"children":841},{"className":840},[],[842],{"type":43,"value":843},"\"livewire\u002Fflux\"",{"type":37,"tag":123,"props":845,"children":846},{},[847,849,854,856,861,863,868,870,875,876,881],{"type":43,"value":848},"State the detected kit out loud. If only one column matches, proceed. If two columns partially match (e.g. both ",{"type":37,"tag":56,"props":850,"children":852},{"className":851},[],[853],{"type":43,"value":686},{"type":43,"value":855}," and ",{"type":37,"tag":56,"props":857,"children":859},{"className":858},[],[860],{"type":43,"value":703},{"type":43,"value":862}," present, or ",{"type":37,"tag":56,"props":864,"children":866},{"className":865},[],[867],{"type":43,"value":185},{"type":43,"value":869}," lists ",{"type":37,"tag":56,"props":871,"children":873},{"className":872},[],[874],{"type":43,"value":649},{"type":43,"value":855},{"type":37,"tag":56,"props":877,"children":879},{"className":878},[],[880],{"type":43,"value":654},{"type":43,"value":882},"), stop and ask.",{"type":37,"tag":123,"props":884,"children":885},{},[886],{"type":43,"value":887},"Then determine the branch variant. There are four branches per kit, formed by two independent axes:",{"type":37,"tag":46,"props":889,"children":890},{},[891,971],{"type":37,"tag":50,"props":892,"children":893},{},[894,899,901,906,908],{"type":37,"tag":93,"props":895,"children":896},{},[897],{"type":43,"value":898},"Auth axis",{"type":43,"value":900}," (read ",{"type":37,"tag":56,"props":902,"children":904},{"className":903},[],[905],{"type":43,"value":178},{"type":43,"value":907},"):\n",{"type":37,"tag":46,"props":909,"children":910},{},[911,952],{"type":37,"tag":50,"props":912,"children":913},{},[914,916,921,923,929,930,935,937,943,944,950],{"type":43,"value":915},"Fortify if ",{"type":37,"tag":56,"props":917,"children":919},{"className":918},[],[920],{"type":43,"value":178},{"type":43,"value":922}," has ",{"type":37,"tag":56,"props":924,"children":926},{"className":925},[],[927],{"type":43,"value":928},"laravel\u002Ffortify",{"type":43,"value":78},{"type":37,"tag":56,"props":931,"children":933},{"className":932},[],[934],{"type":43,"value":210},{"type":43,"value":936}," exists, or ",{"type":37,"tag":56,"props":938,"children":940},{"className":939},[],[941],{"type":43,"value":942},"app\u002FActions\u002FFortify\u002F",{"type":43,"value":936},{"type":37,"tag":56,"props":945,"children":947},{"className":946},[],[948],{"type":43,"value":949},"app\u002FProviders\u002FFortifyServiceProvider.php",{"type":43,"value":951}," exists.",{"type":37,"tag":50,"props":953,"children":954},{},[955,957,962,963,969],{"type":43,"value":956},"WorkOS if ",{"type":37,"tag":56,"props":958,"children":960},{"className":959},[],[961],{"type":43,"value":178},{"type":43,"value":922},{"type":37,"tag":56,"props":964,"children":966},{"className":965},[],[967],{"type":43,"value":968},"laravel\u002Fworkos",{"type":43,"value":970}," and none of the Fortify markers are present.",{"type":37,"tag":50,"props":972,"children":973},{},[974,979,981],{"type":37,"tag":93,"props":975,"children":976},{},[977],{"type":43,"value":978},"Teams axis",{"type":43,"value":980}," (check whether team scaffolding is present):\n",{"type":37,"tag":46,"props":982,"children":983},{},[984,1020],{"type":37,"tag":50,"props":985,"children":986},{},[987,989,995,997,1003,1004,1010,1012,1018],{"type":43,"value":988},"Teams if ",{"type":37,"tag":56,"props":990,"children":992},{"className":991},[],[993],{"type":43,"value":994},"app\u002FModels\u002FTeam.php",{"type":43,"value":996}," exists (usually accompanied by ",{"type":37,"tag":56,"props":998,"children":1000},{"className":999},[],[1001],{"type":43,"value":1002},"Membership.php",{"type":43,"value":63},{"type":37,"tag":56,"props":1005,"children":1007},{"className":1006},[],[1008],{"type":43,"value":1009},"TeamInvitation.php",{"type":43,"value":1011},", and a ",{"type":37,"tag":56,"props":1013,"children":1015},{"className":1014},[],[1016],{"type":43,"value":1017},"..._create_teams_table.php",{"type":43,"value":1019}," migration).",{"type":37,"tag":50,"props":1021,"children":1022},{},[1023],{"type":43,"value":1024},"Non-teams otherwise.",{"type":37,"tag":123,"props":1026,"children":1027},{},[1028],{"type":43,"value":1029},"Combine the two axes to get the branch name:",{"type":37,"tag":630,"props":1031,"children":1032},{},[1033,1054],{"type":37,"tag":634,"props":1034,"children":1035},{},[1036],{"type":37,"tag":638,"props":1037,"children":1038},{},[1039,1044,1049],{"type":37,"tag":642,"props":1040,"children":1041},{},[1042],{"type":43,"value":1043},"Auth",{"type":37,"tag":642,"props":1045,"children":1046},{},[1047],{"type":43,"value":1048},"Teams",{"type":37,"tag":642,"props":1050,"children":1051},{},[1052],{"type":43,"value":1053},"Branch",{"type":37,"tag":666,"props":1055,"children":1056},{},[1057,1079,1100,1121],{"type":37,"tag":638,"props":1058,"children":1059},{},[1060,1065,1070],{"type":37,"tag":673,"props":1061,"children":1062},{},[1063],{"type":43,"value":1064},"Fortify",{"type":37,"tag":673,"props":1066,"children":1067},{},[1068],{"type":43,"value":1069},"no",{"type":37,"tag":673,"props":1071,"children":1072},{},[1073],{"type":37,"tag":56,"props":1074,"children":1076},{"className":1075},[],[1077],{"type":43,"value":1078},"main",{"type":37,"tag":638,"props":1080,"children":1081},{},[1082,1086,1091],{"type":37,"tag":673,"props":1083,"children":1084},{},[1085],{"type":43,"value":1064},{"type":37,"tag":673,"props":1087,"children":1088},{},[1089],{"type":43,"value":1090},"yes",{"type":37,"tag":673,"props":1092,"children":1093},{},[1094],{"type":37,"tag":56,"props":1095,"children":1097},{"className":1096},[],[1098],{"type":43,"value":1099},"teams",{"type":37,"tag":638,"props":1101,"children":1102},{},[1103,1108,1112],{"type":37,"tag":673,"props":1104,"children":1105},{},[1106],{"type":43,"value":1107},"WorkOS",{"type":37,"tag":673,"props":1109,"children":1110},{},[1111],{"type":43,"value":1069},{"type":37,"tag":673,"props":1113,"children":1114},{},[1115],{"type":37,"tag":56,"props":1116,"children":1118},{"className":1117},[],[1119],{"type":43,"value":1120},"workos",{"type":37,"tag":638,"props":1122,"children":1123},{},[1124,1128,1132],{"type":37,"tag":673,"props":1125,"children":1126},{},[1127],{"type":43,"value":1107},{"type":37,"tag":673,"props":1129,"children":1130},{},[1131],{"type":43,"value":1090},{"type":37,"tag":673,"props":1133,"children":1134},{},[1135],{"type":37,"tag":56,"props":1136,"children":1138},{"className":1137},[],[1139],{"type":43,"value":1140},"workos-teams",{"type":37,"tag":123,"props":1142,"children":1143},{},[1144,1146,1151,1153,1158,1160,1166],{"type":43,"value":1145},"State the detected branch out loud. Only ask if signals are contradictory (e.g. Fortify markers present ",{"type":37,"tag":367,"props":1147,"children":1148},{},[1149],{"type":43,"value":1150},"and",{"type":43,"value":1152}," ",{"type":37,"tag":56,"props":1154,"children":1156},{"className":1155},[],[1157],{"type":43,"value":968},{"type":43,"value":1159}," in composer, or a ",{"type":37,"tag":56,"props":1161,"children":1163},{"className":1162},[],[1164],{"type":43,"value":1165},"Team.php",{"type":43,"value":1167}," model with no teams migration); that means user customization you can't safely guess at.",{"type":37,"tag":618,"props":1169,"children":1171},{"id":1170},"phase-2-enumerate-available-upstream-features",[1172],{"type":43,"value":1173},"Phase 2: Enumerate available upstream features",{"type":37,"tag":123,"props":1175,"children":1176},{},[1177],{"type":43,"value":1178},"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 feature catalog.",{"type":37,"tag":123,"props":1180,"children":1181},{},[1182,1184,1189,1191,1197,1198,1204,1206,1212],{"type":43,"value":1183},"Fetch raw data. The default window is the ",{"type":37,"tag":93,"props":1185,"children":1186},{},[1187],{"type":43,"value":1188},"last 100 commits \u002F merged PRs",{"type":43,"value":1190},"; tell the user that up front so they know features older than that won't appear in the catalog. If they bootstrapped well before that window, walk back with ",{"type":37,"tag":56,"props":1192,"children":1194},{"className":1193},[],[1195],{"type":43,"value":1196},"&page=2",{"type":43,"value":63},{"type":37,"tag":56,"props":1199,"children":1201},{"className":1200},[],[1202],{"type":43,"value":1203},"&page=3",{"type":43,"value":1205},", etc. or raise ",{"type":37,"tag":56,"props":1207,"children":1209},{"className":1208},[],[1210],{"type":43,"value":1211},"--limit",{"type":43,"value":389},{"type":37,"tag":1214,"props":1215,"children":1219},"pre",{"className":1216,"code":1217,"language":284,"meta":1218,"style":1218},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","gh api \"repos\u002Flaravel\u002F\u003Ckit>\u002Fcommits?sha=\u003Cbranch>&per_page=100\" \\\n  -q '.[] | {sha: .sha[0:7], date: .commit.author.date[0:10], msg: .commit.message | split(\"\\n\")[0]}'\n\ngh pr list --repo \"laravel\u002F\u003Ckit>\" --state merged --base \"\u003Cbranch>\" --limit 100 \\\n  --json number,title,mergeCommit,mergedAt\n","",[1220],{"type":37,"tag":56,"props":1221,"children":1222},{"__ignoreMap":1218},[1223,1262,1286,1296,1375],{"type":37,"tag":1224,"props":1225,"children":1228},"span",{"class":1226,"line":1227},"line",1,[1229,1234,1240,1246,1251,1256],{"type":37,"tag":1224,"props":1230,"children":1232},{"style":1231},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[1233],{"type":43,"value":246},{"type":37,"tag":1224,"props":1235,"children":1237},{"style":1236},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[1238],{"type":43,"value":1239}," api",{"type":37,"tag":1224,"props":1241,"children":1243},{"style":1242},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[1244],{"type":43,"value":1245}," \"",{"type":37,"tag":1224,"props":1247,"children":1248},{"style":1236},[1249],{"type":43,"value":1250},"repos\u002Flaravel\u002F\u003Ckit>\u002Fcommits?sha=\u003Cbranch>&per_page=100",{"type":37,"tag":1224,"props":1252,"children":1253},{"style":1242},[1254],{"type":43,"value":1255},"\"",{"type":37,"tag":1224,"props":1257,"children":1259},{"style":1258},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[1260],{"type":43,"value":1261}," \\\n",{"type":37,"tag":1224,"props":1263,"children":1265},{"class":1226,"line":1264},2,[1266,1271,1276,1281],{"type":37,"tag":1224,"props":1267,"children":1268},{"style":1236},[1269],{"type":43,"value":1270},"  -q",{"type":37,"tag":1224,"props":1272,"children":1273},{"style":1242},[1274],{"type":43,"value":1275}," '",{"type":37,"tag":1224,"props":1277,"children":1278},{"style":1236},[1279],{"type":43,"value":1280},".[] | {sha: .sha[0:7], date: .commit.author.date[0:10], msg: .commit.message | split(\"\\n\")[0]}",{"type":37,"tag":1224,"props":1282,"children":1283},{"style":1242},[1284],{"type":43,"value":1285},"'\n",{"type":37,"tag":1224,"props":1287,"children":1289},{"class":1226,"line":1288},3,[1290],{"type":37,"tag":1224,"props":1291,"children":1293},{"emptyLinePlaceholder":1292},true,[1294],{"type":43,"value":1295},"\n",{"type":37,"tag":1224,"props":1297,"children":1299},{"class":1226,"line":1298},4,[1300,1304,1309,1314,1319,1323,1328,1332,1337,1342,1347,1351,1356,1360,1365,1371],{"type":37,"tag":1224,"props":1301,"children":1302},{"style":1231},[1303],{"type":43,"value":246},{"type":37,"tag":1224,"props":1305,"children":1306},{"style":1236},[1307],{"type":43,"value":1308}," pr",{"type":37,"tag":1224,"props":1310,"children":1311},{"style":1236},[1312],{"type":43,"value":1313}," list",{"type":37,"tag":1224,"props":1315,"children":1316},{"style":1236},[1317],{"type":43,"value":1318}," --repo",{"type":37,"tag":1224,"props":1320,"children":1321},{"style":1242},[1322],{"type":43,"value":1245},{"type":37,"tag":1224,"props":1324,"children":1325},{"style":1236},[1326],{"type":43,"value":1327},"laravel\u002F\u003Ckit>",{"type":37,"tag":1224,"props":1329,"children":1330},{"style":1242},[1331],{"type":43,"value":1255},{"type":37,"tag":1224,"props":1333,"children":1334},{"style":1236},[1335],{"type":43,"value":1336}," --state",{"type":37,"tag":1224,"props":1338,"children":1339},{"style":1236},[1340],{"type":43,"value":1341}," merged",{"type":37,"tag":1224,"props":1343,"children":1344},{"style":1236},[1345],{"type":43,"value":1346}," --base",{"type":37,"tag":1224,"props":1348,"children":1349},{"style":1242},[1350],{"type":43,"value":1245},{"type":37,"tag":1224,"props":1352,"children":1353},{"style":1236},[1354],{"type":43,"value":1355},"\u003Cbranch>",{"type":37,"tag":1224,"props":1357,"children":1358},{"style":1242},[1359],{"type":43,"value":1255},{"type":37,"tag":1224,"props":1361,"children":1362},{"style":1236},[1363],{"type":43,"value":1364}," --limit",{"type":37,"tag":1224,"props":1366,"children":1368},{"style":1367},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[1369],{"type":43,"value":1370}," 100",{"type":37,"tag":1224,"props":1372,"children":1373},{"style":1258},[1374],{"type":43,"value":1261},{"type":37,"tag":1224,"props":1376,"children":1378},{"class":1226,"line":1377},5,[1379,1384],{"type":37,"tag":1224,"props":1380,"children":1381},{"style":1236},[1382],{"type":43,"value":1383},"  --json",{"type":37,"tag":1224,"props":1385,"children":1386},{"style":1236},[1387],{"type":43,"value":1388}," number,title,mergeCommit,mergedAt\n",{"type":37,"tag":123,"props":1390,"children":1391},{},[1392],{"type":43,"value":1393},"Cluster commits\u002FPRs into user-facing features. Examples a user would recognize:",{"type":37,"tag":46,"props":1395,"children":1396},{},[1397,1402,1407,1412,1417,1422],{"type":37,"tag":50,"props":1398,"children":1399},{},[1400],{"type":43,"value":1401},"\"Toast notifications across all kits\" (1 commit, several files)",{"type":37,"tag":50,"props":1403,"children":1404},{},[1405],{"type":43,"value":1406},"\"Password visibility toggle in auth forms\" (1 commit, 3 files)",{"type":37,"tag":50,"props":1408,"children":1409},{},[1410],{"type":43,"value":1411},"\"2FA autofocus fix\" (1 commit, 1 file)",{"type":37,"tag":50,"props":1413,"children":1414},{},[1415],{"type":43,"value":1416},"\"Teams support\" (1 PR, many files; flag as large)",{"type":37,"tag":50,"props":1418,"children":1419},{},[1420],{"type":43,"value":1421},"\"Inertia 3 upgrade\" (lockfile-heavy; flag as needing review)",{"type":37,"tag":50,"props":1423,"children":1424},{},[1425],{"type":43,"value":1426},"\"Maintenance: formatting \u002F lint config\" (bucket of small commits)",{"type":37,"tag":123,"props":1428,"children":1429},{},[1430],{"type":43,"value":1431},"Bucket internal\u002Frefactor commits as a single \"Maintenance\" entry. The user usually skips it.",{"type":37,"tag":123,"props":1433,"children":1434},{},[1435,1437,1443,1445,1450,1452,1458],{"type":43,"value":1436},"Pre-filter: for each candidate feature, run ",{"type":37,"tag":56,"props":1438,"children":1440},{"className":1439},[],[1441],{"type":43,"value":1442},"scripts\u002Fclassify_feature.sh",{"type":43,"value":1444}," against its commit. If every file is ",{"type":37,"tag":56,"props":1446,"children":1448},{"className":1447},[],[1449],{"type":43,"value":587},{"type":43,"value":1451},", mark ",{"type":37,"tag":56,"props":1453,"children":1455},{"className":1454},[],[1456],{"type":43,"value":1457},"[!] Already present",{"type":43,"value":1459}," and skip by default.",{"type":37,"tag":618,"props":1461,"children":1463},{"id":1462},"phase-3-present-the-catalog-and-get-explicit-selection",[1464],{"type":43,"value":1465},"Phase 3: Present the catalog and get explicit selection",{"type":37,"tag":1214,"props":1467,"children":1471},{"className":1468,"code":1470,"language":43},[1469],"language-text","Available upstream features (vue-starter-kit, branch: main):\n\n[ ] Toast notifications              · PR #142, 4 files, 1 lockfile\n[ ] Password visibility toggle       · PR #131, 3 files\n[ ] 2FA autofocus fix                · commit 78fda0c, 1 file\n[ ] Teams support                    · PR #98, 23 files (LARGE)\n[~] Inertia 3 upgrade                · PR #110, lockfile-heavy (review carefully)\n[!] Already present: Vite font plugin\n\nWhich would you like to pull in?\n",[1472],{"type":37,"tag":56,"props":1473,"children":1474},{"__ignoreMap":1218},[1475],{"type":43,"value":1470},{"type":37,"tag":123,"props":1477,"children":1478},{},[1479],{"type":43,"value":1480},"Wait for the selection. Recap the picks and the affected file counts. Ask one final time before any side effects.",{"type":37,"tag":618,"props":1482,"children":1484},{"id":1483},"phase-4-preflight-baseline-and-workspace-setup",[1485],{"type":43,"value":1486},"Phase 4: Preflight, baseline, and workspace setup",{"type":37,"tag":123,"props":1488,"children":1489},{},[1490],{"type":43,"value":1491},"Run preflight:",{"type":37,"tag":1214,"props":1493,"children":1495},{"className":1216,"code":1494,"language":284,"meta":1218,"style":1218},"scripts\u002Fpreflight.sh \u003Cuser_repo>\n",[1496],{"type":37,"tag":56,"props":1497,"children":1498},{"__ignoreMap":1218},[1499],{"type":37,"tag":1224,"props":1500,"children":1501},{"class":1226,"line":1227},[1502,1507,1512,1517,1522],{"type":37,"tag":1224,"props":1503,"children":1504},{"style":1231},[1505],{"type":43,"value":1506},"scripts\u002Fpreflight.sh",{"type":37,"tag":1224,"props":1508,"children":1509},{"style":1242},[1510],{"type":43,"value":1511}," \u003C",{"type":37,"tag":1224,"props":1513,"children":1514},{"style":1236},[1515],{"type":43,"value":1516},"user_rep",{"type":37,"tag":1224,"props":1518,"children":1519},{"style":1258},[1520],{"type":43,"value":1521},"o",{"type":37,"tag":1224,"props":1523,"children":1524},{"style":1242},[1525],{"type":43,"value":1526},">\n",{"type":37,"tag":123,"props":1528,"children":1529},{},[1530,1532,1537,1539,1544],{"type":43,"value":1531},"It checks the repo is a git repo, the tree is clean, and that ",{"type":37,"tag":56,"props":1533,"children":1535},{"className":1534},[],[1536],{"type":43,"value":246},{"type":43,"value":1538}," (authenticated) and ",{"type":37,"tag":56,"props":1540,"children":1542},{"className":1541},[],[1543],{"type":43,"value":265},{"type":43,"value":1545}," are available. If it exits non-zero, surface the message verbatim and stop.",{"type":37,"tag":123,"props":1547,"children":1548},{},[1549,1551,1557],{"type":43,"value":1550},"Record a verification baseline so Phase 7 can distinguish regressions from pre-existing failures. Use ",{"type":37,"tag":56,"props":1552,"children":1554},{"className":1553},[],[1555],{"type":43,"value":1556},"mktemp",{"type":43,"value":1558}," so concurrent runs don't clobber each other:",{"type":37,"tag":1214,"props":1560,"children":1562},{"className":1216,"code":1561,"language":284,"meta":1218,"style":1218},"baseline=$(mktemp -t skup-baseline.XXXXXX.json)\nscripts\u002Frun_tests.sh \u003Cuser_repo> --baseline \"$baseline\"\n",[1563],{"type":37,"tag":56,"props":1564,"children":1565},{"__ignoreMap":1218},[1566,1598],{"type":37,"tag":1224,"props":1567,"children":1568},{"class":1226,"line":1227},[1569,1574,1579,1583,1588,1593],{"type":37,"tag":1224,"props":1570,"children":1571},{"style":1258},[1572],{"type":43,"value":1573},"baseline",{"type":37,"tag":1224,"props":1575,"children":1576},{"style":1242},[1577],{"type":43,"value":1578},"=$(",{"type":37,"tag":1224,"props":1580,"children":1581},{"style":1231},[1582],{"type":43,"value":1556},{"type":37,"tag":1224,"props":1584,"children":1585},{"style":1236},[1586],{"type":43,"value":1587}," -t",{"type":37,"tag":1224,"props":1589,"children":1590},{"style":1236},[1591],{"type":43,"value":1592}," skup-baseline.XXXXXX.json",{"type":37,"tag":1224,"props":1594,"children":1595},{"style":1242},[1596],{"type":43,"value":1597},")\n",{"type":37,"tag":1224,"props":1599,"children":1600},{"class":1226,"line":1264},[1601,1606,1610,1614,1618,1623,1628,1632,1637],{"type":37,"tag":1224,"props":1602,"children":1603},{"style":1231},[1604],{"type":43,"value":1605},"scripts\u002Frun_tests.sh",{"type":37,"tag":1224,"props":1607,"children":1608},{"style":1242},[1609],{"type":43,"value":1511},{"type":37,"tag":1224,"props":1611,"children":1612},{"style":1236},[1613],{"type":43,"value":1516},{"type":37,"tag":1224,"props":1615,"children":1616},{"style":1258},[1617],{"type":43,"value":1521},{"type":37,"tag":1224,"props":1619,"children":1620},{"style":1242},[1621],{"type":43,"value":1622},">",{"type":37,"tag":1224,"props":1624,"children":1625},{"style":1236},[1626],{"type":43,"value":1627}," --baseline",{"type":37,"tag":1224,"props":1629,"children":1630},{"style":1242},[1631],{"type":43,"value":1245},{"type":37,"tag":1224,"props":1633,"children":1634},{"style":1258},[1635],{"type":43,"value":1636},"$baseline",{"type":37,"tag":1224,"props":1638,"children":1639},{"style":1242},[1640],{"type":43,"value":1641},"\"\n",{"type":37,"tag":123,"props":1643,"children":1644},{},[1645,1647,1652],{"type":43,"value":1646},"Hold onto ",{"type":37,"tag":56,"props":1648,"children":1650},{"className":1649},[],[1651],{"type":43,"value":1636},{"type":43,"value":1653},"; Phase 7 needs it.",{"type":37,"tag":123,"props":1655,"children":1656},{},[1657],{"type":43,"value":1658},"Fetch the upstream kit and capture its path:",{"type":37,"tag":1214,"props":1660,"children":1662},{"className":1216,"code":1661,"language":284,"meta":1218,"style":1218},"kit_dir=$(scripts\u002Ffetch_kit.sh \u003Ckit> \u003Cbranch>)\n",[1663],{"type":37,"tag":56,"props":1664,"children":1665},{"__ignoreMap":1218},[1666],{"type":37,"tag":1224,"props":1667,"children":1668},{"class":1226,"line":1227},[1669,1674,1678,1683,1687,1692,1697,1701,1705,1710,1715],{"type":37,"tag":1224,"props":1670,"children":1671},{"style":1258},[1672],{"type":43,"value":1673},"kit_dir",{"type":37,"tag":1224,"props":1675,"children":1676},{"style":1242},[1677],{"type":43,"value":1578},{"type":37,"tag":1224,"props":1679,"children":1680},{"style":1231},[1681],{"type":43,"value":1682},"scripts\u002Ffetch_kit.sh",{"type":37,"tag":1224,"props":1684,"children":1685},{"style":1242},[1686],{"type":43,"value":1511},{"type":37,"tag":1224,"props":1688,"children":1689},{"style":1236},[1690],{"type":43,"value":1691},"ki",{"type":37,"tag":1224,"props":1693,"children":1694},{"style":1258},[1695],{"type":43,"value":1696},"t",{"type":37,"tag":1224,"props":1698,"children":1699},{"style":1242},[1700],{"type":43,"value":1622},{"type":37,"tag":1224,"props":1702,"children":1703},{"style":1242},[1704],{"type":43,"value":1511},{"type":37,"tag":1224,"props":1706,"children":1707},{"style":1236},[1708],{"type":43,"value":1709},"branc",{"type":37,"tag":1224,"props":1711,"children":1712},{"style":1258},[1713],{"type":43,"value":1714},"h",{"type":37,"tag":1224,"props":1716,"children":1717},{"style":1242},[1718],{"type":43,"value":1719},">)\n",{"type":37,"tag":123,"props":1721,"children":1722},{},[1723,1724,1730],{"type":43,"value":1646},{"type":37,"tag":56,"props":1725,"children":1727},{"className":1726},[],[1728],{"type":43,"value":1729},"$kit_dir",{"type":43,"value":1731},"; Phase 5 needs it. The script is idempotent: re-running with the same args fetches the latest branch tip rather than re-cloning.",{"type":37,"tag":123,"props":1733,"children":1734},{},[1735],{"type":43,"value":1736},"Create the upgrade branch:",{"type":37,"tag":1214,"props":1738,"children":1740},{"className":1216,"code":1739,"language":284,"meta":1218,"style":1218},"git -C \u003Cuser_repo> checkout -b \"starter-kit-upgrade\u002F$(date +%Y%m%d-%H%M)-\u003Cfirst-slug>\"\n",[1741],{"type":37,"tag":56,"props":1742,"children":1743},{"__ignoreMap":1218},[1744],{"type":37,"tag":1224,"props":1745,"children":1746},{"class":1226,"line":1227},[1747,1751,1756,1760,1764,1768,1772,1777,1782,1786,1791,1796,1801,1806,1810,1815],{"type":37,"tag":1224,"props":1748,"children":1749},{"style":1231},[1750],{"type":43,"value":235},{"type":37,"tag":1224,"props":1752,"children":1753},{"style":1236},[1754],{"type":43,"value":1755}," -C",{"type":37,"tag":1224,"props":1757,"children":1758},{"style":1242},[1759],{"type":43,"value":1511},{"type":37,"tag":1224,"props":1761,"children":1762},{"style":1236},[1763],{"type":43,"value":1516},{"type":37,"tag":1224,"props":1765,"children":1766},{"style":1258},[1767],{"type":43,"value":1521},{"type":37,"tag":1224,"props":1769,"children":1770},{"style":1242},[1771],{"type":43,"value":1622},{"type":37,"tag":1224,"props":1773,"children":1774},{"style":1236},[1775],{"type":43,"value":1776}," checkout",{"type":37,"tag":1224,"props":1778,"children":1779},{"style":1236},[1780],{"type":43,"value":1781}," -b",{"type":37,"tag":1224,"props":1783,"children":1784},{"style":1242},[1785],{"type":43,"value":1245},{"type":37,"tag":1224,"props":1787,"children":1788},{"style":1236},[1789],{"type":43,"value":1790},"starter-kit-upgrade\u002F",{"type":37,"tag":1224,"props":1792,"children":1793},{"style":1242},[1794],{"type":43,"value":1795},"$(",{"type":37,"tag":1224,"props":1797,"children":1798},{"style":1231},[1799],{"type":43,"value":1800},"date",{"type":37,"tag":1224,"props":1802,"children":1803},{"style":1236},[1804],{"type":43,"value":1805}," +%Y%m%d-%H%M",{"type":37,"tag":1224,"props":1807,"children":1808},{"style":1242},[1809],{"type":43,"value":275},{"type":37,"tag":1224,"props":1811,"children":1812},{"style":1236},[1813],{"type":43,"value":1814},"-\u003Cfirst-slug>",{"type":37,"tag":1224,"props":1816,"children":1817},{"style":1242},[1818],{"type":43,"value":1641},{"type":37,"tag":123,"props":1820,"children":1821},{},[1822,1824,1830,1832,1838,1840,1845,1847,1852,1854,1859,1861,1867,1869,1874],{"type":43,"value":1823},"If the user is already on a ",{"type":37,"tag":56,"props":1825,"children":1827},{"className":1826},[],[1828],{"type":43,"value":1829},"starter-kit-upgrade\u002F...",{"type":43,"value":1831}," branch (a previous run that didn't get cleaned up), ",{"type":37,"tag":56,"props":1833,"children":1835},{"className":1834},[],[1836],{"type":43,"value":1837},"checkout -b",{"type":43,"value":1839}," will refuse if the new name collides. Don't auto-resolve: ask whether they want to ",{"type":37,"tag":93,"props":1841,"children":1842},{},[1843],{"type":43,"value":1844},"resume on that branch",{"type":43,"value":1846}," (skip the ",{"type":37,"tag":56,"props":1848,"children":1850},{"className":1849},[],[1851],{"type":43,"value":1837},{"type":43,"value":1853},", keep going from where they were), ",{"type":37,"tag":93,"props":1855,"children":1856},{},[1857],{"type":43,"value":1858},"start fresh",{"type":43,"value":1860}," (the new timestamped name will already differ by minute, so just retry — or bump to ",{"type":37,"tag":56,"props":1862,"children":1864},{"className":1863},[],[1865],{"type":43,"value":1866},"+%Y%m%d-%H%M%S",{"type":43,"value":1868}," if it's the same minute), or ",{"type":37,"tag":93,"props":1870,"children":1871},{},[1872],{"type":43,"value":1873},"abort",{"type":43,"value":1875}," so they can clean up manually. Never delete the existing branch on their behalf.",{"type":37,"tag":123,"props":1877,"children":1878},{},[1879],{"type":43,"value":1880},"From this point on, every write goes to this branch.",{"type":37,"tag":618,"props":1882,"children":1884},{"id":1883},"phase-5-apply-each-selected-feature",[1885],{"type":43,"value":1886},"Phase 5: Apply each selected feature",{"type":37,"tag":123,"props":1888,"children":1889},{},[1890],{"type":43,"value":1891},"For each selected feature, in order:",{"type":37,"tag":129,"props":1893,"children":1894},{},[1895],{"type":37,"tag":50,"props":1896,"children":1897},{},[1898,1900,1906],{"type":43,"value":1899},"Classify. Run ",{"type":37,"tag":56,"props":1901,"children":1903},{"className":1902},[],[1904],{"type":43,"value":1905},"scripts\u002Fclassify_feature.sh \u003Ckit_dir> \u003Csha> \u003Cuser_repo>",{"type":43,"value":1907},". Statuses:",{"type":37,"tag":46,"props":1909,"children":1910},{},[1911,1921,1931,1941,1952],{"type":37,"tag":50,"props":1912,"children":1913},{},[1914,1919],{"type":37,"tag":56,"props":1915,"children":1917},{"className":1916},[],[1918],{"type":43,"value":321},{"type":43,"value":1920},": file does not exist in user repo, exists at upstream HEAD. Safe to add.",{"type":37,"tag":50,"props":1922,"children":1923},{},[1924,1929],{"type":37,"tag":56,"props":1925,"children":1927},{"className":1926},[],[1928],{"type":43,"value":587},{"type":43,"value":1930},": user's file is byte-identical to upstream HEAD. Skip.",{"type":37,"tag":50,"props":1932,"children":1933},{},[1934,1939],{"type":37,"tag":56,"props":1935,"children":1937},{"className":1936},[],[1938],{"type":43,"value":329},{"type":43,"value":1940},": user has the file and bytes differ from upstream HEAD. Surface.",{"type":37,"tag":50,"props":1942,"children":1943},{},[1944,1950],{"type":37,"tag":56,"props":1945,"children":1947},{"className":1946},[],[1948],{"type":43,"value":1949},"deleted-upstream",{"type":43,"value":1951},": upstream HEAD lacks the file but the user has it. Surface; default is keep theirs.",{"type":37,"tag":50,"props":1953,"children":1954},{},[1955,1961],{"type":37,"tag":56,"props":1956,"children":1958},{"className":1957},[],[1959],{"type":43,"value":1960},"lockfile",{"type":43,"value":1962},": manifest or lock file. Surface; never auto-merge.",{"type":37,"tag":123,"props":1964,"children":1965},{},[1966],{"type":43,"value":1967},"The classifier compares only against upstream HEAD. The user's git history doesn't trace back to the kit's, so there's no \"before-image\" baseline to merge against; we don't try. The feature commit just enumerates which paths to look at.",{"type":37,"tag":129,"props":1969,"children":1970},{"start":1264},[1971],{"type":37,"tag":50,"props":1972,"children":1973},{},[1974,1976,1981],{"type":43,"value":1975},"Later-edits check. Find which feature paths ",{"type":37,"tag":367,"props":1977,"children":1978},{},[1979],{"type":43,"value":1980},"later",{"type":43,"value":1982}," upstream commits also modified:",{"type":37,"tag":1214,"props":1984,"children":1986},{"className":1216,"code":1985,"language":284,"meta":1218,"style":1218},"scripts\u002Flater_edits.sh \u003Ckit_dir> \u003Csha> \u003Cuser_repo>\n",[1987],{"type":37,"tag":56,"props":1988,"children":1989},{"__ignoreMap":1218},[1990],{"type":37,"tag":1224,"props":1991,"children":1992},{"class":1226,"line":1227},[1993,1998,2002,2007,2012,2016,2020,2025,2029,2033,2037,2041,2045],{"type":37,"tag":1224,"props":1994,"children":1995},{"style":1231},[1996],{"type":43,"value":1997},"scripts\u002Flater_edits.sh",{"type":37,"tag":1224,"props":1999,"children":2000},{"style":1242},[2001],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2003,"children":2004},{"style":1236},[2005],{"type":43,"value":2006},"kit_di",{"type":37,"tag":1224,"props":2008,"children":2009},{"style":1258},[2010],{"type":43,"value":2011},"r",{"type":37,"tag":1224,"props":2013,"children":2014},{"style":1242},[2015],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2017,"children":2018},{"style":1242},[2019],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2021,"children":2022},{"style":1236},[2023],{"type":43,"value":2024},"sh",{"type":37,"tag":1224,"props":2026,"children":2027},{"style":1258},[2028],{"type":43,"value":510},{"type":37,"tag":1224,"props":2030,"children":2031},{"style":1242},[2032],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2034,"children":2035},{"style":1242},[2036],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2038,"children":2039},{"style":1236},[2040],{"type":43,"value":1516},{"type":37,"tag":1224,"props":2042,"children":2043},{"style":1258},[2044],{"type":43,"value":1521},{"type":37,"tag":1224,"props":2046,"children":2047},{"style":1242},[2048],{"type":43,"value":1526},{"type":37,"tag":123,"props":2050,"children":2051},{},[2052,2054,2058,2060,2065,2067,2072,2074,2080],{"type":43,"value":2053},"Each path the script prints is a path where copying upstream HEAD's content pulls ",{"type":37,"tag":367,"props":2055,"children":2056},{},[2057],{"type":43,"value":1980},{"type":43,"value":2059}," changes in too. Diff ",{"type":37,"tag":56,"props":2061,"children":2063},{"className":2062},[],[2064],{"type":43,"value":379},{"type":43,"value":2066}," against ",{"type":37,"tag":56,"props":2068,"children":2070},{"className":2069},[],[2071],{"type":43,"value":387},{"type":43,"value":2073},"; if a non-whitespace hunk differs, scope to the feature commit (",{"type":37,"tag":56,"props":2075,"children":2077},{"className":2076},[],[2078],{"type":43,"value":2079},"git -C \u003Ckit_dir> show \u003Csha>:\u003Cpath>",{"type":43,"value":2081},") and note it in the report.",{"type":37,"tag":123,"props":2083,"children":2084},{},[2085,2097,2099,2104],{"type":37,"tag":93,"props":2086,"children":2087},{},[2088,2090,2095],{"type":43,"value":2089},"3. Apply ",{"type":37,"tag":56,"props":2091,"children":2093},{"className":2092},[],[2094],{"type":43,"value":321},{"type":43,"value":2096}," files.",{"type":43,"value":2098}," The script writes upstream HEAD's content for each ",{"type":37,"tag":56,"props":2100,"children":2102},{"className":2101},[],[2103],{"type":43,"value":321},{"type":43,"value":2105}," path and stages it; everything else is left for steps 4–5:",{"type":37,"tag":1214,"props":2107,"children":2109},{"className":1216,"code":2108,"language":284,"meta":1218,"style":1218},"scripts\u002Fapply_new_files.sh \u003Ckit_dir> \u003Csha> \u003Cuser_repo>\n",[2110],{"type":37,"tag":56,"props":2111,"children":2112},{"__ignoreMap":1218},[2113],{"type":37,"tag":1224,"props":2114,"children":2115},{"class":1226,"line":1227},[2116,2121,2125,2129,2133,2137,2141,2145,2149,2153,2157,2161,2165],{"type":37,"tag":1224,"props":2117,"children":2118},{"style":1231},[2119],{"type":43,"value":2120},"scripts\u002Fapply_new_files.sh",{"type":37,"tag":1224,"props":2122,"children":2123},{"style":1242},[2124],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2126,"children":2127},{"style":1236},[2128],{"type":43,"value":2006},{"type":37,"tag":1224,"props":2130,"children":2131},{"style":1258},[2132],{"type":43,"value":2011},{"type":37,"tag":1224,"props":2134,"children":2135},{"style":1242},[2136],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2138,"children":2139},{"style":1242},[2140],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2142,"children":2143},{"style":1236},[2144],{"type":43,"value":2024},{"type":37,"tag":1224,"props":2146,"children":2147},{"style":1258},[2148],{"type":43,"value":510},{"type":37,"tag":1224,"props":2150,"children":2151},{"style":1242},[2152],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2154,"children":2155},{"style":1242},[2156],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2158,"children":2159},{"style":1236},[2160],{"type":43,"value":1516},{"type":37,"tag":1224,"props":2162,"children":2163},{"style":1258},[2164],{"type":43,"value":1521},{"type":37,"tag":1224,"props":2166,"children":2167},{"style":1242},[2168],{"type":43,"value":1526},{"type":37,"tag":123,"props":2170,"children":2171},{},[2172,2174,2180],{"type":43,"value":2173},"It prints ",{"type":37,"tag":56,"props":2175,"children":2177},{"className":2176},[],[2178],{"type":43,"value":2179},"applied \u003Cpath>",{"type":43,"value":2181}," for each file written so you can collect the list for the feature's commit message and the report.",{"type":37,"tag":123,"props":2183,"children":2184},{},[2185,2187,2192],{"type":43,"value":2186},"Before letting the script run, check for the rename gotcha (see Gotchas → \"Renamed paths\"). If a ",{"type":37,"tag":56,"props":2188,"children":2190},{"className":2189},[],[2191],{"type":43,"value":321},{"type":43,"value":2193}," path's basename already exists at a different location in the user's repo, surface to the user before applying.",{"type":37,"tag":123,"props":2195,"children":2196},{},[2197,2202,2204,2210,2212,2218],{"type":37,"tag":93,"props":2198,"children":2199},{},[2200],{"type":43,"value":2201},"4. Transitive-imports check.",{"type":43,"value":2203}," New files often import helpers that aren't in the same feature commit. The script picks the right regex for the kit (Vue\u002FReact\u002FSvelte handle TS\u002FJS imports; Livewire handles Blade includes \u002F ",{"type":37,"tag":56,"props":2205,"children":2207},{"className":2206},[],[2208],{"type":43,"value":2209},"x-",{"type":43,"value":2211}," components \u002F ",{"type":37,"tag":56,"props":2213,"children":2215},{"className":2214},[],[2216],{"type":43,"value":2217},"livewire:",{"type":43,"value":2219}," tags):",{"type":37,"tag":1214,"props":2221,"children":2223},{"className":1216,"code":2222,"language":284,"meta":1218,"style":1218},"scripts\u002Fscan_transitive_imports.sh \u003Ckit> \u003Cnew_files...>\n",[2224],{"type":37,"tag":56,"props":2225,"children":2226},{"__ignoreMap":1218},[2227],{"type":37,"tag":1224,"props":2228,"children":2229},{"class":1226,"line":1227},[2230,2235,2239,2243,2247,2251,2255,2260,2264],{"type":37,"tag":1224,"props":2231,"children":2232},{"style":1231},[2233],{"type":43,"value":2234},"scripts\u002Fscan_transitive_imports.sh",{"type":37,"tag":1224,"props":2236,"children":2237},{"style":1242},[2238],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2240,"children":2241},{"style":1236},[2242],{"type":43,"value":1691},{"type":37,"tag":1224,"props":2244,"children":2245},{"style":1258},[2246],{"type":43,"value":1696},{"type":37,"tag":1224,"props":2248,"children":2249},{"style":1242},[2250],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2252,"children":2253},{"style":1242},[2254],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2256,"children":2257},{"style":1236},[2258],{"type":43,"value":2259},"new_files..",{"type":37,"tag":1224,"props":2261,"children":2262},{"style":1258},[2263],{"type":43,"value":389},{"type":37,"tag":1224,"props":2265,"children":2266},{"style":1242},[2267],{"type":43,"value":1526},{"type":37,"tag":123,"props":2269,"children":2270},{},[2271,2273,2279,2281,2286],{"type":43,"value":2272},"Output is ",{"type":37,"tag":56,"props":2274,"children":2276},{"className":2275},[],[2277],{"type":43,"value":2278},"\u003Cfile>:\u003Cline>:\u003Cmatch>",{"type":43,"value":2280}," per import. For each match, verify the corresponding helper file exists in the user's repo. If not, the new files won't compile\u002Frender; flag the missing target as a follow-up dependency the user needs to fetch (same walkthrough as ",{"type":37,"tag":56,"props":2282,"children":2284},{"className":2283},[],[2285],{"type":43,"value":329},{"type":43,"value":2287},").",{"type":37,"tag":123,"props":2289,"children":2290},{},[2291,2315],{"type":37,"tag":93,"props":2292,"children":2293},{},[2294,2296,2301,2302,2307,2309,2314],{"type":43,"value":2295},"5. Walk the user through ",{"type":37,"tag":56,"props":2297,"children":2299},{"className":2298},[],[2300],{"type":43,"value":329},{"type":43,"value":63},{"type":37,"tag":56,"props":2303,"children":2305},{"className":2304},[],[2306],{"type":43,"value":1949},{"type":43,"value":2308},", and ",{"type":37,"tag":56,"props":2310,"children":2312},{"className":2311},[],[2313],{"type":43,"value":1960},{"type":43,"value":389},{"type":43,"value":2316}," One file at a time:",{"type":37,"tag":46,"props":2318,"children":2319},{},[2320,2348,2353,2358,2363,2368],{"type":37,"tag":50,"props":2321,"children":2322},{},[2323,2325,2331,2333,2338,2340,2346],{"type":43,"value":2324},"Show what upstream has: ",{"type":37,"tag":56,"props":2326,"children":2328},{"className":2327},[],[2329],{"type":43,"value":2330},"git -C \u003Ckit_dir> show HEAD:\u003Cpath>",{"type":43,"value":2332}," (or ",{"type":37,"tag":56,"props":2334,"children":2336},{"className":2335},[],[2337],{"type":43,"value":379},{"type":43,"value":2339}," if ",{"type":37,"tag":56,"props":2341,"children":2343},{"className":2342},[],[2344],{"type":43,"value":2345},"later_edits.sh",{"type":43,"value":2347}," flagged this path).",{"type":37,"tag":50,"props":2349,"children":2350},{},[2351],{"type":43,"value":2352},"Show their current file.",{"type":37,"tag":50,"props":2354,"children":2355},{},[2356],{"type":43,"value":2357},"Show the diff between the two.",{"type":37,"tag":50,"props":2359,"children":2360},{},[2361],{"type":43,"value":2362},"Ask the user to pick: take upstream wholesale (lossy; confirm first), keep theirs, or merge by hand (you produce a unified diff for reference; they write the result).",{"type":37,"tag":50,"props":2364,"children":2365},{},[2366],{"type":43,"value":2367},"If they're unsure, ask once more with the diff in front of them. Still unsure → keep theirs and move on. Don't pick silently.",{"type":37,"tag":50,"props":2369,"children":2370},{},[2371,2373,2379],{"type":43,"value":2372},"Stage whatever they chose: ",{"type":37,"tag":56,"props":2374,"children":2376},{"className":2375},[],[2377],{"type":43,"value":2378},"git -C \u003Cuser_repo> add \u003Cpath>",{"type":43,"value":389},{"type":37,"tag":123,"props":2381,"children":2382},{},[2383,2385,2390,2392,2397,2399,2404],{"type":43,"value":2384},"For ",{"type":37,"tag":56,"props":2386,"children":2388},{"className":2387},[],[2389],{"type":43,"value":1960},{"type":43,"value":2391},": never overwrite the manifest. Show the upstream diff for ",{"type":37,"tag":56,"props":2393,"children":2395},{"className":2394},[],[2396],{"type":43,"value":178},{"type":43,"value":2398}," \u002F ",{"type":37,"tag":56,"props":2400,"children":2402},{"className":2401},[],[2403],{"type":43,"value":185},{"type":43,"value":2405},", walk them through the relevant change, let them edit the manifest. Lockfile regeneration happens in Phase 6.",{"type":37,"tag":123,"props":2407,"children":2408},{},[2409],{"type":37,"tag":93,"props":2410,"children":2411},{},[2412],{"type":43,"value":2413},"6. Commit the feature as one revertable unit:",{"type":37,"tag":1214,"props":2415,"children":2417},{"className":1216,"code":2416,"language":284,"meta":1218,"style":1218},"git -C \u003Cuser_repo> commit -m \"starter-kit-upgrade: \u003Cfeature name>\n\nUpstream: laravel\u002F\u003Ckit>@\u003Csha>\nFiles added: \u003Clist>\nFiles updated (took upstream): \u003Clist>\nFiles updated (manual merge): \u003Clist>\nFiles kept as-is: \u003Clist>\"\n",[2418],{"type":37,"tag":56,"props":2419,"children":2420},{"__ignoreMap":1218},[2421,2467,2474,2482,2490,2498,2507],{"type":37,"tag":1224,"props":2422,"children":2423},{"class":1226,"line":1227},[2424,2428,2432,2436,2440,2444,2448,2453,2458,2462],{"type":37,"tag":1224,"props":2425,"children":2426},{"style":1231},[2427],{"type":43,"value":235},{"type":37,"tag":1224,"props":2429,"children":2430},{"style":1236},[2431],{"type":43,"value":1755},{"type":37,"tag":1224,"props":2433,"children":2434},{"style":1242},[2435],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2437,"children":2438},{"style":1236},[2439],{"type":43,"value":1516},{"type":37,"tag":1224,"props":2441,"children":2442},{"style":1258},[2443],{"type":43,"value":1521},{"type":37,"tag":1224,"props":2445,"children":2446},{"style":1242},[2447],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2449,"children":2450},{"style":1236},[2451],{"type":43,"value":2452}," commit",{"type":37,"tag":1224,"props":2454,"children":2455},{"style":1236},[2456],{"type":43,"value":2457}," -m",{"type":37,"tag":1224,"props":2459,"children":2460},{"style":1242},[2461],{"type":43,"value":1245},{"type":37,"tag":1224,"props":2463,"children":2464},{"style":1236},[2465],{"type":43,"value":2466},"starter-kit-upgrade: \u003Cfeature name>\n",{"type":37,"tag":1224,"props":2468,"children":2469},{"class":1226,"line":1264},[2470],{"type":37,"tag":1224,"props":2471,"children":2472},{"emptyLinePlaceholder":1292},[2473],{"type":43,"value":1295},{"type":37,"tag":1224,"props":2475,"children":2476},{"class":1226,"line":1288},[2477],{"type":37,"tag":1224,"props":2478,"children":2479},{"style":1236},[2480],{"type":43,"value":2481},"Upstream: laravel\u002F\u003Ckit>@\u003Csha>\n",{"type":37,"tag":1224,"props":2483,"children":2484},{"class":1226,"line":1298},[2485],{"type":37,"tag":1224,"props":2486,"children":2487},{"style":1236},[2488],{"type":43,"value":2489},"Files added: \u003Clist>\n",{"type":37,"tag":1224,"props":2491,"children":2492},{"class":1226,"line":1377},[2493],{"type":37,"tag":1224,"props":2494,"children":2495},{"style":1236},[2496],{"type":43,"value":2497},"Files updated (took upstream): \u003Clist>\n",{"type":37,"tag":1224,"props":2499,"children":2501},{"class":1226,"line":2500},6,[2502],{"type":37,"tag":1224,"props":2503,"children":2504},{"style":1236},[2505],{"type":43,"value":2506},"Files updated (manual merge): \u003Clist>\n",{"type":37,"tag":1224,"props":2508,"children":2510},{"class":1226,"line":2509},7,[2511,2516],{"type":37,"tag":1224,"props":2512,"children":2513},{"style":1236},[2514],{"type":43,"value":2515},"Files kept as-is: \u003Clist>",{"type":37,"tag":1224,"props":2517,"children":2518},{"style":1242},[2519],{"type":43,"value":1641},{"type":37,"tag":123,"props":2521,"children":2522},{},[2523,2525,2531],{"type":43,"value":2524},"If the user wants to bail out at any point, leave the branch as-is. They can drop it with ",{"type":37,"tag":56,"props":2526,"children":2528},{"className":2527},[],[2529],{"type":43,"value":2530},"git branch -D",{"type":43,"value":389},{"type":37,"tag":618,"props":2533,"children":2535},{"id":2534},"phase-6-reconcile-manifests-if-needed",[2536],{"type":43,"value":2537},"Phase 6: Reconcile manifests if needed",{"type":37,"tag":123,"props":2539,"children":2540},{},[2541],{"type":43,"value":2542},"If any feature touched a manifest, lockfiles are out of sync. After the user agrees, run:",{"type":37,"tag":1214,"props":2544,"children":2546},{"className":1216,"code":2545,"language":284,"meta":1218,"style":1218},"scripts\u002Freconcile_manifests.sh \u003Cuser_repo>\n",[2547],{"type":37,"tag":56,"props":2548,"children":2549},{"__ignoreMap":1218},[2550],{"type":37,"tag":1224,"props":2551,"children":2552},{"class":1226,"line":1227},[2553,2558,2562,2566,2570],{"type":37,"tag":1224,"props":2554,"children":2555},{"style":1231},[2556],{"type":43,"value":2557},"scripts\u002Freconcile_manifests.sh",{"type":37,"tag":1224,"props":2559,"children":2560},{"style":1242},[2561],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2563,"children":2564},{"style":1236},[2565],{"type":43,"value":1516},{"type":37,"tag":1224,"props":2567,"children":2568},{"style":1258},[2569],{"type":43,"value":1521},{"type":37,"tag":1224,"props":2571,"children":2572},{"style":1242},[2573],{"type":43,"value":1526},{"type":37,"tag":123,"props":2575,"children":2576},{},[2577,2579,2585,2587,2592,2593,2599,2601,2607,2609,2614,2616,2622],{"type":43,"value":2578},"The script runs ",{"type":37,"tag":56,"props":2580,"children":2582},{"className":2581},[],[2583],{"type":43,"value":2584},"composer install",{"type":43,"value":2586}," (when ",{"type":37,"tag":56,"props":2588,"children":2590},{"className":2589},[],[2591],{"type":43,"value":178},{"type":43,"value":760},{"type":37,"tag":56,"props":2594,"children":2596},{"className":2595},[],[2597],{"type":43,"value":2598},"composer.lock",{"type":43,"value":2600}," are both present), auto-detects the JS package manager from the existing lockfile, runs ",{"type":37,"tag":56,"props":2602,"children":2604},{"className":2603},[],[2605],{"type":43,"value":2606},"\u003Cpm> install",{"type":43,"value":2608},", and on failure (typically ",{"type":37,"tag":56,"props":2610,"children":2612},{"className":2611},[],[2613],{"type":43,"value":478},{"type":43,"value":2615}," after a major bump like Vite v7 → v8 or React 18 → 19) wipes ",{"type":37,"tag":56,"props":2617,"children":2619},{"className":2618},[],[2620],{"type":43,"value":2621},"node_modules",{"type":43,"value":2623}," + the lockfile and retries once.",{"type":37,"tag":123,"props":2625,"children":2626},{},[2627,2629,2635],{"type":43,"value":2628},"Commit lockfile updates as a separate ",{"type":37,"tag":56,"props":2630,"children":2632},{"className":2631},[],[2633],{"type":43,"value":2634},"starter-kit-upgrade: dependency lockfiles",{"type":43,"value":2636}," commit so they can be reverted independently.",{"type":37,"tag":618,"props":2638,"children":2640},{"id":2639},"phase-7-verify-behavior-preservation",[2641],{"type":43,"value":2642},"Phase 7: Verify behavior preservation",{"type":37,"tag":123,"props":2644,"children":2645},{},[2646],{"type":43,"value":2647},"Compare against the baseline:",{"type":37,"tag":1214,"props":2649,"children":2651},{"className":1216,"code":2650,"language":284,"meta":1218,"style":1218},"scripts\u002Frun_tests.sh \u003Cuser_repo> --compare \"$baseline\"\n",[2652],{"type":37,"tag":56,"props":2653,"children":2654},{"__ignoreMap":1218},[2655],{"type":37,"tag":1224,"props":2656,"children":2657},{"class":1226,"line":1227},[2658,2662,2666,2670,2674,2678,2683,2687,2691],{"type":37,"tag":1224,"props":2659,"children":2660},{"style":1231},[2661],{"type":43,"value":1605},{"type":37,"tag":1224,"props":2663,"children":2664},{"style":1242},[2665],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2667,"children":2668},{"style":1236},[2669],{"type":43,"value":1516},{"type":37,"tag":1224,"props":2671,"children":2672},{"style":1258},[2673],{"type":43,"value":1521},{"type":37,"tag":1224,"props":2675,"children":2676},{"style":1242},[2677],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2679,"children":2680},{"style":1236},[2681],{"type":43,"value":2682}," --compare",{"type":37,"tag":1224,"props":2684,"children":2685},{"style":1242},[2686],{"type":43,"value":1245},{"type":37,"tag":1224,"props":2688,"children":2689},{"style":1258},[2690],{"type":43,"value":1636},{"type":37,"tag":1224,"props":2692,"children":2693},{"style":1242},[2694],{"type":43,"value":1641},{"type":37,"tag":123,"props":2696,"children":2697},{},[2698],{"type":43,"value":2699},"Compare mode runs PHP tests, JS typecheck, JS build (whichever exist) and reports only checks that were passing in the baseline and now fail. Pre-existing failures are not the upgrade's fault and don't block.",{"type":37,"tag":123,"props":2701,"children":2702},{},[2703],{"type":43,"value":2704},"If a regression is reported:",{"type":37,"tag":46,"props":2706,"children":2707},{},[2708,2713,2726,2738],{"type":37,"tag":50,"props":2709,"children":2710},{},[2711],{"type":43,"value":2712},"Show the failing output from the per-check log file the script points to.",{"type":37,"tag":50,"props":2714,"children":2715},{},[2716,2718,2724],{"type":43,"value":2717},"Recommend ",{"type":37,"tag":56,"props":2719,"children":2721},{"className":2720},[],[2722],{"type":43,"value":2723},"git revert HEAD",{"type":43,"value":2725}," first; if that doesn't fix it, revert again.",{"type":37,"tag":50,"props":2727,"children":2728},{},[2729,2731,2737],{"type":43,"value":2730},"For multi-feature uncertainty, suggest ",{"type":37,"tag":56,"props":2732,"children":2734},{"className":2733},[],[2735],{"type":43,"value":2736},"git bisect start \u003Cupgrade-branch> \u003Cprevious-branch>",{"type":43,"value":389},{"type":37,"tag":50,"props":2739,"children":2740},{},[2741],{"type":43,"value":2742},"Do not edit code to make the failing check pass; that violates the behavior contract.",{"type":37,"tag":123,"props":2744,"children":2745},{},[2746],{"type":43,"value":2747},"If the project has no discoverable verification commands, say so explicitly in the report. Don't pretend verification happened.",{"type":37,"tag":618,"props":2749,"children":2751},{"id":2750},"phase-8-write-the-report",[2752],{"type":43,"value":2753},"Phase 8: Write the report",{"type":37,"tag":123,"props":2755,"children":2756},{},[2757,2759,2765,2767,2773,2775,2781,2783,2789],{"type":43,"value":2758},"Write to ",{"type":37,"tag":56,"props":2760,"children":2762},{"className":2761},[],[2763],{"type":43,"value":2764},"\u002Ftmp\u002Fstarter-kit-upgrade-report-\u003Cid>.md",{"type":43,"value":2766}," (where ",{"type":37,"tag":56,"props":2768,"children":2770},{"className":2769},[],[2771],{"type":43,"value":2772},"\u003Cid>",{"type":43,"value":2774}," matches the upgrade branch's ",{"type":37,"tag":56,"props":2776,"children":2778},{"className":2777},[],[2779],{"type":43,"value":2780},"starter-kit-upgrade\u002F\u003Cid>",{"type":43,"value":2782},") first; never silently into the user's repo. Stamping the id keeps concurrent runs and re-runs from clobbering each other. Show the path and ask whether they want it copied in as ",{"type":37,"tag":56,"props":2784,"children":2786},{"className":2785},[],[2787],{"type":43,"value":2788},"STARTER_KIT_UPGRADE.md",{"type":43,"value":2790}," or kept out of tree.",{"type":37,"tag":1214,"props":2792,"children":2796},{"className":2793,"code":2794,"language":2795,"meta":1218,"style":1218},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Starter Kit Upgrade Report\n\n- Date: \u003Cdate>\n- Kit: laravel\u002F\u003Ckit>\n- Branch tracked: \u003Cbranch>\n- Upgrade branch: starter-kit-upgrade\u002F\u003Cid>\n\n## Features applied\n\n- \u003Cfeature name> · laravel\u002F\u003Ckit>@\u003Csha> · \u003CN files>\n  - Applied: \u003Clist>\n  - Skipped: \u003Clist with reasons>\n  - Manual decisions: \u003Cif any, with reasoning>\n  - Later-edit drift avoided: \u003Cif any, with paths scoped manually>\n\n## Lockfile updates\n\n\u003Cwhich lock files were regenerated and how>\n\n## Verification\n\n- Baseline: \u003Cpath or summary>\n- Result: \u003CPASS \u002F REGRESSED:\u003Clist> \u002F NO-CHECKS>\n- Output: \u003Crelevant snippet>\n\n## How to revert\n\n- Drop a single feature: `git revert \u003Ccommit-sha>`\n- Discard everything: `git checkout \u003Cprevious-branch> && git branch -D starter-kit-upgrade\u002F\u003Cid>`\n","markdown",[2797],{"type":37,"tag":56,"props":2798,"children":2799},{"__ignoreMap":1218},[2800,2813,2820,2847,2872,2897,2922,2929,2943,2951,3036,3063,3098,3138,3186,3194,3207,3215,3261,3269,3278,3286,3318,3355,3382,3390,3399,3407,3433],{"type":37,"tag":1224,"props":2801,"children":2802},{"class":1226,"line":1227},[2803,2808],{"type":37,"tag":1224,"props":2804,"children":2805},{"style":1242},[2806],{"type":43,"value":2807},"# ",{"type":37,"tag":1224,"props":2809,"children":2810},{"style":1231},[2811],{"type":43,"value":2812},"Starter Kit Upgrade Report\n",{"type":37,"tag":1224,"props":2814,"children":2815},{"class":1226,"line":1264},[2816],{"type":37,"tag":1224,"props":2817,"children":2818},{"emptyLinePlaceholder":1292},[2819],{"type":43,"value":1295},{"type":37,"tag":1224,"props":2821,"children":2822},{"class":1226,"line":1288},[2823,2828,2833,2838,2843],{"type":37,"tag":1224,"props":2824,"children":2825},{"style":1242},[2826],{"type":43,"value":2827},"-",{"type":37,"tag":1224,"props":2829,"children":2830},{"style":1258},[2831],{"type":43,"value":2832}," Date: ",{"type":37,"tag":1224,"props":2834,"children":2835},{"style":1242},[2836],{"type":43,"value":2837},"\u003C",{"type":37,"tag":1224,"props":2839,"children":2841},{"style":2840},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[2842],{"type":43,"value":1800},{"type":37,"tag":1224,"props":2844,"children":2845},{"style":1242},[2846],{"type":43,"value":1526},{"type":37,"tag":1224,"props":2848,"children":2849},{"class":1226,"line":1298},[2850,2854,2859,2863,2868],{"type":37,"tag":1224,"props":2851,"children":2852},{"style":1242},[2853],{"type":43,"value":2827},{"type":37,"tag":1224,"props":2855,"children":2856},{"style":1258},[2857],{"type":43,"value":2858}," Kit: laravel\u002F",{"type":37,"tag":1224,"props":2860,"children":2861},{"style":1242},[2862],{"type":43,"value":2837},{"type":37,"tag":1224,"props":2864,"children":2865},{"style":2840},[2866],{"type":43,"value":2867},"kit",{"type":37,"tag":1224,"props":2869,"children":2870},{"style":1242},[2871],{"type":43,"value":1526},{"type":37,"tag":1224,"props":2873,"children":2874},{"class":1226,"line":1377},[2875,2879,2884,2888,2893],{"type":37,"tag":1224,"props":2876,"children":2877},{"style":1242},[2878],{"type":43,"value":2827},{"type":37,"tag":1224,"props":2880,"children":2881},{"style":1258},[2882],{"type":43,"value":2883}," Branch tracked: ",{"type":37,"tag":1224,"props":2885,"children":2886},{"style":1242},[2887],{"type":43,"value":2837},{"type":37,"tag":1224,"props":2889,"children":2890},{"style":2840},[2891],{"type":43,"value":2892},"branch",{"type":37,"tag":1224,"props":2894,"children":2895},{"style":1242},[2896],{"type":43,"value":1526},{"type":37,"tag":1224,"props":2898,"children":2899},{"class":1226,"line":2500},[2900,2904,2909,2913,2918],{"type":37,"tag":1224,"props":2901,"children":2902},{"style":1242},[2903],{"type":43,"value":2827},{"type":37,"tag":1224,"props":2905,"children":2906},{"style":1258},[2907],{"type":43,"value":2908}," Upgrade branch: starter-kit-upgrade\u002F",{"type":37,"tag":1224,"props":2910,"children":2911},{"style":1242},[2912],{"type":43,"value":2837},{"type":37,"tag":1224,"props":2914,"children":2915},{"style":2840},[2916],{"type":43,"value":2917},"id",{"type":37,"tag":1224,"props":2919,"children":2920},{"style":1242},[2921],{"type":43,"value":1526},{"type":37,"tag":1224,"props":2923,"children":2924},{"class":1226,"line":2509},[2925],{"type":37,"tag":1224,"props":2926,"children":2927},{"emptyLinePlaceholder":1292},[2928],{"type":43,"value":1295},{"type":37,"tag":1224,"props":2930,"children":2932},{"class":1226,"line":2931},8,[2933,2938],{"type":37,"tag":1224,"props":2934,"children":2935},{"style":1242},[2936],{"type":43,"value":2937},"## ",{"type":37,"tag":1224,"props":2939,"children":2940},{"style":1231},[2941],{"type":43,"value":2942},"Features applied\n",{"type":37,"tag":1224,"props":2944,"children":2946},{"class":1226,"line":2945},9,[2947],{"type":37,"tag":1224,"props":2948,"children":2949},{"emptyLinePlaceholder":1292},[2950],{"type":43,"value":1295},{"type":37,"tag":1224,"props":2952,"children":2954},{"class":1226,"line":2953},10,[2955,2959,2963,2968,2974,2978,2983,2987,2991,2995,3000,3004,3009,3013,3018,3022,3027,3032],{"type":37,"tag":1224,"props":2956,"children":2957},{"style":1242},[2958],{"type":43,"value":2827},{"type":37,"tag":1224,"props":2960,"children":2961},{"style":1242},[2962],{"type":43,"value":1511},{"type":37,"tag":1224,"props":2964,"children":2965},{"style":2840},[2966],{"type":43,"value":2967},"feature",{"type":37,"tag":1224,"props":2969,"children":2971},{"style":2970},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[2972],{"type":43,"value":2973}," name",{"type":37,"tag":1224,"props":2975,"children":2976},{"style":1242},[2977],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2979,"children":2980},{"style":1258},[2981],{"type":43,"value":2982}," · laravel\u002F",{"type":37,"tag":1224,"props":2984,"children":2985},{"style":1242},[2986],{"type":43,"value":2837},{"type":37,"tag":1224,"props":2988,"children":2989},{"style":2840},[2990],{"type":43,"value":2867},{"type":37,"tag":1224,"props":2992,"children":2993},{"style":1242},[2994],{"type":43,"value":1622},{"type":37,"tag":1224,"props":2996,"children":2997},{"style":1258},[2998],{"type":43,"value":2999},"@",{"type":37,"tag":1224,"props":3001,"children":3002},{"style":1242},[3003],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3005,"children":3006},{"style":2840},[3007],{"type":43,"value":3008},"sha",{"type":37,"tag":1224,"props":3010,"children":3011},{"style":1242},[3012],{"type":43,"value":1622},{"type":37,"tag":1224,"props":3014,"children":3015},{"style":1258},[3016],{"type":43,"value":3017}," · ",{"type":37,"tag":1224,"props":3019,"children":3020},{"style":1242},[3021],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3023,"children":3024},{"style":2840},[3025],{"type":43,"value":3026},"N",{"type":37,"tag":1224,"props":3028,"children":3029},{"style":2970},[3030],{"type":43,"value":3031}," files",{"type":37,"tag":1224,"props":3033,"children":3034},{"style":1242},[3035],{"type":43,"value":1526},{"type":37,"tag":1224,"props":3037,"children":3039},{"class":1226,"line":3038},11,[3040,3045,3050,3054,3059],{"type":37,"tag":1224,"props":3041,"children":3042},{"style":1242},[3043],{"type":43,"value":3044},"  -",{"type":37,"tag":1224,"props":3046,"children":3047},{"style":1258},[3048],{"type":43,"value":3049}," Applied: ",{"type":37,"tag":1224,"props":3051,"children":3052},{"style":1242},[3053],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3055,"children":3056},{"style":2840},[3057],{"type":43,"value":3058},"list",{"type":37,"tag":1224,"props":3060,"children":3061},{"style":1242},[3062],{"type":43,"value":1526},{"type":37,"tag":1224,"props":3064,"children":3066},{"class":1226,"line":3065},12,[3067,3071,3076,3080,3084,3089,3094],{"type":37,"tag":1224,"props":3068,"children":3069},{"style":1242},[3070],{"type":43,"value":3044},{"type":37,"tag":1224,"props":3072,"children":3073},{"style":1258},[3074],{"type":43,"value":3075}," Skipped: ",{"type":37,"tag":1224,"props":3077,"children":3078},{"style":1242},[3079],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3081,"children":3082},{"style":2840},[3083],{"type":43,"value":3058},{"type":37,"tag":1224,"props":3085,"children":3086},{"style":2970},[3087],{"type":43,"value":3088}," with",{"type":37,"tag":1224,"props":3090,"children":3091},{"style":2970},[3092],{"type":43,"value":3093}," reasons",{"type":37,"tag":1224,"props":3095,"children":3096},{"style":1242},[3097],{"type":43,"value":1526},{"type":37,"tag":1224,"props":3099,"children":3101},{"class":1226,"line":3100},13,[3102,3106,3111,3115,3120,3125,3129,3134],{"type":37,"tag":1224,"props":3103,"children":3104},{"style":1242},[3105],{"type":43,"value":3044},{"type":37,"tag":1224,"props":3107,"children":3108},{"style":1258},[3109],{"type":43,"value":3110}," Manual decisions: ",{"type":37,"tag":1224,"props":3112,"children":3113},{"style":1242},[3114],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3116,"children":3117},{"style":2840},[3118],{"type":43,"value":3119},"if",{"type":37,"tag":1224,"props":3121,"children":3122},{"style":2970},[3123],{"type":43,"value":3124}," any,",{"type":37,"tag":1224,"props":3126,"children":3127},{"style":2970},[3128],{"type":43,"value":3088},{"type":37,"tag":1224,"props":3130,"children":3131},{"style":2970},[3132],{"type":43,"value":3133}," reasoning",{"type":37,"tag":1224,"props":3135,"children":3136},{"style":1242},[3137],{"type":43,"value":1526},{"type":37,"tag":1224,"props":3139,"children":3141},{"class":1226,"line":3140},14,[3142,3146,3151,3155,3159,3163,3167,3172,3177,3182],{"type":37,"tag":1224,"props":3143,"children":3144},{"style":1242},[3145],{"type":43,"value":3044},{"type":37,"tag":1224,"props":3147,"children":3148},{"style":1258},[3149],{"type":43,"value":3150}," Later-edit drift avoided: ",{"type":37,"tag":1224,"props":3152,"children":3153},{"style":1242},[3154],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3156,"children":3157},{"style":2840},[3158],{"type":43,"value":3119},{"type":37,"tag":1224,"props":3160,"children":3161},{"style":2970},[3162],{"type":43,"value":3124},{"type":37,"tag":1224,"props":3164,"children":3165},{"style":2970},[3166],{"type":43,"value":3088},{"type":37,"tag":1224,"props":3168,"children":3169},{"style":2970},[3170],{"type":43,"value":3171}," paths",{"type":37,"tag":1224,"props":3173,"children":3174},{"style":2970},[3175],{"type":43,"value":3176}," scoped",{"type":37,"tag":1224,"props":3178,"children":3179},{"style":2970},[3180],{"type":43,"value":3181}," manually",{"type":37,"tag":1224,"props":3183,"children":3184},{"style":1242},[3185],{"type":43,"value":1526},{"type":37,"tag":1224,"props":3187,"children":3189},{"class":1226,"line":3188},15,[3190],{"type":37,"tag":1224,"props":3191,"children":3192},{"emptyLinePlaceholder":1292},[3193],{"type":43,"value":1295},{"type":37,"tag":1224,"props":3195,"children":3197},{"class":1226,"line":3196},16,[3198,3202],{"type":37,"tag":1224,"props":3199,"children":3200},{"style":1242},[3201],{"type":43,"value":2937},{"type":37,"tag":1224,"props":3203,"children":3204},{"style":1231},[3205],{"type":43,"value":3206},"Lockfile updates\n",{"type":37,"tag":1224,"props":3208,"children":3210},{"class":1226,"line":3209},17,[3211],{"type":37,"tag":1224,"props":3212,"children":3213},{"emptyLinePlaceholder":1292},[3214],{"type":43,"value":1295},{"type":37,"tag":1224,"props":3216,"children":3218},{"class":1226,"line":3217},18,[3219,3223,3228,3233,3237,3242,3247,3252,3257],{"type":37,"tag":1224,"props":3220,"children":3221},{"style":1242},[3222],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3224,"children":3225},{"style":2840},[3226],{"type":43,"value":3227},"which",{"type":37,"tag":1224,"props":3229,"children":3230},{"style":2970},[3231],{"type":43,"value":3232}," lock",{"type":37,"tag":1224,"props":3234,"children":3235},{"style":2970},[3236],{"type":43,"value":3031},{"type":37,"tag":1224,"props":3238,"children":3239},{"style":2970},[3240],{"type":43,"value":3241}," were",{"type":37,"tag":1224,"props":3243,"children":3244},{"style":2970},[3245],{"type":43,"value":3246}," regenerated",{"type":37,"tag":1224,"props":3248,"children":3249},{"style":2970},[3250],{"type":43,"value":3251}," and",{"type":37,"tag":1224,"props":3253,"children":3254},{"style":2970},[3255],{"type":43,"value":3256}," how",{"type":37,"tag":1224,"props":3258,"children":3259},{"style":1242},[3260],{"type":43,"value":1526},{"type":37,"tag":1224,"props":3262,"children":3264},{"class":1226,"line":3263},19,[3265],{"type":37,"tag":1224,"props":3266,"children":3267},{"emptyLinePlaceholder":1292},[3268],{"type":43,"value":1295},{"type":37,"tag":1224,"props":3270,"children":3272},{"class":1226,"line":3271},20,[3273],{"type":37,"tag":1224,"props":3274,"children":3275},{"style":1258},[3276],{"type":43,"value":3277},"## Verification\n",{"type":37,"tag":1224,"props":3279,"children":3281},{"class":1226,"line":3280},21,[3282],{"type":37,"tag":1224,"props":3283,"children":3284},{"emptyLinePlaceholder":1292},[3285],{"type":43,"value":1295},{"type":37,"tag":1224,"props":3287,"children":3289},{"class":1226,"line":3288},22,[3290,3295,3299,3304,3309,3314],{"type":37,"tag":1224,"props":3291,"children":3292},{"style":1258},[3293],{"type":43,"value":3294},"- Baseline: ",{"type":37,"tag":1224,"props":3296,"children":3297},{"style":1242},[3298],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3300,"children":3301},{"style":2840},[3302],{"type":43,"value":3303},"path",{"type":37,"tag":1224,"props":3305,"children":3306},{"style":2970},[3307],{"type":43,"value":3308}," or",{"type":37,"tag":1224,"props":3310,"children":3311},{"style":2970},[3312],{"type":43,"value":3313}," summary",{"type":37,"tag":1224,"props":3315,"children":3316},{"style":1242},[3317],{"type":43,"value":1526},{"type":37,"tag":1224,"props":3319,"children":3321},{"class":1226,"line":3320},23,[3322,3327,3331,3336,3340,3345,3350],{"type":37,"tag":1224,"props":3323,"children":3324},{"style":1258},[3325],{"type":43,"value":3326},"- Result: ",{"type":37,"tag":1224,"props":3328,"children":3329},{"style":1242},[3330],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3332,"children":3333},{"style":2840},[3334],{"type":43,"value":3335},"PASS",{"type":37,"tag":1224,"props":3337,"children":3338},{"style":1242},[3339],{"type":43,"value":2398},{"type":37,"tag":1224,"props":3341,"children":3342},{"style":2970},[3343],{"type":43,"value":3344},"REGRESSED:",{"type":37,"tag":1224,"props":3346,"children":3347},{"style":1242},[3348],{"type":43,"value":3349},"\u003Clist>",{"type":37,"tag":1224,"props":3351,"children":3352},{"style":1258},[3353],{"type":43,"value":3354}," \u002F NO-CHECKS>\n",{"type":37,"tag":1224,"props":3356,"children":3358},{"class":1226,"line":3357},24,[3359,3364,3368,3373,3378],{"type":37,"tag":1224,"props":3360,"children":3361},{"style":1258},[3362],{"type":43,"value":3363},"- Output: ",{"type":37,"tag":1224,"props":3365,"children":3366},{"style":1242},[3367],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3369,"children":3370},{"style":2840},[3371],{"type":43,"value":3372},"relevant",{"type":37,"tag":1224,"props":3374,"children":3375},{"style":2970},[3376],{"type":43,"value":3377}," snippet",{"type":37,"tag":1224,"props":3379,"children":3380},{"style":1242},[3381],{"type":43,"value":1526},{"type":37,"tag":1224,"props":3383,"children":3385},{"class":1226,"line":3384},25,[3386],{"type":37,"tag":1224,"props":3387,"children":3388},{"emptyLinePlaceholder":1292},[3389],{"type":43,"value":1295},{"type":37,"tag":1224,"props":3391,"children":3393},{"class":1226,"line":3392},26,[3394],{"type":37,"tag":1224,"props":3395,"children":3396},{"style":1258},[3397],{"type":43,"value":3398},"## How to revert\n",{"type":37,"tag":1224,"props":3400,"children":3402},{"class":1226,"line":3401},27,[3403],{"type":37,"tag":1224,"props":3404,"children":3405},{"emptyLinePlaceholder":1292},[3406],{"type":43,"value":1295},{"type":37,"tag":1224,"props":3408,"children":3409},{"class":1226,"line":24},[3410,3415,3419,3424,3428],{"type":37,"tag":1224,"props":3411,"children":3412},{"style":1258},[3413],{"type":43,"value":3414},"- Drop a single feature: `git revert ",{"type":37,"tag":1224,"props":3416,"children":3417},{"style":1242},[3418],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3420,"children":3421},{"style":2840},[3422],{"type":43,"value":3423},"commit-sha",{"type":37,"tag":1224,"props":3425,"children":3426},{"style":1242},[3427],{"type":43,"value":1622},{"type":37,"tag":1224,"props":3429,"children":3430},{"style":1258},[3431],{"type":43,"value":3432},"`\n",{"type":37,"tag":1224,"props":3434,"children":3436},{"class":1226,"line":3435},29,[3437,3442,3446,3451,3455,3460,3464,3468,3472],{"type":37,"tag":1224,"props":3438,"children":3439},{"style":1258},[3440],{"type":43,"value":3441},"- Discard everything: `git checkout ",{"type":37,"tag":1224,"props":3443,"children":3444},{"style":1242},[3445],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3447,"children":3448},{"style":2840},[3449],{"type":43,"value":3450},"previous-branch",{"type":37,"tag":1224,"props":3452,"children":3453},{"style":1242},[3454],{"type":43,"value":1622},{"type":37,"tag":1224,"props":3456,"children":3457},{"style":1258},[3458],{"type":43,"value":3459}," && git branch -D starter-kit-upgrade\u002F",{"type":37,"tag":1224,"props":3461,"children":3462},{"style":1242},[3463],{"type":43,"value":2837},{"type":37,"tag":1224,"props":3465,"children":3466},{"style":2840},[3467],{"type":43,"value":2917},{"type":37,"tag":1224,"props":3469,"children":3470},{"style":1242},[3471],{"type":43,"value":1622},{"type":37,"tag":1224,"props":3473,"children":3474},{"style":1258},[3475],{"type":43,"value":3432},{"type":37,"tag":116,"props":3477,"children":3479},{"id":3478},"out-of-scope",[3480],{"type":43,"value":3481},"Out of scope",{"type":37,"tag":46,"props":3483,"children":3484},{},[3485,3490,3495,3500,3505],{"type":37,"tag":50,"props":3486,"children":3487},{},[3488],{"type":43,"value":3489},"Detecting which kit \"version\" the user started from. There is no reliable way; we don't pretend.",{"type":37,"tag":50,"props":3491,"children":3492},{},[3493],{"type":43,"value":3494},"Reconciling dep version constraints automatically. We show; the user decides.",{"type":37,"tag":50,"props":3496,"children":3497},{},[3498],{"type":43,"value":3499},"Forks of the starter kits. If the repo's structure isn't recognizable as one of the three official kits, refuse and explain.",{"type":37,"tag":50,"props":3501,"children":3502},{},[3503],{"type":43,"value":3504},"Cross-kit migration (e.g. Vue → React).",{"type":37,"tag":50,"props":3506,"children":3507},{},[3508],{"type":43,"value":3509},"Running linters \u002F formatters on applied files. The user runs their own tooling.",{"type":37,"tag":3511,"props":3512,"children":3513},"style",{},[3514],{"type":43,"value":3515},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3517,"total":2945},[3518,3534,3548,3563,3580,3595,3601,3615,3632],{"slug":3519,"name":3519,"fn":3520,"description":3521,"org":3522,"tags":3523,"stars":3531,"repoUrl":3532,"updatedAt":3533},"socialite-development","integrate OAuth social authentication","Manages OAuth social authentication with Laravel Socialite. Activate when adding social login providers; configuring OAuth redirect\u002Fcallback flows; retrieving authenticated user details; customizing scopes or parameters; setting up community providers; testing with Socialite fakes; or when the user mentions social login, OAuth, Socialite, or third-party authentication.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3524,3526,3527,3530],{"name":1043,"slug":3525,"type":15},"auth",{"name":9,"slug":8,"type":15},{"name":3528,"slug":3529,"type":15},"OAuth","oauth",{"name":17,"slug":18,"type":15},5745,"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fsocialite","2026-07-13T06:22:10.648812",{"slug":3535,"name":3535,"fn":3536,"description":3537,"org":3538,"tags":3539,"stars":3545,"repoUrl":3546,"updatedAt":3547},"octane-development","develop applications with Laravel Octane","Use this skill 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 rebooting for each request like PHP-FPM. Trigger when installing Octane or starting its server; configuring or detecting the active driver for driver-specific code; using Octane::concurrently(), Octane::table(), the Octane cache, or shared in-memory state across workers; controlling worker memory growth; or testing Octane behavior. Skip plain PHP-FPM applications with no persistent worker.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3540,3541,3544],{"name":9,"slug":8,"type":15},{"name":3542,"slug":3543,"type":15},"Performance","performance",{"name":17,"slug":18,"type":15},4021,"https:\u002F\u002Fgithub.com\u002Flaravel\u002Foctane","2026-07-16T06:02:20.284131",{"slug":3549,"name":3549,"fn":3550,"description":3551,"org":3552,"tags":3553,"stars":3560,"repoUrl":3561,"updatedAt":3562},"fortify-development","implement authentication with Laravel Fortify","ACTIVATE when the user works on authentication in Laravel. This includes login, registration, password reset, email verification, two-factor authentication (2FA\u002FTOTP\u002FQR codes\u002Frecovery codes), passkeys, profile updates, password confirmation, or any auth-related routes and controllers. Activate when the user mentions Fortify, auth, authentication, login, register, signup, forgot password, verify email, 2FA, passkeys, WebAuthn, or references app\u002FActions\u002FFortify\u002F, CreateNewUser, UpdateUserProfileInformation, FortifyServiceProvider, config\u002Ffortify.php, or auth guards. Fortify is the frontend-agnostic authentication backend for Laravel that registers all auth routes and controllers. Also activate when building SPA or headless authentication, customizing login redirects, overriding response contracts like LoginResponse, or configuring login throttling. Do NOT activate for Laravel Passport (OAuth2 API tokens), Socialite (OAuth social login), or non-auth Laravel features.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3554,3557,3558,3559],{"name":3555,"slug":3556,"type":15},"2FA","2fa",{"name":1043,"slug":3525,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},1746,"https:\u002F\u002Fgithub.com\u002Flaravel\u002Ffortify","2026-07-13T06:22:28.612049",{"slug":3564,"name":3564,"fn":3565,"description":3566,"org":3567,"tags":3568,"stars":3577,"repoUrl":3578,"updatedAt":3579},"ai-sdk-development","build AI agents with Laravel AI SDK","TRIGGER when working with ai-sdk which is Laravel official first-party AI SDK. Activate when building, editing AI agents, chatbots, text generation, image generation, audio\u002FTTS, transcription\u002FSTT, embeddings, RAG, vector stores, reranking, structured output, streaming, conversation memory, tools, queueing, broadcasting, and provider failover across OpenAI, Anthropic, Gemini, Azure, Groq, xAI, DeepSeek, Mistral, Ollama, ElevenLabs, Cohere, Jina, and VoyageAI. Invoke when the user references ai-sdk, the `Laravel\\Ai\\` namespace, or this project's AI features — not for other AI packages used directly.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3569,3572,3575,3576],{"name":3570,"slug":3571,"type":15},"Agents","agents",{"name":3573,"slug":3574,"type":15},"AI SDK","ai-sdk",{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},1040,"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fai","2026-07-13T06:22:24.770526",{"slug":3581,"name":3581,"fn":3582,"description":3583,"org":3584,"tags":3585,"stars":20,"repoUrl":21,"updatedAt":3594},"deploying-laravel-cloud","deploy Laravel applications to Laravel Cloud","Deploys and manages Laravel applications on Laravel Cloud using the `cloud` CLI. Use when the user wants to deploy an app, ship to cloud, create\u002Fmanage environments, databases, caches, domains, instances, background processes, check billing\u002Fusage\u002Fspend, or any Laravel Cloud infrastructure. Triggers on deploy, ship, cloud management, environment setup, database provisioning, billing\u002Fusage queries, and similar cloud operations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3586,3589,3592,3593],{"name":3587,"slug":3588,"type":15},"CLI","cli",{"name":3590,"slug":3591,"type":15},"Deployment","deployment",{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},"2026-07-13T06:22:18.36234",{"slug":4,"name":4,"fn":5,"description":6,"org":3596,"tags":3597,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3598,3599,3600],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"slug":3602,"name":3602,"fn":3603,"description":3604,"org":3605,"tags":3606,"stars":3612,"repoUrl":3613,"updatedAt":3614},"pennant-development","manage feature flags with Laravel Pennant","Use when working with Laravel Pennant the official Laravel feature flag package. Trigger whenever the query mentions Pennant by name or involves feature flags or feature toggles in a Laravel project. Tasks include defining feature flags checking whether features are active creating class based features in `app\u002FFeatures` using Blade `@feature` directives scoping flags to users or teams building custom Pennant storage drivers protecting routes with feature flags testing feature flags with Pest or PHPUnit and implementing A B testing or gradual rollouts with feature flags. Do not trigger for generic Laravel configuration authorization policies authentication or non Pennant feature management systems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3607,3610,3611],{"name":3608,"slug":3609,"type":15},"Feature Flags","feature-flags",{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},585,"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fpennant","2026-07-13T06:22:26.043758",{"slug":3616,"name":3616,"fn":3617,"description":3618,"org":3619,"tags":3620,"stars":3629,"repoUrl":3630,"updatedAt":3631},"configure-nightwatch","configure Laravel Nightwatch data collection","Configures Laravel Nightwatch data collection, sampling rates, filtering rules, and redaction policies. Use when setting up Nightwatch, managing data volume, protecting sensitive data (PII), or optimizing event collection for production workloads.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3621,3624,3625,3628],{"name":3622,"slug":3623,"type":15},"Configuration","configuration",{"name":9,"slug":8,"type":15},{"name":3626,"slug":3627,"type":15},"Observability","observability",{"name":17,"slug":18,"type":15},368,"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fnightwatch","2026-07-13T06:22:29.945491",{"slug":3633,"name":3633,"fn":3617,"description":3634,"org":3635,"tags":3636,"stars":3645,"repoUrl":3646,"updatedAt":3647},"nightwatch-configure","Configure Laravel Nightwatch data collection, sampling rates, filtering rules, and redaction policies. Use this when setting up Nightwatch, managing data volume, protecting sensitive data (PII), or optimizing event collection for production workloads.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3637,3638,3639,3642],{"name":3622,"slug":3623,"type":15},{"name":9,"slug":8,"type":15},{"name":3640,"slug":3641,"type":15},"Monitoring","monitoring",{"name":3643,"slug":3644,"type":15},"Privacy","privacy",0,"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fnightwatch-cursor-plugin","2026-07-16T06:02:16.946147",{"items":3649,"total":1264},[3650,3657],{"slug":3581,"name":3581,"fn":3582,"description":3583,"org":3651,"tags":3652,"stars":20,"repoUrl":21,"updatedAt":3594},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3653,3654,3655,3656],{"name":3587,"slug":3588,"type":15},{"name":3590,"slug":3591,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":3658,"tags":3659,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3660,3661,3662],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15}]