# Project Merge

> Merge two divergent codebases that share a common baseline but implemented different features, producing a single project that has the union of both projects' features. Use whenever a user has two sibling/forked projects (project A and project B, or "两个项目"、"两份代码"、"两个分支") built on a similar starting point and wants to combine, consolidate, or "缝合/合并" them into one — especially when one variant is said to work better than the other and the user wants to keep the better base while pulling in the other's features. Trigger on phrases like "合并这两个项目", "把这两份代码合到一起", "merge project A and B", "consolidate these two forks", "把 b 缝进 a", "combine the features of both", even when the user only describes two folders and says one is better without saying the word "merge".

- Skill: `wakeeys/project-merge` (Agent Skill)
- Install (CLI): `npx skillmds@latest add wakeeys/project-merge`
- Raw SKILL.md: https://api.skillmd.com/api/skills/wakeeys/project-merge/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: wakeeys (https://skillmd.com/u/wakeeys)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/wakeeys/project-merge

---


# Project Merge

Two projects, A and B, grew from a similar baseline but diverged — each added different features, and one is generally better than the other. The goal is **one project that contains the union of both projects' working features**, built on the better base, with nothing from either side lost.

This is delicate work: a naive merge silently drops features or breaks the base. The whole point of this skill is to be deliberate — understand both sides first, pick the easier merge direction, integrate carefully, then *prove* nothing was lost.

## The mental model

Think of it as a directed graph: you pick a **base** (the project you keep and build on) and a **source** (the project you pull features *from*). You're transplanting the source's unique features onto the base. "把 b 缝进 a" means base=A, source=B.

The base should almost always be the project that works better and/or has the cleaner architecture, because you keep its code largely intact and only graft additions onto it. Grafting onto a solid base is far easier than rebuilding a weak base's missing pieces.

## Workflow

Work through these phases in order. Don't skip the understanding phases to rush into editing — a merge done without understanding both sides is the most common way features get silently lost.

### Phase 1 — Locate both projects and ask the key questions

First find the two project roots (ask the user for the two paths if not obvious). Then ask the user up front — these answers shape everything:

1. **Which project works better in practice, and why?** The "why" matters enormously — it tells you what to protect. ("B's output is more accurate", "A keeps crashing on large inputs", "B's UX is smoother".) If the user can be specific about *what* is better, capture it.
2. **Which project should be the merge base?** If the user has a preference, honor it. If they don't, tell them you'll decide after analysis (Phase 4) and explain your choice.
3. **Any features from the worse project that must NOT be carried over?** Sometimes the worse project has experiments the user wants dropped. Knowing this prevents wasted work.
4. **Where should the merge happen — on a safe working copy, or in place on the base project?** Recommend the working copy (it keeps a pristine original for verification and rollback in Phase 7), but honor an in-place preference. Note that if the base is a git repo, a branch gives in-place editing *with* a recoverable original — the best of both. Details and setup are in Phase 5.

Ask these together (one round of questions), then proceed. Don't interrogate the user phase by phase.

### Phase 2 — Understand both projects independently

Read enough of each project to genuinely understand it. For each project, build a picture of:

- **Entry points & structure**: how it's organized, where execution starts, the main modules.
- **Dependencies & build/run setup**: package manifests, build scripts, how tests run.
- **Feature inventory**: a concrete list of what this project *does* — user-facing capabilities and notable internal mechanisms.

For large projects, this is a good place to fan out: spawn one Explore/general-purpose subagent per project (or per major subsystem) so you can read breadth in parallel and get back structured inventories rather than reading everything yourself. Have each subagent return a feature list + file map.

### Phase 3 — Diff the two: shared baseline vs. unique features

This is the heart of the analysis. Produce three explicit lists:

1. **Shared baseline** — code/structure common to both (the original starting point, possibly drifted on each side). This is what you *don't* need to merge; it's the common ground. Note where the two sides have *diverged* on shared files — those are your real conflict zones.
2. **A-only features** — capabilities present in A but not B.
3. **B-only features** — capabilities present in B but not A.

For each unique feature, note which files implement it and what it touches (so you know its blast radius when transplanting). Where both sides modified the *same* baseline file differently, flag it explicitly — these are the spots that need careful manual merging rather than copy-paste.

Then answer the user's "why is X better" with evidence from the code: is it a better algorithm? more robust error handling? a fix the other side never made? This analysis directly informs what to protect during the merge.

Present this analysis to the user before moving on — a short, readable summary (shared baseline, A-only, B-only, why-better). This is cheap insurance: the user can correct a misunderstanding before you write a line of code.

### Phase 4 — Decide the merge direction (if the user didn't)

If the user already chose the base, use it. Otherwise decide, and explain your reasoning. Pick the base by asking: **which direction transplants fewer / less-entangled features?**

Strong signals for choosing a base:
- **It works better / is more correct.** Keep the code that already behaves well; don't risk regressing it.
- **It has the cleaner or more modular architecture.** Easier to graft onto.
- **It would receive fewer or more self-contained features.** If A's unique features are 3 tidy modules and B's are scattered across the whole codebase, make B the base and graft A's 3 modules in — less surface area to disturb.

These can conflict (the better-working project might have the messier code). When they do, prefer the better-working project as base — correctness is harder to recover than cleanliness. State the tradeoff to the user.

### Phase 5 — Set up a safe working copy

Act on the user's Phase 1 answer about where the merge should happen. If for some reason it wasn't settled there, ask now before editing — but normally you already have the answer and just execute it.

- **On a working copy (recommended).** Make a copy of the base project to merge into, so both originals stay pristine. This is what Phase 7 relies on: it lets you diff the merged result against the untouched originals to prove nothing was lost.
- **In place, on the original base.** Faster and avoids a duplicate directory, but it sacrifices the pristine base as a verification/rollback reference. Only safe when there's another safety net — see the git note below.

How to set it up depending on the choice and the VCS situation:

- **Base is a git repo:** create a new branch (e.g. `git switch -c merge/from-<source>`). This is the best of both worlds — edits are "in place" in the same directory, but the original base stays recoverable on its branch and `git diff` gives you the comparison Phase 7 needs. Prefer this when git is available, whichever option the user picked. (Commit or stash any pending changes first so the pre-merge state is captured.)
- **Working copy, no git:** copy the base project directory to a new location (e.g. `<base>-merged/`) and edit there.
- **In place, no git:** discouraged. If the user insists, at minimum take a one-time backup copy of the base first so rollback and the Phase 7 diff are still possible, and tell the user that's what you're doing.

Tell the user the exact path/branch where edits will happen. Keep the source project untouched regardless, so the verification phase can diff against it.

### Phase 6 — Transplant the source's unique features

Now graft each source-only feature onto the base, one feature at a time (smallest/most-isolated first builds confidence and reduces churn). For each feature:

- Bring over its implementation files; wire them into the base's entry points, routing, config, and dependency manifests.
- Reconcile shared-but-diverged files by hand — merge the two versions so both the base's behavior and the source's feature survive. Don't blindly overwrite; that's how base features get clobbered.
- Add any new dependencies the feature needs to the base's manifest.
- Resolve naming/namespace collisions between the two projects.

Work in small, verifiable increments. After each feature (or small group), do a quick build/sanity check rather than transplanting everything and debugging a giant pile at the end.

### Phase 7 — Verify: both feature sets present, nothing lost

This is non-negotiable — the merge isn't done until verified. Verify in three complementary ways:

1. **Run the tests.** Run the base's test suite *and* port over the source project's tests for the features you transplanted, then run those too. A transplanted feature with its original tests passing is strong evidence it survived the move. Report actual results — if tests fail, say so with the output.
2. **Build it.** Run the build/compile/lint step for the merged project. It must build cleanly. Fix what the build surfaces.
3. **Code-level feature audit.** Go back to the Phase 3 lists (A-only + B-only) and check each feature off against the merged codebase: is its implementation present and wired in? This catches features that "merged" as dead code — copied in but never actually reachable. For anything you can't confirm by reading, note it explicitly rather than claiming success.

Produce a **completion checklist** mapping every unique feature from both projects to its status in the merged project (present & tested / present but untested / not yet merged / intentionally dropped). Plus the test and build results. Be honest about gaps — a checklist that hides a missing feature is worse than no checklist.

If anything is missing or broken, loop back to Phase 6 for that feature.

## Output

At the end, give the user:
- The location of the merged working copy (path/branch).
- The completion checklist (every feature from A and B → status in the merged project).
- Test results and build status, stated plainly.
- Any features intentionally dropped (per the Phase 1 answer) or any gaps you couldn't resolve, called out explicitly.

## Principles

- **Understand before editing.** Phases 2–4 exist so the merge is deliberate, not a hopeful copy-paste.
- **Protect the base.** You chose the base because it works; don't regress it while grafting features on.
- **Preserve a ground truth.** A pristine reference (working copy, git branch, or backup) is what verification and rollback depend on. The source project always stays untouched; let the user decide how to protect the base, but never edit it with no safety net.
- **Prove it, don't claim it.** "Merged" means tests pass, it builds, and every feature is accounted for on the checklist — not "I copied the files over."

