# `MingaEditor.Agent.ProvenanceJump`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/agent/provenance_jump.ex#L1)

A pending "jump to the turn that wrote this line" navigation.

Created when the user presses Enter on a code-provenance popup
(`MingaAgent.Autobiography`). It holds everything the async session-load and
the subsequent buffer re-syncs need to land the chat cursor on the right turn
and to get the reader back to where they started:

* `target_message_id` — the stable chat message id to land on (the turn's
  opening user message, resolved once at request time so layout shifts during
  the multi-sync load can't move it; see `Transcript.turn_anchor_id/2`).
* `landed?` — false until the first sync after load performs the jump. While
  false, syncs land on the target; once true, syncs leave the cursor where it
  is so re-syncs don't yank the reader back to the bottom.
* `origin` — `{path, line}` of the source file the user jumped from, for the
  return trip. Stored as a path (not a buffer pid) so it survives the source
  buffer being closed.

The whole struct is cleared when the user sends a new prompt (live streaming
should resume its bottom-pinned auto-scroll).

# `origin`

```elixir
@type origin() :: {path :: String.t(), line :: non_neg_integer()}
```

# `t`

```elixir
@type t() :: %MingaEditor.Agent.ProvenanceJump{
  landed?: boolean(),
  origin: origin() | nil,
  target_message_id: pos_integer()
}
```

# `cursor_target`

```elixir
@spec cursor_target(t()) :: {:message_id, pos_integer()} | :keep
```

Returns the cursor target a sync should use for this jump's current phase.

# `mark_landed`

```elixir
@spec mark_landed(t()) :: t()
```

Marks the jump as landed (the cursor has been placed on the target turn).

# `request`

```elixir
@spec request(pos_integer(), origin() | nil) :: t()
```

Creates a pending jump to `target_message_id`, remembering the origin for the return trip.

---

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