# `Minga.Buffer.Fork`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga/buffer/fork.ex#L1)

A forked copy of a buffer for concurrent agent editing.

When an agent session starts editing a file, a fork is created from the
parent `Buffer.Server`. The fork holds a snapshot of the parent's Document
at fork time (the common ancestor) and its own Document that the agent edits.
The user continues editing the parent buffer independently.

When the agent finishes, `merge/1` computes a three-way merge: common ancestor,
fork changes, and current parent changes. Non-overlapping changes merge
automatically. Overlapping changes are returned as conflicts for resolution.

The fork exposes the same GenServer call messages as Buffer.Server for the
editing subset (content, find_and_replace, replace_content, etc.), so agent
tools can call it without knowing whether they're talking to a fork or a
real buffer.

## Lifecycle

    parent_pid ──→ Fork.create(parent_pid) ──→ fork_pid
                                                  │
                                agent edits ◀─────┘
                                                  │
                              Fork.merge(fork_pid) ──→ {:ok, merged} | {:conflict, hunks}

# `create_opt`

```elixir
@type create_opt() :: {:parent, pid()} | {:content, String.t()}
```

Fork creation options.

# `state`

```elixir
@type state() :: %{
  ancestor: Minga.Buffer.Document.t(),
  document: Minga.Buffer.Document.t(),
  parent: pid(),
  parent_monitor: reference(),
  parent_alive: boolean(),
  version: non_neg_integer(),
  dirty: boolean()
}
```

Internal fork state.

# `ancestor_content`

```elixir
@spec ancestor_content(GenServer.server()) :: String.t()
```

Returns the ancestor (snapshot at fork time) content.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `content`

```elixir
@spec content(GenServer.server()) :: String.t()
```

Returns the full text content of the fork.

# `create`

```elixir
@spec create(pid()) :: {:ok, pid()} | {:error, term()}
```

Creates a fork from an existing buffer.

Snapshots the parent's current Document as the common ancestor and creates
an independent copy for editing. The fork monitors the parent buffer.

# `dirty?`

```elixir
@spec dirty?(GenServer.server()) :: boolean()
```

Whether the fork has been edited since creation.

# `find_and_replace`

```elixir
@spec find_and_replace(GenServer.server(), String.t(), String.t()) ::
  {:ok, String.t()} | {:error, String.t()}
```

Finds and replaces text in the fork. Returns `{:ok, msg}` or `{:error, reason}`.

# `merge`

```elixir
@spec merge(GenServer.server()) ::
  {:ok, String.t()}
  | {:conflict, [Minga.Core.Diff.merge_hunk()]}
  | {:error, term()}
```

Computes a three-way merge between the ancestor, fork, and current parent.

Returns `{:ok, merged_text}` when all changes merge cleanly, or
`{:conflict, merge_hunks}` when overlapping changes exist.
Returns `{:error, reason}` if the parent buffer is dead.

# `replace_content`

```elixir
@spec replace_content(GenServer.server(), String.t()) :: :ok
```

Replaces the entire content of the fork.

# `start_link`

```elixir
@spec start_link([create_opt()]) :: GenServer.on_start()
```

# `version`

```elixir
@spec version(GenServer.server()) :: non_neg_integer()
```

Monotonic version counter.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
