BackgroundTasks: dismiss no longer calls clearTaggingJobs; dismissal only
updates local dismissed state
DuplicateFinder: entering the view clears stale groups when the stored scan
scope differs from selectedFolderId; duplicateScanFolderId is recorded on
each scan and cache load so scope is always tracked
Tagger threshold: set_tagger_threshold now sets TAGGER_SESSION_DIRTY so the
worker rebuilds its WdTagger instance and applies the new threshold on the
next batch
Region search global scope: fetch offset+limit+2 candidates before removing
the source image so has_more is accurate across pages
Region search pagination: loadMoreImages now sets loadingImages and checks
galleryRequestToken before appending results, preventing duplicate pages and
stale responses corrupting a new collection
Folder recovery: when index_folder detects a missing path it records the
error in a new folders.scan_error column (ensure_column migration) and emits
done without deleting images, preserving them for recovery. A new
update_folder_path command rewrites image paths in the DB before reindexing
so thumbnails and embeddings are not needlessly regenerated for unchanged
files. The sidebar shows an amber warning icon on affected folders and a
recovery banner with Locate Folder and Remove actions
- upsert_image now resets ai_tagged_at, ai_rating, ai_tagger_model, and
ai_tagger_error to NULL and deletes AI-sourced image_tags when a file
is reindexed after content changes, preventing stale tags/ratings from
the previous version being shown and blocking re-tagging
- get_pending_tagging_jobs_excluding now applies the paused-folder
exclusion in SQL before LIMIT using folder_exclusion_clause, matching
the pattern used by caption and embedding job claimers; previously a
large paused-folder backlog could starve all unpaused folders
- Merged similarRequestToken into galleryRequestToken so all
gallery-producing requests share one generation counter; a late
similarity response can no longer overwrite a subsequently loaded
folder, and vice versa
- Duplicate scanner now emits one DuplicateGroup per distinct full hash
within a sample-hash bucket, preventing disjoint sets (A,A vs B,B)
from being merged and presented as a single deletable group
- Tagger model download now installs the shared ONNX runtime DLLs via
ensure_onnx_runtime so the tagger is ready on a clean install without
requiring the caption model to have been downloaded first
- Caption queue clear now follows the tagging worker pattern: marks
in-flight rows as cancelled and deletes only non-processing rows;
the caption worker skips writing results for cancelled jobs; startup
cleanup removes any leftover cancelled caption rows
- Region search pagination now stores the crop rect in state and uses
find_similar_by_region for subsequent pages instead of falling through
to loadImages which appended unrelated folder results
Register the Tauri notification plugin and request notification permission during startup. Send completion notifications for folder scans, embeddings, AI tagging, and duplicate scans, including failure counts where available.
Include tags used by a single image in Explore and invalidate the tag cache after edits so changes appear immediately. Add an accessible, time-limited confirmation step before removing indexed folders from the sidebar.
Adds a "Search within image" button to the lightbox that lets the user
draw a crop region on an image and find visually similar results using
that crop's embedding. The crop is embedded in-memory without a temp
file via a new embed_image_crop method on ClipImageEmbedder.
Introduces a folder-scoped cosine search (search_image_ids_by_embedding_in_folder)
to support the current-folder scope option, and wires up the new
find_similar_by_region Tauri command end-to-end from Rust through to
the Zustand store and Lightbox UI.
- Fix root cause: embedding_source_path() returns Result<PathBuf>, returning
Err for videos without a thumbnail instead of silently falling back to the
raw .mp4 path that CLIP cannot decode
- indexer: split embedding batch into pre-failed (no source) and embeddable
jobs; pre-failed are marked immediately without hitting the CLIP model
- db: retry_failed_embedding_jobs skips videos still without a thumbnail so
they no longer re-fail immediately on retry
- Add get_failed_embedding_images command listing failed files + error per folder
- Gallery: amber warning badge on tiles with embedding_status = 'failed'
- BackgroundTasks: fetch and show failed filenames/errors in expanded panel
- Toolbar: conditional 'Failed Embeddings' amber filter pill shown when any
folder has embedding_failed > 0; filters at DB level via new
embedding_failed_only param on get_images / count_images
- TagCloud: replaced vocabulary/dictionary label system with representative
image thumbnails per cluster; results cached in SQLite by image-id hash
Introduces an Explore view with a tag cloud that clusters image embeddings
using cosine k-means and labels clusters via vocabulary-nearest-neighbour
CLIP matching. Vocabulary embeddings are disk-cached (FNV hash-keyed) to
avoid redundant inference. Enables CUDA for candle dependencies and adds a
build.rs check that surfaces a clear error when the toolkit is missing.
- make Candle CUDA support opt-in so default builds work on CPU-only machines
- improve semantic search loading and empty states in the gallery
- keep semantic search UX clearer when no matches are found
Refs: #4
- add semantic text search with toolbar mode switching and sqlite-vec query support
- improve embedding progress visibility, failure recovery, and similar-image affordances
- add search clearing and keyboard controls for filename vs semantic search modes
- refine background task interactions and gallery/lightbox embedding states
Refs: #4
- add Candle + HF Hub CLIP image embedding pipeline with background embedding worker
- write image embeddings into sqlite-vec and expose similar-image lookup through a new backend command
- surface embedding progress and recovery in the UI, including retries for failed embeddings
- improve gallery/lightbox embedding UX and make similar-image actions directly accessible
Refs: #3, #4
Sets up Tauri v2 + React frontend with SQLite metadata store,
sqlite-vec for CLIP embedding infrastructure, and r2d2 connection
pool replacing the single Arc<Mutex<Connection>>. Indexer now uses
rayon for parallel file metadata collection.