Headers, URL parameters, and environment variables each carry an `id`
that identifies the row to the pair editor. Importers leave it empty and
the editor stamps one in the first time it touches a resource, so merely
opening an imported request made the next import report it as locally
edited. `comparable` now drops `id` at every level rather than only the
top, since a row ID says no more about content than the model's own ID.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A row marked "edited" or "conflict" gave no way to tell what actually
differs, so a resource that drifted from the file — however it drifted —
reads as an unexplained accusation. The plan now carries the field names
the source and the local copy disagree on, and the row's tooltip lists
them.
The preview's primary button also read "Apply" when the current selection
would change nothing. It now reads "Done", since committing an empty
selection only records the decisions made in the preview.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Yaak now remembers, per item of a linked import source, whether the user
wants it. A mapping row that still points at a model means wanted, so
re-imports merge into it; a row with no model behind it means not wanted,
so re-imports leave it alone. Wanted-ness is structural rather than a flag:
deleting the model locally, or turning the item down in the preview, is
what makes it not wanted.
- import_source_resources drops `snapshot` for a nullable `content_hash`
and lets `model_id` be NULL. The migration keeps every beta row's
key to model mapping and starts hashes empty; until a hash is recorded,
a difference can't be attributed to either side, so the item is offered
once as a conflict that keeps local changes.
- comparable() ignores sortPriority. Importers number it from source
order, so inserting one operation used to plan a fake update for
everything after it. The trade is that pure reorders don't propagate.
- Keys the user turned down come back as unchecked "not imported" rows
instead of being re-offered as new resources or resurrected. Checking
one imports it under the same source key and pulls in the folders it
needs.
- An imported resource the source moves into a folder that isn't imported
is offered as a deletion, with a tooltip pointing at the folder.
- Plan-time source resolution binds by source-key overlap instead of by
path, so a renamed or moved file merges into what it created and heals
the stored origin. Several sources sharing keys never guess-merge: the
plan says so and imports everything as new.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>