Two agents. Same repo.
Clean merge. Broken code.
conflict-check catches semantic conflicts between parallel AI coding
agents — the ones git merge never sees, because the changes never
touch the same line, or even the same file.
npm run demo, nothing edited
$ git checkout agent-a-rename && git merge agent-b-add-helper Auto-merging math.js # clean merge. no conflict markers. exit code 0. $ conflict-check check --branch-a agent-a-rename --branch-b agent-b-add-helper Checking "agent-a-rename" (1 file) against "agent-b-add-helper" (1 file)... Using gemini (gemini-3.6-flash) Overlapping files: math.js Checking math.js... CONFLICT ✗ math.js Agent A renames the `add()` function to `sum()`, while Agent B adds a new `sumAll()` function that explicitly calls `add()`. If both changes are merged, `sumAll()` will attempt to call `add()`, which no longer exists, resulting in a runtime ReferenceError. Summary: ✗ 1 of 1 overlapping file(s) have a likely semantic conflict.
Why this exists
Run multiple AI coding agents — Claude Code, Codex, Cursor, whatever — in parallel
git worktrees on the same repo, and eventually they collide in a way
git merge can't see. Agent A renames a function, changes what it
returns, or changes some assumption about shared state. Agent B, working in a
different worktree with zero visibility into what A is doing, writes new code
that depends on the old behavior.
“No markers, no warning, exit code 0. The build's green. It just doesn't work anymore.”
conflict-check tries to catch that before you merge. You tell it what
each agent was supposed to be doing, it grabs the diff each agent actually
produced, and it asks an LLM whether the two look like they're making conflicting
assumptions about the same code.
It catches cross-file conflicts too
The same-file example above is the easy case — both agents touched
math.js, so there was an overlapping file to even look at. The harder,
more common case is when they don't share a file: one agent renames a
function, and the other calls the old name from a completely different file it
added or already had. No overlapping filename, no diff collision —
git merge sees nothing.
conflict-check parses each branch's diff with a real AST (via
ts-morph) to find functions and
methods that were added, removed, or renamed, then searches the whole
repo — not just the diff — for anything that still calls the old name.
$ conflict-check check --branch-a agent-a-rename --branch-b agent-b-add-helper Checking 2 branches (1 pair): agent-a-rename, agent-b-add-helper Using gemini (gemini-3.6-flash) === "agent-a-rename" ⇄ "agent-b-add-helper" === [same-file] 0 file(s) touched by both branches ✓ No files touched by both branches. [cross-file] renamed/removed symbols still referenced elsewhere Checking math.js: `add` renamed to `sum`... CONFLICT CROSS-FILE math.js — `add` renamed to `sum` — from branch "agent-a-rename" CONFIRMED REFERENCE [confirmed] batch.js:1 (branch "agent-b-add-helper") — import { add } from "./math.js"; [confirmed] batch.js:4 (branch "agent-b-add-helper") — return numbers.reduce((total, n) => add(total, n), 0); Branch agent-a-rename renamed `add` to `sum` in math.js, but branch agent-b-add-helper's new batch.js still imports and calls `add`, which no longer exists after the rename. Merging both branches will throw at import/call time. === Summary === ✓ No same-file conflicts across 0 checked file(s). ✗ 1 cross-file conflict(s) with a CONFIRMED reference (real import/scope resolution).
Resolved through real import/scope binding — ts-morph's language service, not a name that just happens to match.
The old declaration couldn't be resolved semantically (say, both branches touched the same symbol), so this is a plain AST name match instead. Still worth a look — but a coincidentally reused name could slip through here. Treat it as a lead to verify, not a confirmed diagnosis.
Installing it
Not on npm yet, so you'll have to build it yourself.
# clone, install, build, link
git clone https://github.com/Cipher-08/conflict-check.git
cd conflict-check
npm install
npm run build
npm link
npm link symlinks the built output globally, so after pulling changes
you just need npm run build again — no re-linking. If it blows up with
EACCES, that's your global npm prefix not being writable, not this tool
— fix the prefix permissions, or switch to nvm, which sidesteps the
whole problem.
then, inside whatever repo you actually want to check:
conflict-check init
What it doesn't do
Being upfront about this, most important first.
- Cross-file detection currently understands JS/TS/JSX/TSX only — functions, arrow/function-expression consts, and class methods. Other languages or symbol kinds aren't tracked yet.
- The
POSSIBLE — NAME MATCH ONLYtag means exactly that: worth checking, not a verdict. A coincidentally reused name can still slip through it. - It only warns — it never touches your code or does the merge for you.
- No dashboard, no accounts, nothing hosted. Just your terminal, one repo at a time.
See the full list in the README for the rest, including exactly how cross-file checking depends on snapshot metadata and git history.