Merge Up
symfony/symfony
Cascade-merge maintained Symfony branches from oldest to newest (e.g.
Cascade-merge the maintained Symfony UX branches from oldest to newest (2.x - 3.x), resolve conflicts, run the affected packages' tests and prepare the push.
$ npx skills add symfony/ux --skill merge-up -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install symfony/ux merge-up --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/symfony/ux.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/merge-up .claude/skills/merge-up && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "merge-up" agent skill from https://github.com/symfony/ux/tree/3.x/.agents/skills/merge-up into .claude/skills/merge-up/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "merge-up", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/symfony/ux/tree/3.x/.agents/skills/merge-upType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add symfony/ux --skill merge-up -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install symfony/ux merge-up --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/symfony/ux.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/merge-up .agents/skills/merge-up && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "merge-up" agent skill from https://github.com/symfony/ux/tree/3.x/.agents/skills/merge-up into .agents/skills/merge-up/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "merge-up", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add symfony/ux --skill merge-up -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install symfony/ux merge-up --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/symfony/ux.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/merge-up .cursor/skills/merge-up && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "merge-up" agent skill from https://github.com/symfony/ux/tree/3.x/.agents/skills/merge-up into .cursor/skills/merge-up/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "merge-up", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/symfony/ux.git --path .agents/skills/merge-up--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add symfony/ux --skill merge-up -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install symfony/ux merge-up --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/symfony/ux.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/merge-up .gemini/skills/merge-up && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "merge-up" agent skill from https://github.com/symfony/ux/tree/3.x/.agents/skills/merge-up into .gemini/skills/merge-up/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "merge-up", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install symfony/ux merge-upInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add symfony/ux --skill merge-up -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/symfony/ux.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/merge-up .github/skills/merge-up && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "merge-up" agent skill from https://github.com/symfony/ux/tree/3.x/.agents/skills/merge-up into .github/skills/merge-up/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "merge-up", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add symfony/ux --skill merge-up -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install symfony/ux merge-up --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/symfony/ux.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/merge-up .opencode/skills/merge-up && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "merge-up" agent skill from https://github.com/symfony/ux/tree/3.x/.agents/skills/merge-up into .opencode/skills/merge-up/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "merge-up", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
merge-upCascade-merge the maintained Symfony UX branches from oldest to newest (2.x - 3.x), resolve conflicts, run the affected packages' tests and prepare the push.
Merge Up is an agent skill from symfony/ux. Cascade-merge the maintained Symfony UX branches from oldest to newest (2.x - 3.x), resolve conflicts, run the affected packages' tests and prepare the push. Use when the user wants the maintained branches merged up or synced.
Its SKILL.md is about 3.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development. It works with Symfony and Git. The repository describes itself as: Symfony UX initiative: a JavaScript ecosystem for Symfony. The licence is MIT.
3 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 93cda70. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitcomposerpnpmphpFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git and pnpm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Merge Up loads about 3.4k tokens when it runs. Until then it costs about 59 tokens; SKILL.md has 1,892 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from symfony/ux at commit 93cda70, republished under its MIT licence (© symfony). 1,892 words, ~3,357 tokens.
.claude/skills/merge-up/SKILL.md (or your agent's skills folder).Merges each maintained branch into the next one, from oldest to newest.
Whenever the skill says "Wait for confirmation", treat anything other than an explicit affirmative as no: stop and ask the user how they want to proceed.
git status --porcelain --untracked-files=noIf any output, stop:
"The working tree is not clean. Please commit or stash your changes first."
The maintained branches, oldest first:
Store them as BRANCHES.
For each branch in BRANCHES:
git checkout <branch>
git pull --ff-only upstream <branch>Using --ff-only ensures local branches haven't diverged from upstream. If the
pull fails, stop and report the error.
For each consecutive pair (SOURCE, TARGET) in BRANCHES:
git checkout <TARGET>Read the merge-up notes of the incoming pull requests first. The bot copies the whole pull request description into the merge commit, so the authors' own instructions for this merge are already in the local history. A description can end with a "Merge-up to <branch>" paragraph naming the declarations to add, the style the target branch expects, or the resolved code itself:
git log --merges --format=%H <TARGET>..<SOURCE> \
| xargs -I{} git log -1 --format=%B {} \
| grep -inE 'merge(d| )?-?up|adapt|on [0-9]+\.x'Prefer the resolution a note gives over an equivalent one of your own: it is what the author wrote the change for and usually ran on the target branch already, and a merge commit is the wrong place for a refactor. A note also covers files that merge cleanly, which is why this runs before the merge and not only when git reports a conflict.
git merge <SOURCE>Three outcomes are possible:
<TARGET> already up-to-date with <SOURCE>"
and skip to the next pair.List conflicts:
git diff --name-only --diff-filter=URead each conflicted file, resolve it, then git add it by name. When all are resolved:
git commit --no-edit| File pattern | Strategy |
|---|---|
CHANGELOG*.md | Keep entries from both sides; newer branch entries on top |
version in assets/package.json, version constants | Keep the TARGET branch value |
assets/dist/** | Never merge by hand. Resolve the sources first, then rebuild the package on the TARGET (cd src/<NAME>/assets && pnpm run build) and stage the result: CI's "Dist Files Unbuilt" job fails when dist/ does not match a fresh build |
.github/workflows/*.yaml, CI config | Keep the TARGET value for branch-specific pins. A job merged from SOURCE may carry SOURCE's php-version (2.x runs PHP 8.1+); bump it to the TARGET's minimum (3.x runs PHP 8.4+) |
| Idiom the TARGET replaced (logic extracted to a trait, a method or class removed) | Take the TARGET version; the SOURCE change is superseded. git checkout --ours <file>, then re-apply the part of the SOURCE fix the TARGET still needs |
| File the TARGET deleted (modify/delete conflict) | Keep it deleted if the TARGET removed the feature (confirm with git log <TARGET> -- <file>); the SOURCE edit is moot. git rm <file> |
Test using docblock metadata (@dataProvider, @testWith, @group legacy) | Convert to attributes (#[DataProvider(...)], #[TestWith([...])], #[Group(...)]). 3.x runs PHPUnit 11/12, where doc-comment metadata is deprecated and then ignored, so the data sets are never passed and the test errors with "too few arguments" |
Compat guard added by SOURCE (class_exists() / method_exists() fallback for a symbol an older dependency may lack) | Check whether the TARGET dropped it on purpose: git log <TARGET> -S'<guard text>' -- <file>. If it did, take SOURCE's new structure but leave the guard out |
| Both sides added a member at the same spot (no overlapping content, git just collapsed them onto a shared closing) | Keep both. Give each its own terminator: two elseif branches each need their own return/closing brace, and two methods each need their own }. Private methods go last, after all public ones |
| Code files | Merge logically based on context; when unsure, ask the user |
3.x removed what 2.x deprecated and raised the minimum PHP from 8.1 to 8.4. When merging 2.x into 3.x:
@group legacy / #[Group('legacy')]: the deprecations they cover are gone in 3.x. Also remove any test, fixture or import that references a removed symbol, otherwise it fatals on the TARGET.\PHP_VERSION_ID < ... guards, or function_exists() / class_exists() fallbacks for symbols that are always available) is dead on 3.x and can be collapsed to the modern path. The TARGET usually dropped it already, so prefer its version; clean up only where SOURCE's old-PHP code lands somewhere the TARGET had not simplified.test* methods from 2.x arrive without a return type, while 3.x declares : void on them (its php-cs-fixer config applies void_return to tests/). Run php vendor/bin/php-cs-fixer fix <file> on the merged test files.Most of these produce no conflict at all: the merge succeeds and the tests fail. They show up as a merged test that is fine on SOURCE and wrong on TARGET.
Unrecognized option "x" with the valid list attached, or a deprecation the run reports. Drop the key if it is boilerplate rather than what the test is about. Grep the whole merge diff for the key, since several merged tests usually carry it.git log <TARGET> -S'<flag> = <value>', then adapt the expectations, capturing the real output from a run rather than guessing at it.After resolving, show git diff HEAD~1 (first parent of the merge commit, i.e.
the previous TARGET state) and wait for the user to confirm the resolution looks
correct before proceeding.
Extract package and bridge names from changed files:
git diff --name-only HEAD~1..HEADPaths look like src/<NAME>/..., or src/<NAME>/src/Bridge/<BRIDGE>/... for a bridge, which has its own composer.json and test suite. Deduplicate, then run the tests from each directory. Each package has its own vendor/ and the branches pin different dependencies, so update it first:
(cd <DIR>; composer update; symfony php vendor/bin/phpunit)When src/<NAME>/assets/ changed, also run that package's JS tests: (cd src/<NAME>/assets; pnpm run test:unit).
Ignore files outside these directories (root configs, .github/, etc.): they
don't have package-level test suites.
Read the whole summary line, not just the exit status: a suite can end with Tests: N, Failures: 1 or abort on a Fatal error well before any FAILURES! banner, and ANSI colour codes sit in front of those words, so a check anchored to the start of a line reports a red run as green.
If tests fail or report PHPUnit deprecations (2.x runs phpunit-bridge, 3.x PHPUnit 11/12), first check whether the failure is pre-existing. Cheapest test first: if the merge did not touch the failing area, it did not cause the failure.
git diff --name-only HEAD~1..HEAD -- <path of the failing test or the code it covers>Only when that is inconclusive, run the test on the TARGET before the merge (git checkout HEAD~1, run, git checkout <TARGET>). Beware a CI baseline as evidence: a branch tip that has not been pushed in a while keeps an old green run, and CI installs dependencies fresh on every run, so a release made in between can turn a suite red with no commit to blame.
Only fix failures introduced by the merge:
[<ComponentName>] Fix merge conflict resolution.Report any pre-existing failures to the user without attempting to fix them.
A local composer update installs the sibling UX packages a package requires (e.g. symfony/ux-twig-component for LiveComponent) from Packagist, at their released version. CI first runs .github/build-packages.php, which rewrites every composer.json to use the sibling packages from the checkout. A merged test that relies on a sibling change from the same merge can therefore fail locally and pass in CI. To reproduce CI, run php .github/build-packages.php before composer update, and restore the rewritten composer.json files with git checkout -- '*composer.json' before committing anything.
CI also runs a lowest-dependencies job and jobs pinned to specific Symfony versions, while a local run gets the newest versions the constraints allow. An assertion pinned to a Symfony component's exception message can break when a newer release appends to it: assert the part that identifies the failure and leave the tail free (drop a trailing ., or use expectExceptionMessageMatches()), and fix it on the oldest branch that has the test so the cascade carries it up.
Before writing a CI failure off as flaky, check that the group meant to exclude it is actually excluded: the jobs pass --exclude-group skip-on-lowest and --exclude-group transient-on-windows, and on 3.x the group has to be an attribute, since PHPUnit 11 deprecates doc-comment metadata and PHPUnit 12 ignores it.
Show:
Merge: <SOURCE> -> <TARGET>
Affected: <package list>
Tests: all passing
Commits since upstream/<TARGET>:
git log --oneline upstream/<TARGET>..<TARGET>
Ready to push? (yes / no)Wait for confirmation. The user may make changes themselves before confirming.
The user pushes. Print the command for them to run:
git push upstream <TARGET>Wait until they report it done. If the push fails, stop and let them handle it.
Print "✓ <SOURCE> -> <TARGET> done." and continue to the next pair.
All merges complete:
2.x -> 3.x ✓CHANGELOG.md conflicts are the most common; entries must be kept from both sides, never dropped.dist/, and CI version pins can each be wrong even when git reports no conflict.return.--no-verify on commits.git add -A (or git add .) while resolving: it sweeps the user's untracked working files into the merge commit. Stage the files you resolved, by name.git reset in the middle of a merge: it deletes .git/MERGE_HEAD, and the commit that follows records a single parent, silently turning the merge into a squash.git pull. Stop and hand control back to the user.© symfony, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/merge-up of symfony/ux.
Open the folder on GitHubat commit 93cda70
Merge Up next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Merge Up this skillsymfony/ux | 1.1k | — | ~3.4k | Automated safety check: Pass | MIT | |
| Merge Upsymfony/symfony | 31k | — | ~4k | Automated safety check: Pass | MIT | |
| Finishing a Development Branchobra/superpowers | 297k | 5 repos | ~1.9k | Automated safety check: Pass | MIT | |
| Code Review ChecklistshareAI-lab/learn-claude-code | 78k | 4 repos | ~1.1k | Automated safety check: Pass | MIT | |
| Contributor-First PR MergeHKUDS/OpenHarness | 16k | 1 repos | ~847 | Automated safety check: Pass | MIT | |
| Finishing A Development Branchfarm-fe/farm | 5.6k | 35 repos | ~1.8k | Automated safety check: Pass | MIT |
symfony/symfony
Cascade-merge maintained Symfony branches from oldest to newest (e.g.
obra/superpowers
Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.
shareAI-lab/learn-claude-code
Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.
HKUDS/OpenHarness
Merges external GitHub pull requests while keeping the original author credited, and fixes conflicts after the merge instead of rewriting the contribution.
farm-fe/farm
A skill your agent uses when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for…
TryGhost/Ghost
Moves a package from another TryGhost repository into Ghost as an internal workspace package while keeping its Git history, with checkpoints for the steps that need an administrator.
symfony/ux
Principles for rigorously reviewing a Symfony UX pull request and making it merge-ready.
symfony/ux
Triage a security finding in a Symfony UX package into a disposition: a private CVE (coordinated disclosure through the Symfony security process), a public hardening PR (fix in the open, no CVE), or…
symfony/ux
Review a change (a PR, the current branch diff, or a set of files) or audit a Symfony UX package or the whole src/ tree for missing or incorrect security hardening.
symfony/ux
Generate, modify, or review Symfony UX Toolkit kit recipes (shadcn, flowbite-4, bootstrap, common).
Categories
Cascade-merge the maintained Symfony UX branches from oldest to newest (2.x - 3.x), resolve conflicts, run the affected packages' tests and prepare the push. Merge Up is an agent skill from symfony/ux.x), resolve conflicts, run the affected packages' tests and prepare the push.
Merge Up fits situations like: the user wants the maintained branches merged up.
Run `npx skills add symfony/ux --skill merge-up -a claude-code`. Or copy the skill folder (.agents/skills/merge-up in symfony/ux) into .claude/skills/merge-up in your project. Claude Code loads it when a task matches its description.
Run `npx skills add symfony/ux --skill merge-up -a codex`. Or copy the skill folder (.agents/skills/merge-up in symfony/ux) into .agents/skills/merge-up in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add symfony/ux --skill merge-up -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/merge-up, .gemini/skills/merge-up, .github/skills/merge-up and .opencode/skills/merge-up in your project.
Going by SKILL.md and its folder, Merge Up needs the command-line tools its instructions call (git, composer, pnpm and php).
SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Merge Up is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.4k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Merge Up: Merge Up (symfony/symfony, 31k stars), Finishing a Development Branch (obra/superpowers, 297k stars), Code Review Checklist (shareAI-lab/learn-claude-code, 78k stars) and Contributor-First PR Merge (HKUDS/OpenHarness, 16k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
symfony (a GitHub organization) maintains it in symfony/ux, which has 1,080 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on October 11, 2026.
Source: symfony/ux on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.