GitWand from v1.6.3 to v3.2.0: the merge engine gets structural, the workflow gets multi-forge

Leader 1 7
calendar_today agoschedule7 min read

Back in April I wrote about why GitWand exists: most Git clients show you a conflict and stop, and I wanted one that actually understood the structure of what it was looking at. That article left off at v1.6.3 — the pattern registry, the merge preview, the CLI and MCP server, 322 tests. Since then the project has shipped roughly two dozen releases, and rereading the changelog end to end, three things stand out: the conflict engine went from pattern-matching text to parsing actual syntax trees, the app stopped assuming GitHub is your only forge, and the whole thing got noticeably faster under the hood. Here's the detailed version.

The conflict engine: from text patterns to ASTs to a validated LLM fallback

The nine-pattern registry from April was already good at the trivial 60-80% of conflicts, but anything involving real code structure — a rename, a moved function, a reordered block — still fell through to complex. Three releases changed that.

v2.1.0 replaced the underlying diff routine with Histogram diff (rare-anchor splitting with forward/backward extension, the same approach JGit uses), which on its own lifted the success rate of the non_overlapping and insertion_at_boundary patterns on real source code. It also shipped a primitive block-move detector using Rabin-Karp rolling hashes with token-diversity filtering — no scoring impact yet, but it laid the groundwork for what came two versions later.

v2.2.0 added a format-profile registry to the JSON and YAML resolvers. Instead of treating every array as an opaque blob, JSON Pointer paths like /dependencies or /scripts get a merge strategy (set-by-identity or merge-keys), and YAML sequences in Helm values or Kubernetes manifests merge by name or port instead of bailing out on a single divergent line. Five built-in profiles ship (package.json, tsconfig.json, composer.json, helm/values.yaml, generic Kubernetes manifests), and underneath it there's a minimal in-house RFC 6902 JSON Patch implementation — diffJson, applyJsonPatch, mergeJsonPatches — with the round-trip property verified against 100 random JSON inputs.

v2.3.0 is the big one: an AST-based first pass using web-tree-sitter for TypeScript, TSX, JavaScript, JSX, Python, Go, and Rust. Base/ours/theirs get parsed, top-level entities (functions, classes, methods) are paired by canonical signature, and the merge happens entity-by-entity — the same approach Mergiraf and Weave use. When the structural pass returns null, the hunk-based engine takes over, so coverage never regresses. It stays browser-compatible by treating web-tree-sitter as an optional peer dependency and loading grammars lazily through three environment adapters (Node, browser, Tauri), so the package keeps zero static Node imports.

v2.6.0 built on the block-move detector to add refactoring-aware merging: a four-phase pipeline that tokenizes base/ours/theirs, identifies tokens that vanished from one side and appeared on the other, and confirms the mapping via a full bijective substitution check. It handles local variable/parameter renames, top-level function/class renames, and method moves between classes — inverting both branches back to the base naming, merging with the standard engine, then replaying the rename forward. It's opt-in (refactoringAware: { enabled: true }) and silent/zero-overhead when off. A neat edge case fix in the same release: when two parameters are renamed simultaneously with the same occurrence count, the original algorithm misclassified it as ambiguous — the fix uses permutation search over same-count candidate groups instead.

Finally, v2.4.1 added semantic validation across the board: every candidate resolution is fed through tree-sitter for its language, and anything that would produce a parse error is retried or surfaced as manual instead of silently shipped. A new postMergeRisk dimension (weight −0.20) demotes the confidence score retroactively. Validation now runs in three tiers — off, balanced (the new default, parse-tree check only), and strict (adds tsc --noEmit and eslint via a dedicated adapter).

On top of all that structural work, v2.5.0 introduced an opt-in LLM fallback for whatever's still classified complex. You supply any endpoint that accepts a prompt and returns a string; GitWand builds a context-aware prompt from a configurable window of surrounding lines, calls it, and only accepts the result if it clears a minPostMergeScore threshold after being run back through the parse-tree and post-merge scoring pipeline. Below threshold, it degrades cleanly to complex for manual review. Every accepted resolution is tagged llm_proposed in the decision trace, with the full audit trail — model, latency, prompt hash, truncated raw response, validation score — attached as an LlmTrace. Critically, the synchronous resolve() never touches the model; only resolveAsync() does, so nothing about the default performance profile changed. It took until v2.8.3 for this to actually be wired into the desktop app, CLI (--llm-fallback, --llm-provider, --llm-model), and MCP server (a gitwand_resolve_hunk tool that inverts the flow — the connected agent is the LLM) — validated against a 15-fixture benchmark where all fixtures resolved through llm_proposed with a validation score of 100.

Multi-forge support: GitLab, Bitbucket, Azure DevOps

v2.10.0 added native GitLab support (via the glab CLI) and Bitbucket Cloud support (via the REST v2 API directly, no CLI needed), bringing diffs, CI status, inline comments, and draft-to-ready conversion to all three forges uniformly. v2.14.0 filled in the remaining gaps: GitLab inline comments now anchor to the exact diff line through the Discussions API (passing base_sha/start_sha/head_sha from the MR's diffRefs) instead of landing as general notes, Bitbucket got CI checks via the Pipelines commit-statuses endpoint and a title-prefix convention for draft PRs, and comment editing/deletion was extended to all three forges.

v2.19.0 added Azure DevOps as a fourth forge, using the same Entra ID device flow with automatic token refresh, plus the full PR lifecycle, threaded comments, branch-policy CI checks, and reviewer votes. The same release replaced the GitHub CLI dependency for authentication with a built-in OAuth device flow — approve once in the browser, token goes straight into the OS keychain, never touching the frontend — and added cross-fork PR support (targeting upstream by default when your origin is a fork). v2.18.0 layered CI annotations directly into the diff view across all three forges (GitHub check-runs, GitLab code-quality reports, Bitbucket report annotations) — a warning icon in the gutter, no configuration needed if your pipeline already publishes them.

Workspaces, worktrees, and monorepo scoping

v2.7.0 introduced a workspace config file for grouping repos into a single multi-repo dashboard (fetch/pull/status across all of them), alongside a Hooks manager (toggle, create, delete any of the 18 standard Git hooks, using the .disabled suffix convention Husky understands) and first-class worktrees (one shortcut creates the branch, the worktree, and opens a tab). v2.8.2 parallelized the six workspace-wide aggregate commands using Rust's rayon work-stealing pool, so a ten-repo workspace scales roughly an order of magnitude better than a two-repo one.

v2.21.0 addressed a different scaling problem: monorepos where the commit graph is noisy with commits from packages you don't care about. A scope picker auto-detects sub-workspaces from six formats (pnpm, npm/yarn, Cargo, Nx, Turborepo, Go), all parsed natively in Rust, and narrows the commit graph, search, and stats to the selected sub-tree, with the choice persisted per repository.

The Launchpad becomes Today, and AI agents become something GitWand watches

The cross-repo dashboard first shipped in v2.9.0 as the Launchpad, with four tabs (WIP, PRs, Issues, Team) and pin/snooze support with localStorage persistence. v2.15.0 replaced the flat commit log with the Git Tree as the primary navigation surface — a full multi-branch DAG with trunk-pinning, a lane-cooldown algorithm to keep long-running projects from growing unboundedly wide, and an automatic WIP node showing uncommitted changes live at HEAD. v2.24.0 removed the permanent sidebar entirely in favor of a floating dock.

v3.0.0 rebuilt the dashboard again, renaming it Today and reorganizing it around three urgency tiers (needs you now, waiting on others, low priority) with a single context-aware primary action per item that routes directly to the right surface instead of linking out to the browser. The same release published the VS Code extension to the Marketplace as a self-contained VSIX (bundling the core engine via esbuild) and fixed four correctness bugs in it, including a "Resolve All" that had silently only been covering open files rather than the whole workspace.

On the AI-agent side, v2.8.0 added an Agent Sessions view that detects running Claude Code, Cursor, and Windsurf processes by their working directories and cross-references them against your worktrees, plus four opt-in scheduled tasks (auto-resolve on conflict, nightly pull --rebase, release notes on tag push, AI commit-message batching). v3.2.0 fixed the terminal panel so that launching an agent from inside GitWand actually attaches a real interactive shell instead of a dead tab, and added a "New AI task" button that spins up an isolated git worktree and opens a Claude Code session in it in one click. The MCP catalog (v2.10.0) also turned Settings → MCP into a browser for the npm MCP ecosystem — hundreds of tagged packages, one-click install into Claude Desktop/Code, Cursor, or Windsurf configs.

Performance: fixing a CSP bug that had been quietly crippling IPC for months

v2.8.2 was a dedicated performance release: git status, the hottest IPC call in the app, moved from forking a git subprocess to running in-process via libgit2 (measurably faster, especially once fork-exec overhead disappears in the running app); twenty rarely-used panels and seventeen syntax-highlighter languages became lazy-loaded instead of parsed at launch; three independent polling timers were consolidated into one that pauses when the window loses focus; and every IPC call gained a default timeout, with longer presets for network operations and AI prompts.

v2.8.5 turned out to explain a lot of the sluggishness that preceded it: the Content Security Policy had never whitelisted Tauri 2's ipc://localhost protocol scheme, so every single IPC call was being silently rejected and falling back to Tauri's slow legacy postMessage path — the source of months of mysterious callback-id warnings in the console. The same CSP gap had also been blocking the Ollama detection probe and the Claude API endpoint. Fixing it, alongside a macOS launchd environment fix (GUI apps launched from Finder inherit essentially no shell environment) and a keychain ACL workaround for the GitHub CLI, resolved a cluster of "it works from the terminal but not from the app" bugs at once.

Where things stand

GitWand is at v3.2.0. Since the April article, the conflict engine gained tree-sitter structural merging, refactoring-aware resolution, and a validated LLM fallback; the forge support expanded from GitHub-only to GitHub, GitLab, Bitbucket, and Azure DevOps; the navigation model was rebuilt twice (Git Tree as primary view, then the floating dock); and a dedicated performance pass fixed both algorithmic hot paths and a CSP misconfiguration that had been quietly throttling every IPC call since Tauri 2 was adopted. If the April version didn't fit your workflow, most of what shipped since is aimed at exactly the gaps that would have caused that.

Part 1 of 1 in Gitwand

1 Comment

0 votes
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

I spent years trying to get AI agents to collaborate. Then Opus 4.6 and Codex 5.3 wrote the rules

snapsynapseverified - Apr 20

The Sovereign Vault — A Comprehensive Guide to Protocol-Driven AI

Ken W. Algerverified - Jun 4

Helping Clients Move from Pilot to Production: The Agentic AI Governance Playbook

Tom Smithverified - Jun 8

From Prompts to Goals: The Rise of Outcome-Driven Development

Tom Smithverified - Apr 11

From Subjective Narratives to Objective Data: Re-engineering the Elderly Care Communication Loop

Huifer - Jan 28
chevron_left
794 Points8 Badges
Lyoncv.devlint.fr
3Posts
1Comments
5Connections
Front-end dev

Related Jobs

View all jobs →

Commenters (This Week)

2 comments
2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!