bowline
Guides

Resolve a sync conflict

Detect, inspect, and repair a Sync Conflict from the CLI or TUI while Bowline keeps both sides' work safe.

When two machines or agents change the same work in incompatible ways, Bowline records a Sync Conflict instead of guessing. Your real project directory stays usable, both sides are preserved, and nothing interrupts you. This guide walks through the conflict model and the exact steps to repair one: detect it with bowline status, inspect it with bowline resolve --diff, repair it in the TUI or with a copy-prompt, then accept or reject the result.

What a sync conflict is

A Sync Conflict is a divergence that Bowline can't merge while preserving both sides' intent. Bowline merges aggressively and safely on its own. Different files, non-overlapping text hunks, and changes that still parse advance the Workspace Head through an Automatic Merge with no action from you. A conflict is what's left when a safe merge is impossible, such as the same line changed differently on two machines, or a structured config whose merged output would no longer parse.

When that happens, Bowline protects your work in three ways:

  • Each affected machine keeps a stable Local Active View at the real project path. The file you see and edit at ~/Code/<project>/... is a coherent version, never a file with conflict markers spliced into it.
  • A Conflict Bundle preserves the base, local, remote, and resolution material outside the live project path. Nothing is overwritten; every side is recoverable until you resolve the conflict.
  • Text conflicts are tracked as Conflict Spans, the smallest unresolved regions inside a file. Safe edits elsewhere in the same file keep syncing through Automatic Merge while only the conflicting span waits for repair.

Not every conflict is text. Binary files, structured config that fails validation, same-key .env changes, and divergent opaque Git state become their own conflict kinds, but they follow the same rule: preserve both sides, keep the Local Active View stable, and wait for you.

How conflicts surface

Sync Conflicts stay passive but visible. Bowline never steals focus, never writes conflict markers into your source, and never auto-launches an agent to repair them. A conflict shows up in the macOS status icon and its dropdown, in bowline status, and in the TUI, and it stays there until you act.

Because conflicts are passive, you resolve them on your schedule. Bowline holds the Conflict Bundle indefinitely, and safe non-overlapping edits keep syncing in the meantime.

Resolve a conflict

Repair moves from detection to inspection to repair to acceptance. Every step works from the CLI on any platform, including headless hosts, and every command accepts --json for scripts and agents.

  1. Detect the conflict. Run bowline status in the project. A conflict shows as an attention Status Level with the affected paths and the conflict ID you'll pass to later commands. Run bowline actions to see the safe next steps for the current state.
  2. Inspect what diverged. Run bowline resolve --diff <conflict> to see the conflict kind and the Conflict Spans (the base, local, and remote line ranges of each unsafe overlap) without printing secret values or full file contents. This tells you what needs a decision before you open a repair surface.
  3. Repair in the TUI. Run bowline resolve --tui for the keyboard-first repair flow. The TUI detects installed agent CLIs (codex, claude, and cursor) and offers to hand the conflict context to one with bowline resolve --agent <codex|claude|cursor>. It always offers a copy-prompt fallback, bowline resolve --copy-prompt, which gives you a redacted, agent-ready prompt to paste into any tool when no agent CLI is installed or you'd rather drive it yourself.
  4. Accept or reject the result. When you have a repaired version you trust, run bowline resolve --accept <conflict>. To discard the proposed repair and leave your Local Active View (your machine's current version) untouched, run bowline resolve --reject <conflict>. Both decisions close the Conflict Bundle and clear the conflict from status.

Any agent that repairs a conflict writes only under the bundle's resolution/ area and never touches Git, never stages, commits, pushes, or branches, and never prints secret values. Bowline keeps source control as your tool; resolving a conflict syncs files, it does not publish anything.

Secret-bearing conflicts

Secret values never enter prompt text. For a conflict that touches secrets, for example a same-key .env change, the repair prompt carries redacted, per-key metadata, and the secret bytes stay in the local Conflict Bundle. The repair runs against those local files, not against secrets pasted into a prompt.

What acceptance does

A repaired version is a Resolution Overlay: a proposed conflict repair output that exists only as a proposal until you accept it. This is the one place in Bowline where a snapshot waits on an explicit decision. Ordinary machine and agent work advances the Workspace Head automatically, but a Resolution Overlay does not.

  • Accepting a Resolution Overlay creates a new Workspace Snapshot and advances the Workspace Head through the normal sync path. Your other Authorized Devices import the resolved bytes like any other update.
  • Rejecting a resolution discards the proposed repair and leaves your Local Active View untouched. Nothing you preserved is lost from the bundle until the conflict is closed.

Both outcomes emit redacted resolution events (accepted or rejected, with the conflict ID and affected paths but never file contents or secret values) so the decision is auditable across your devices.

Next steps

On this page