drift#

Per-app comparison of versions reported by participating sources (currently Installomator and Homebrew Cask). Surfaces apps where sources disagree on what β€œlatest” means, the case where one source has silently fallen behind. Powers the /apps/drift endpoint and the list_drift MCP tool.

extract_versions(detail: AppSourceDetail | None) dict[str, str][source]#

Pull the per-source version string out of an app’s source detail.

Returns a dict keyed by source name (installomator, homebrew_cask). Sources with no extractable version (missing payload, missing version field, shell-expression value) are omitted so callers can rely on len(...) for β€œhow many versioned sources does this app have.”

Parameters:

detail (AppSourceDetail | None) – The app_source_details row, or None.

Returns:

Mapping of source name to version string.

Return type:

dict[str, str]

detect_drift(app_row: App, detail: AppSourceDetail | None) DriftEntry | None[source]#

Compute drift for a single app.

Returns None when fewer than two sources expose a version or when all versions are equivalent (PEP-440 equal for parseable values, case-insensitive string equality otherwise). Returns a DriftEntry when sources disagree.

Parameters:
  • app_row (App) – The apps table row.

  • detail (AppSourceDetail | None) – The matching app_source_details row, or None.

Returns:

A drift entry, or None if no drift.

Return type:

DriftEntry | None