Avoids the ls-remote + merge-base --is-ancestor walk in last() for the
common case by reading the recorded tag from .opencode-version. merge.ts
writes the file as part of the pre-merge compat commit so future runs of
fix-kilocode-markers, reset-to-upstream, and find-reset-candidates can
resolve the base tag instantly. Seeded with v1.14.33 (PR #9978).
git rerere learns conflict resolutions from past upstream merges and
replays them on the next merge. When past resolutions used the buggy
mergeWithNewestVersions ordering, rerere auto-resolves package.json
files with stale content before transformConflictedPackageJson ever
gets a chance to run — so the fixed merge logic never reaches the
file.
Add reconcileAllPackageJson, which runs after every merge (clean,
auto-resolved, or partially conflicted) and rewrites every package.json
that the merge touched from the kilo branch's pre-merge HEAD and the
opencode compat branch using the same merge logic. Files that are
still conflicted are skipped so manual resolution isn't silently
overwritten.
This makes our merge logic the source of truth for package.json
content, regardless of what rerere or git's textual merge produced.
Update the upstream merge script to identify and link to the previous compatibility commit. This ensures that pre-merge transformations maintain a proper commit history by using multiple parents when a prior compatibility base is found, rather than creating disconnected commits.
- Add `findLatestCompatCommit` to locate previous compatibility commits
- Implement `commitTree` and `updateBranch` for low-level git manipulation
- Update `merge.ts` to integrate compatibility base detection and multi-parent commits
Files in UD/DU/binary/etc. conflict states have no <<<<<<< markers in
the working tree. My earlier simplification that removed the
`git checkout --conflict=diff3` pre-check caused mergiraf to run on
them: it would exit 0 (nothing to solve), after which the unconditional
`git add` silently staged our side as resolved, losing the signal that
upstream deleted the file (or that we deleted what upstream modified).
Guard runMergiraf by inspecting the file before calling mergiraf: if
there are no conflict markers, skip the file entirely so it falls
through to manual review. Surface a skipped-count line in the normal
log output so the operator can see how many non-textual conflicts were
left alone.
Pass merge.conflictStyle=zdiff3 on the git merge invocation so every
conflicted file gets base-aware (|||||||) markers from the start, not
just the ones runMergiraf happens to touch. Benefits:
- Mergiraf always has a base section to work from, so its structural
heuristics apply uniformly.
- Remaining manual conflicts show both sides relative to the common
ancestor, which is dramatically easier to resolve than a 2-way marker.
Since the working tree already carries diff3 markers after the merge,
drop the per-file `git checkout --conflict=diff3` in runMergiraf.
mergiraf defaults to writing a .orig sibling file for every file it
touches. Pass --keep-backup=false so the merge script doesn't leave a
pile of .orig files across the working tree after running.
mergiraf exit 2 means it reduced conflicts but didn't fully close them.
Previously we bailed on any non-zero exit, throwing away the useful
partial reduction in the working tree. Now we always read the file after
mergiraf runs: if no conflict markers remain we stage, if markers remain
we keep the reduced content in the working tree for manual review but
leave the file unstaged so nothing half-resolved is auto-committed. Also
clean up the debug wording and surface a partial-resolution count in the
normal log output.
Previously git add and mergiraf solve could bubble up exit 128 (e.g. on
files missing the base version) and abort the entire merge. Wrap every
shell call in .nothrow() and skip to the next transform pass on failure.
Invokes `mergiraf solve` (syntax-aware git merge tool) on each conflicted
file before the kilocode-specific transform cascade, re-materializing the
file with diff3 markers first so mergiraf can reconstruct the base
revision. This auto-resolves the common pattern of neighbouring import
additions around kilocode_change markers plus most JSON/YAML/TOML and
other structural conflicts, leaving the existing transforms to handle
only what's genuinely ambiguous.
mergiraf is required at startup; if missing the script aborts early with
install instructions (brew / cargo / nix) rather than failing mid-merge.
Transforms feed git-reported repo-relative paths into Bun.file() and
Glob.scan(), both of which resolve against cwd. Running the script from
script/upstream/ (as the README suggests) silently broke every file
lookup, causing pre-merge transforms to return zero results and i18n
auto-resolve to crash with ENOENT.
The training grep only matched uppercase 'Resolve merge conflict', missing the
lowercase convention used by most historical upstream merges. This dropped ~70
past merges from the rerere training set on kilocode, leaving the cache mostly
empty and causing rerere to miss resolutions that involve the opencode -> kilo
rename.
- Update AGENTS.md to reflect main as default branch
- Update GitHub Actions workflows to trigger on main branch
- Update publish scripts to cherry-pick from origin/main
- Update upstream merge scripts and documentation
- Update CONTRIBUTING.md links in PR standards workflow
- Fix disabled workflow and documentation links
All development commands (bun dev, npm run dev) and external services
(models.dev, ai-sdk.dev) remain unchanged as they are unrelated to branch names.