starter-kit-upgrade
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLaravel Starter Kit Upgrade
Laravel 启动工具包升级
- Users bootstrap from ,
laravel/vue-starter-kit,react-starter-kit, orsvelte-starter-kit, then customize. They own the code.livewire-starter-kit - We pick specific features from upstream (e.g. "toast notifications", "2FA autofocus fix"), not "version upgrades."
- The user's git history is unrelated to the kit's. There is no common ancestor. We compare user-now vs upstream-now, byte by byte.
- We never auto-merge a customized file. Customizations are surfaced; the user decides.
- Behavior preservation is the contract: the user's currently-passing tests/typecheck/build must still pass after.
- 用户基于 、
laravel/vue-starter-kit、react-starter-kit或svelte-starter-kit初始化项目,之后进行自定义开发,代码归用户所有。livewire-starter-kit - 我们从上游选取特定功能(例如“提示通知”、“双因素认证自动聚焦修复”),而非进行“版本升级”。
- 用户的Git历史与工具包的历史无关,没有共同祖先。我们逐字节对比用户当前代码与上游最新代码。
- 绝不会自动合并已自定义的文件。自定义内容会被明确展示,由用户决定处理方式。
- 行为一致性是核心约定:用户当前通过的测试、类型检查和构建任务,在升级后仍需保持可通过状态。
Safety contract: non-negotiable
安全约定:不可协商
Read these to the user before any side effects, and live by them throughout:
- Working tree must be clean. If is non-empty, refuse and tell the user to commit or stash. Do not "stash for them."
git status --porcelain - All work happens on a dedicated branch (). The user's current branch is never modified.
starter-kit-upgrade/<short-id> - Each applied feature is its own commit. That is how revertability works.
- Never auto-resolve conflicts. A change touching customized code is surfaced; default action is to skip the file.
- Never silently overwrite manifests or lockfiles (,
composer.json,package.json). Show diffs; let the user decide.*-lock.* - Verify behavior preservation. Re-run the user's tests/typecheck/build after applying. A previously-passing check that now fails is a regression. Stop, surface, recommend revert.
- Detect from unambiguous signals; ask when ambiguous. Concrete evidence (e.g. exists) is fine. Picking a likely answer when signals are mixed or absent is not.
config/fortify.php
If any of these is violated, abort with a clear message about what went wrong and how to recover.
在产生任何副作用前,需向用户告知以下内容,并在整个流程中严格遵守:
- 工作树必须保持干净。如果 返回非空内容,需拒绝执行并告知用户提交或暂存更改,不得代用户执行“暂存”操作。
git status --porcelain - 所有操作都在专用分支()上进行,绝不会修改用户当前分支。
starter-kit-upgrade/<short-id> - 每个应用的功能对应一个独立提交,以此保证可回滚性。
- 绝不自动解决冲突。涉及自定义代码的变更会被展示,默认操作是跳过该文件。
- 绝不静默覆盖清单文件或锁文件(、
composer.json、package.json)。需展示差异,由用户决定处理方式。*-lock.* - 验证行为一致性。应用功能后重新运行用户的测试、类型检查和构建任务。如果之前通过的检查现在失败,视为回归问题,需停止操作、展示问题并建议回滚。
- 基于明确信号进行判断;存在歧义时询问用户。具体证据(例如存在 文件)可作为判断依据,信号混杂或缺失时不得随意猜测。
config/fortify.php
如果违反上述任何一条,需终止操作并清晰告知问题所在及恢复方法。
Required tools
必备工具
- (in the user's project)
git - (authenticated;
ghreturns OK)gh auth status - (used by
jq)run_tests.sh - (for the bundled scripts)
bash
If any is missing, stop in Phase 4 and tell the user how to install.
- (用户项目中已安装)
git - (已完成认证;
gh返回OK)gh auth status - (
jq脚本依赖)run_tests.sh - (用于执行附带脚本)
bash
如果缺少任何工具,需在第4阶段停止操作并告知用户安装方法。
Gotchas
注意事项
Environment-specific behavior the agent will get wrong without being told. Read these before starting the workflow and apply throughout.
-
Parallel implementations. When a feature hasfiles plus
newto 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 thediffersfiles 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.new -
Renamed paths. If apath's basename or class name already exists elsewhere in the user's repo, the user has likely renamed/moved it. Surface, don't auto-apply, or you'll create a duplicate. Show them the upstream change and let them apply it to their renamed file by hand or wait for user confirmation.
new -
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 toinstead of
<sha>:<path>.HEAD:<path> -
Transitive imports. New files oftenfrom helpers that are NOT in the same feature commit (Vue/React/Svelte:
import,@/lib/...; Livewire:@/components/...,@include,<x-...>). Phase 5 step 4 covers the scan; never declare a feature applied without it. Uncovered imports show up as runtime/compile errors.<livewire:...> -
Lockfile drift. Manifests are user-curated. Never overwrite. Walk the user through the upstream diff, let them merge, then regenerate lockfiles via the package manager (Phase 6).
-
Stale node_modules after major bumps. After Vite v7 → v8, React 18 → 19, etc.,often fails with
npm install. Clean and reinstall (Phase 6).ERESOLVE -
New migrations. When upstream adds migrations (e.g. "Catch migrations up to Skeleton"), surface them separately. Recommendfirst; applying a new migration on a populated DB can fail loudly.
php artisan migrate:status -
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 MCP slash command first, then come back and re-run this skill against the resulting (clean-tree) repo. If Boost is not yet installed:(requires Boost
composer require laravel/boost --dev && php artisan boost:install). Slash commands:^2.0- Laravel 12 → 13:
/upgrade-laravel-v13 - Livewire 3 → 4:
/upgrade-livewire-v4 - Inertia v2 → v3:
/upgrade-inertia-v3
- Laravel 12 → 13:
-
Already-present features. If Phase 2's pre-filter missed it and Phase 5's classifier reports every file as, skip the feature with a note: "every file matches upstream's current; moving on." Don't commit an empty commit.
already-present -
More than ~50. The per-file walkthrough is too tedious to be useful at that scale. Stop, recommend manual upgrade for that feature.
differs
以下是Agent未被告知时容易出错的环境特定行为,开始工作流前需阅读并全程遵守:
-
并行实现:当一个功能包含新增文件以及对调用位置的修改时,用户可能已经有内部等效实现(例如自己的提示助手、验证规则等)。需整体展示该功能,不得单独应用新增文件并认为其“安全”。默认操作是跳过整个功能,用户可选择采用上游版本并后续移除自己的实现。
-
路径重命名:如果新增路径的基名或类名已存在于用户仓库的其他位置,说明用户可能已重命名或移动了该文件。需展示该情况,不得自动应用,否则会创建重复文件。需向用户展示上游变更,让用户手动将变更应用到自己重命名后的文件,或等待用户确认。
-
上游后续编辑:复制上游HEAD会引入该功能提交后的所有变更,而非仅该功能本身的变更。应用前必须执行第5阶段第2步的检查。如果存在后续编辑,需将范围限定为而非
<sha>:<path>。HEAD:<path> -
传递导入:新增文件通常会导入不在同一功能提交中的助手(Vue/React/Svelte:、
@/lib/...;Livewire:@/components/...、@include、<x-...>)。第5阶段第4步会扫描此类导入;未完成该步骤不得宣称功能已应用。未覆盖的导入会导致运行时/编译错误。<livewire:...> -
锁文件偏移:清单文件由用户维护,绝不覆盖。需引导用户查看上游差异,让用户合并后再通过包管理器重新生成锁文件(第6阶段)。
-
大版本升级后陈旧的node_modules:例如从Vite v7升级到v8、React 18升级到19后,常因
npm install失败。需清理并重新安装(第6阶段)。ERESOLVE -
新迁移文件:当上游添加迁移文件(例如“同步迁移至Skeleton版本”)时,需单独展示。建议先运行;在已有数据的数据库上应用新迁移可能会导致严重失败。
php artisan migrate:status -
作为功能的框架大版本升级:诸如Laravel 12→13、Livewire 3→4或Inertia v2→v3等升级规模过大且破坏性强,不适合按功能逐个处理的流程。不得通过此技能尝试此类升级,而是提示用户先运行对应的Laravel Boost MCP斜杠命令,之后再针对生成的(干净工作树)仓库重新运行此技能。如果尚未安装Boost:(要求Boost
composer require laravel/boost --dev && php artisan boost:install)。斜杠命令如下:^2.0- Laravel 12→13:
/upgrade-laravel-v13 - Livewire 3→4:
/upgrade-livewire-v4 - Inertia v2→v3:
/upgrade-inertia-v3
- Laravel 12→13:
-
已存在的功能:如果第2阶段的预筛选未发现,且第5阶段的分类器显示所有文件均为,则跳过该功能并备注:“所有文件与上游当前版本一致;继续执行”。不得提交空提交。
already-present -
超过约50个文件:此时逐个文件的遍历过于繁琐,失去实用价值。需停止操作,建议用户手动升级该功能。
differs
Workflow
工作流
Eight phases, in order. Each phase establishes invariants the next relies on.
共八个阶段,按顺序执行。每个阶段都会建立后续阶段依赖的不变量。
Phase 1: Identify the kit and branch variant
阶段1:识别工具包和分支变体
Inspect the user's project:
| vue | react | svelte | livewire | |
|---|---|---|---|---|
| Cue | | | | no |
| | | | n/a |
| n/a | n/a | n/a | |
State the detected kit out loud. If only one column matches, proceed. If two columns partially match (e.g. both and present, or lists and ), stop and ask.
.vue.tsxpackage.jsonvuereactThen determine the branch variant. There are four branches per kit, formed by two independent axes:
- Auth axis (read ):
composer.json- Fortify if has
composer.json, orlaravel/fortifyexists, orconfig/fortify.phpexists, orapp/Actions/Fortify/exists.app/Providers/FortifyServiceProvider.php - WorkOS if has
composer.jsonand none of the Fortify markers are present.laravel/workos
- Fortify if
- Teams axis (check whether team scaffolding is present):
- Teams if exists (usually accompanied by
app/Models/Team.php,Membership.php, and aTeamInvitation.phpmigration)...._create_teams_table.php - Non-teams otherwise.
- Teams if
Combine the two axes to get the branch name:
| Auth | Teams | Branch |
|---|---|---|
| Fortify | no | |
| Fortify | yes | |
| WorkOS | no | |
| WorkOS | yes | |
State the detected branch out loud. Only ask if signals are contradictory (e.g. Fortify markers present and in composer, or a model with no teams migration); that means user customization you can't safely guess at.
laravel/workosTeam.php检查用户项目:
| vue | react | svelte | livewire | |
|---|---|---|---|---|
| 判断线索 | | | | 不存在 |
| | | | 无相关内容 |
| 无相关内容 | 无相关内容 | 无相关内容 | |
需向用户明确说明检测到的工具包。如果只有一列匹配,继续执行;如果两列部分匹配(例如同时存在 和 文件,或 同时列出 和 ),需停止操作并询问用户。
.vue.tsxpackage.jsonvuereact然后确定分支变体。每个工具包有四个分支,由两个独立维度组合而成:
- 认证维度(读取 ):
composer.json- 如果 包含
composer.json,或存在laravel/fortify文件,或存在config/fortify.php目录,或存在app/Actions/Fortify/文件,则为Fortify分支。app/Providers/FortifyServiceProvider.php - 如果 包含
composer.json且无任何Fortify标识,则为WorkOS分支。laravel/workos
- 如果
- 团队维度(检查是否存在团队脚手架):
- 如果存在 文件(通常伴随
app/Models/Team.php、Membership.php和TeamInvitation.php迁移文件),则为Teams分支。..._create_teams_table.php - 否则为非Teams分支。
- 如果存在
组合两个维度得到分支名称:
| 认证类型 | 团队支持 | 分支名称 |
|---|---|---|
| Fortify | 否 | |
| Fortify | 是 | |
| WorkOS | 否 | |
| WorkOS | 是 | |
需向用户明确说明检测到的分支。仅当信号矛盾时(例如同时存在Fortify标识和 ,或存在 模型但无团队迁移文件)才询问用户,这意味着存在无法安全猜测的用户自定义内容。
laravel/workosTeam.phpPhase 2: Enumerate available upstream features
阶段2:枚举可用的上游功能
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.
Fetch raw data. The default window is the last 100 commits / 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 , , etc. or raise .
&page=2&page=3--limitbash
gh api "repos/laravel/<kit>/commits?sha=<branch>&per_page=100" \
-q '.[] | {sha: .sha[0:7], date: .commit.author.date[0:10], msg: .commit.message | split("\n")[0]}'
gh pr list --repo "laravel/<kit>" --state merged --base "<branch>" --limit 100 \
--json number,title,mergeCommit,mergedAtCluster commits/PRs into user-facing features. Examples a user would recognize:
- "Toast notifications across all kits" (1 commit, several files)
- "Password visibility toggle in auth forms" (1 commit, 3 files)
- "2FA autofocus fix" (1 commit, 1 file)
- "Teams support" (1 PR, many files; flag as large)
- "Inertia 3 upgrade" (lockfile-heavy; flag as needing review)
- "Maintenance: formatting / lint config" (bucket of small commits)
Bucket internal/refactor commits as a single "Maintenance" entry. The user usually skips it.
Pre-filter: for each candidate feature, run against its commit. If every file is , mark and skip by default.
scripts/classify_feature.shalready-present[!] Already present用户无法可靠告知你“他们当前使用的版本”(我们也不尝试获取)。检查当前上游状态并展示功能目录。
获取原始数据。默认范围是最近100次提交/已合并PR;需提前告知用户,以便他们了解早于该范围的功能不会出现在目录中。如果用户初始化项目的时间远早于该范围,可通过 、 等参数回溯,或增大 值。
&page=2&page=3--limitbash
gh api "repos/laravel/<kit>/commits?sha=<branch>&per_page=100" \
-q '.[] | {sha: .sha[0:7], date: .commit.author.date[0:10], msg: .commit.message | split("\n")[0]}'
gh pr list --repo "laravel/<kit>" --state merged --base "<branch>" --limit 100 \
--json number,title,mergeCommit,mergedAt将提交/PR归类为用户可识别的功能。示例如下:
- “所有工具包新增提示通知”(1次提交,多个文件)
- “认证表单中密码可见性切换”(1次提交,3个文件)
- “双因素认证自动聚焦修复”(1次提交,1个文件)
- “团队支持”(1个PR,大量文件;标记为大型功能)
- “Inertia 3升级”(涉及大量锁文件;标记为需仔细审核)
- “维护:格式化/ lint配置”(多个小提交的集合)
将内部/重构提交归类为单个“维护”条目,用户通常会跳过该条目。
预筛选:对每个候选功能,针对其提交运行 。如果所有文件均为 ,标记为 并默认跳过。
scripts/classify_feature.shalready-present[!] 已存在Phase 3: Present the catalog and get explicit selection
阶段3:展示功能目录并获取明确选择
Available upstream features (vue-starter-kit, branch: main):
[ ] Toast notifications · PR #142, 4 files, 1 lockfile
[ ] Password visibility toggle · PR #131, 3 files
[ ] 2FA autofocus fix · commit 78fda0c, 1 file
[ ] Teams support · PR #98, 23 files (LARGE)
[~] Inertia 3 upgrade · PR #110, lockfile-heavy (review carefully)
[!] Already present: Vite font plugin
Which would you like to pull in?Wait for the selection. Recap the picks and the affected file counts. Ask one final time before any side effects.
可用上游功能(vue-starter-kit,分支:main):
[ ] 提示通知 · PR #142,4个文件,1个锁文件
[ ] 密码可见性切换 · PR #131,3个文件
[ ] 双因素认证自动聚焦修复 · 提交 78fda0c,1个文件
[ ] 团队支持 · PR #98,23个文件(大型)
[~] Inertia 3升级 · PR #110,涉及大量锁文件(需仔细审核)
[!] 已存在:Vite字体插件
你想要拉取哪些功能?等待用户选择。重述用户选择的功能及涉及的文件数量。在产生任何副作用前最后确认一次。
Phase 4: Preflight, baseline, and workspace setup
阶段4:预检、基准记录和工作区设置
Run preflight:
bash
scripts/preflight.sh <user_repo>It checks the repo is a git repo, the tree is clean, and that (authenticated) and are available. If it exits non-zero, surface the message verbatim and stop.
ghjqRecord a verification baseline so Phase 7 can distinguish regressions from pre-existing failures. Use so concurrent runs don't clobber each other:
mktempbash
baseline=$(mktemp -t skup-baseline.XXXXXX.json)
scripts/run_tests.sh <user_repo> --baseline "$baseline"Hold onto ; Phase 7 needs it.
$baselineFetch the upstream kit and capture its path:
bash
kit_dir=$(scripts/fetch_kit.sh <kit> <branch>)Hold onto ; Phase 5 needs it. The script is idempotent: re-running with the same args fetches the latest branch tip rather than re-cloning.
$kit_dirCreate the upgrade branch:
bash
git -C <user_repo> checkout -b "starter-kit-upgrade/$(date +%Y%m%d-%H%M)-<first-slug>"If the user is already on a branch (a previous run that didn't get cleaned up), will refuse if the new name collides. Don't auto-resolve: ask whether they want to resume on that branch (skip the , keep going from where they were), start fresh (the new timestamped name will already differ by minute, so just retry — or bump to if it's the same minute), or abort so they can clean up manually. Never delete the existing branch on their behalf.
starter-kit-upgrade/...checkout -bcheckout -b+%Y%m%d-%H%M%SFrom this point on, every write goes to this branch.
运行预检:
bash
scripts/preflight.sh <user_repo>该脚本会检查仓库是否为Git仓库、工作树是否干净,以及 (已认证)和 是否可用。如果脚本返回非零值,需原样展示错误信息并停止操作。
ghjq记录验证基准,以便第7阶段区分回归问题与预先存在的失败。使用 避免并发运行时互相覆盖:
mktempbash
baseline=$(mktemp -t skup-baseline.XXXXXX.json)
scripts/run_tests.sh <user_repo> --baseline "$baseline"需保留 ,第7阶段会用到。
$baseline拉取上游工具包并记录其路径:
bash
kit_dir=$(scripts/fetch_kit.sh <kit> <branch>)需保留 ,第5阶段会用到。该脚本具有幂等性:使用相同参数重新运行会拉取最新分支尖端,而非重新克隆。
$kit_dir创建升级分支:
bash
git -C <user_repo> checkout -b "starter-kit-upgrade/$(date +%Y%m%d-%H%M)-<first-slug>"如果用户已处于 分支(之前未清理的运行残留), 会因新名称冲突而拒绝执行。不得自动解决:需询问用户是要继续在该分支上执行(跳过 ,从当前位置继续)、重新开始(新的时间戳分支名称通常会因分钟不同而不同,可重试;如果是同一分钟,可改为 ),还是终止操作以便用户手动清理。绝不得代用户删除现有分支。
starter-kit-upgrade/...checkout -bcheckout -b+%Y%m%d-%H%M%S从此时起,所有写入操作都将针对该分支。
Phase 5: Apply each selected feature
阶段5:应用每个选中的功能
For each selected feature, in order:
- Classify. Run . Statuses:
scripts/classify_feature.sh <kit_dir> <sha> <user_repo>
- : file does not exist in user repo, exists at upstream HEAD. Safe to add.
new - : user's file is byte-identical to upstream HEAD. Skip.
already-present - : user has the file and bytes differ from upstream HEAD. Surface.
differs - : upstream HEAD lacks the file but the user has it. Surface; default is keep theirs.
deleted-upstream - : manifest or lock file. Surface; never auto-merge.
lockfile
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.
- Later-edits check. Find which feature paths later upstream commits also modified:
bash
scripts/later_edits.sh <kit_dir> <sha> <user_repo>Each path the script prints is a path where copying upstream HEAD's content pulls later changes in too. Diff against ; if a non-whitespace hunk differs, scope to the feature commit () and note it in the report.
<sha>:<path>HEAD:<path>git -C <kit_dir> show <sha>:<path>3. Apply files. The script writes upstream HEAD's content for each path and stages it; everything else is left for steps 4–5:
newnewbash
scripts/apply_new_files.sh <kit_dir> <sha> <user_repo>It prints for each file written so you can collect the list for the feature's commit message and the report.
applied <path>Before letting the script run, check for the rename gotcha (see Gotchas → "Renamed paths"). If a path's basename already exists at a different location in the user's repo, surface to the user before applying.
new4. 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/React/Svelte handle TS/JS imports; Livewire handles Blade includes / components / tags):
x-livewire:bash
scripts/scan_transitive_imports.sh <kit> <new_files...>Output is per import. For each match, verify the corresponding helper file exists in the user's repo. If not, the new files won't compile/render; flag the missing target as a follow-up dependency the user needs to fetch (same walkthrough as ).
<file>:<line>:<match>differs5. Walk the user through , , and . One file at a time:
differsdeleted-upstreamlockfile- Show what upstream has: (or
git -C <kit_dir> show HEAD:<path>if<sha>:<path>flagged this path).later_edits.sh - Show their current file.
- Show the diff between the two.
- 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).
- 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.
- Stage whatever they chose: .
git -C <user_repo> add <path>
For : never overwrite the manifest. Show the upstream diff for / , walk them through the relevant change, let them edit the manifest. Lockfile regeneration happens in Phase 6.
lockfilecomposer.jsonpackage.json6. Commit the feature as one revertable unit:
bash
git -C <user_repo> commit -m "starter-kit-upgrade: <feature name>
Upstream: laravel/<kit>@<sha>
Files added: <list>
Files updated (took upstream): <list>
Files updated (manual merge): <list>
Files kept as-is: <list>"If the user wants to bail out at any point, leave the branch as-is. They can drop it with .
git branch -D按顺序处理每个选中的功能:
- 分类。运行 。状态包括:
scripts/classify_feature.sh <kit_dir> <sha> <user_repo>
- :用户仓库中不存在该文件,上游HEAD中存在。可安全添加。
new - :用户的文件与上游HEAD的文件字节完全一致。跳过。
already-present - :用户拥有该文件,且与上游HEAD的文件字节不同。需展示该情况。
differs - :上游HEAD中无该文件,但用户仓库中有。需展示该情况;默认操作是保留用户的文件。
deleted-upstream - :清单文件或锁文件。需展示该情况;绝不自动合并。
lockfile
分类器仅与上游HEAD对比。用户的Git历史不追溯至工具包的历史,因此没有可用于合并的“之前版本”基准;我们不尝试此类操作。功能提交仅列出需要检查的路径。
- 后续编辑检查。找出上游后续提交也修改过的功能路径:
bash
scripts/later_edits.sh <kit_dir> <sha> <user_repo>脚本输出的每个路径,都是复制上游HEAD内容会引入后续变更的路径。对比 与 ;如果存在非空白差异块,需将范围限定为功能提交()并在报告中备注。
<sha>:<path>HEAD:<path>git -C <kit_dir> show <sha>:<path>3. 应用文件。该脚本会为每个路径写入上游HEAD的内容并暂存;其他内容留到步骤4-5处理:
newnewbash
scripts/apply_new_files.sh <kit_dir> <sha> <user_repo>脚本会打印 以便你收集功能提交消息和报告所需的文件列表。
applied <path>在运行脚本前,需检查重命名注意事项(见注意事项→“路径重命名”)。如果路径的基名已存在于用户仓库的其他位置,需在应用前告知用户。
new4. 传递导入检查。新增文件通常会导入不在同一功能提交中的助手。脚本会根据工具包选择正确的正则表达式(Vue/React/Svelte处理TS/JS导入;Livewire处理Blade包含/ 组件/ 标签):
x-livewire:bash
scripts/scan_transitive_imports.sh <kit> <new_files...>输出格式为 ,对应每个导入。需验证每个匹配的助手文件是否存在于用户仓库中。如果不存在,新增文件将无法编译/渲染;需标记缺失的目标为用户需要拉取的后续依赖(处理方式与相同)。
<file>:<line>:<match>differs5. 引导用户处理、和。逐个文件处理:
differsdeleted-upstreamlockfile- 展示上游内容:(如果
git -C <kit_dir> show HEAD:<path>标记了该路径,则展示later_edits.sh)。<sha>:<path> - 展示用户当前的文件。
- 展示两者之间的差异。
- 让用户选择:完全采用上游版本(会丢失自定义内容;需先确认)、保留自己的文件,或手动合并(你生成统一差异供参考,用户编写结果)。
- 如果用户不确定,需再次展示差异并询问。仍不确定则保留用户的文件并继续。不得静默选择。
- 暂存用户选择的结果:。
git -C <user_repo> add <path>
对于:绝不覆盖清单文件。展示/的上游差异,引导用户查看相关变更,让用户编辑清单文件。锁文件重新生成在第6阶段进行。
lockfilecomposer.jsonpackage.json6. 将功能作为可回滚的单元提交:
bash
git -C <user_repo> commit -m "starter-kit-upgrade: <功能名称>
上游来源:laravel/<kit>@<sha>
新增文件:<列表>
更新文件(采用上游版本):<列表>
更新文件(手动合并):<列表>
保留原文件:<列表>"如果用户在任何时候想要退出,需保留该分支。用户可通过 删除该分支。
git branch -DPhase 6: Reconcile manifests if needed
阶段6:按需协调清单文件
If any feature touched a manifest, lockfiles are out of sync. After the user agrees, run:
bash
scripts/reconcile_manifests.sh <user_repo>The script runs (when + are both present), auto-detects the JS package manager from the existing lockfile, runs , and on failure (typically after a major bump like Vite v7 → v8 or React 18 → 19) wipes + the lockfile and retries once.
composer installcomposer.jsoncomposer.lock<pm> installERESOLVEnode_modulesCommit lockfile updates as a separate commit so they can be reverted independently.
starter-kit-upgrade: dependency lockfiles如果任何功能修改了清单文件,锁文件将不同步。用户同意后运行:
bash
scripts/reconcile_manifests.sh <user_repo>该脚本会运行 (当和同时存在时),从现有锁文件自动检测JS包管理器,运行 ,如果失败(通常是Vite v7→v8或React 18→19等大版本升级后的错误),会清除和锁文件并重试一次。
composer installcomposer.jsoncomposer.lock<pm> installERESOLVEnode_modules将锁文件更新作为单独的 提交,以便独立回滚。
starter-kit-upgrade: 依赖锁文件Phase 7: Verify behavior preservation
阶段7:验证行为一致性
Compare against the baseline:
bash
scripts/run_tests.sh <user_repo> --compare "$baseline"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.
If a regression is reported:
- Show the failing output from the per-check log file the script points to.
- Recommend first; if that doesn't fix it, revert again.
git revert HEAD - For multi-feature uncertainty, suggest .
git bisect start <upgrade-branch> <previous-branch> - Do not edit code to make the failing check pass; that violates the behavior contract.
If the project has no discoverable verification commands, say so explicitly in the report. Don't pretend verification happened.
与基准对比:
bash
scripts/run_tests.sh <user_repo> --compare "$baseline"对比模式会运行PHP测试、JS类型检查、JS构建(无论存在哪一种),仅报告基准中通过但现在失败的检查项。预先存在的失败不属于升级的问题,不会阻止流程。
如果报告存在回归问题:
- 展示脚本指向的检查日志文件中的失败输出。
- 建议先执行 ;如果无法修复,再次回滚。
git revert HEAD - 如果不确定是哪个功能导致的,建议执行 。
git bisect start <upgrade-branch> <previous-branch> - 不得修改代码使失败的检查通过;这违反行为一致性约定。
如果项目没有可检测到的验证命令,需在报告中明确说明。不得假装已完成验证。
Phase 8: Write the report
阶段8:编写报告
Write to (where matches the upgrade branch's ) 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 or kept out of tree.
/tmp/starter-kit-upgrade-report-<id>.md<id>starter-kit-upgrade/<id>STARTER_KIT_UPGRADE.mdmarkdown
undefined先写入 (其中与升级分支的一致);绝不得静默写入用户仓库。标记id可避免并发运行和重新运行时互相覆盖。需展示文件路径并询问用户是否要将其复制为或保留在仓库外。
/tmp/starter-kit-upgrade-report-<id>.md<id>starter-kit-upgrade/<id>STARTER_KIT_UPGRADE.mdmarkdown
undefinedStarter Kit Upgrade Report
启动工具包升级报告
- Date: <date>
- Kit: laravel/<kit>
- Branch tracked: <branch>
- Upgrade branch: starter-kit-upgrade/<id>
- 日期:<日期>
- 工具包:laravel/<kit>
- 跟踪分支:<branch>
- 升级分支:starter-kit-upgrade/<id>
Features applied
已应用功能
- <feature name> · laravel/<kit>@<sha> · <N files>
- Applied: <list>
- Skipped: <list with reasons>
- Manual decisions: <if any, with reasoning>
- Later-edit drift avoided: <if any, with paths scoped manually>
- <功能名称> · laravel/<kit>@<sha> · <N个文件>
- 已应用:<列表>
- 已跳过:<列表及原因>
- 手动决策:<如有,说明理由>
- 避免的后续编辑偏移:<如有,说明手动限定的路径>
Lockfile updates
锁文件更新
<which lock files were regenerated and how>
<哪些锁文件被重新生成及方式>
Verification
验证结果
- Baseline: <path or summary>
- Result: <PASS / REGRESSED:<list> / NO-CHECKS>
- Output: <relevant snippet>
- 基准:<路径或摘要>
- 结果:<通过 / 回归:<列表> / 无检查项>
- 输出:<相关片段>
How to revert
回滚方法
- Drop a single feature:
git revert <commit-sha> - Discard everything:
git checkout <previous-branch> && git branch -D starter-kit-upgrade/<id>
undefined- 回滚单个功能:
git revert <提交sha> - 丢弃所有变更:
git checkout <之前的分支> && git branch -D starter-kit-upgrade/<id>
undefinedOut of scope
超出范围
- Detecting which kit "version" the user started from. There is no reliable way; we don't pretend.
- Reconciling dep version constraints automatically. We show; the user decides.
- Forks of the starter kits. If the repo's structure isn't recognizable as one of the three official kits, refuse and explain.
- Cross-kit migration (e.g. Vue → React).
- Running linters / formatters on applied files. The user runs their own tooling.
- 检测用户最初使用的工具包“版本”。没有可靠的方法;我们不尝试。
- 自动协调依赖版本约束。我们仅展示差异,由用户决定。
- 启动工具包的分支。如果仓库结构无法识别为三个官方工具包之一,需拒绝执行并说明原因。
- 跨工具包迁移(例如Vue→React)。
- 对应用的文件运行代码检查器/格式化工具。用户需运行自己的工具链。