captioner: set_caption_detail now marks CAPTION_SESSION_DIRTY so the
cached FlorenceCaptioner session is torn down and rebuilt with the new
prompt and token limit; previously only the file was updated on disk
db: reset_generated_captions now cancels in-flight caption jobs instead
of deleting them; the worker checks for a cancelled row before writing
back, so deleting the row allowed results to be written immediately after
a reset — now mirrors the clear_caption_jobs cancellation protocol
BackgroundTasks: caption_pending/ready/failed counts are now included in
pendingMediaWork, task stages, hasFailed checks, and the dismiss snapshot;
previously a folder with only caption work caused the panel to disappear
entirely and exposed no caption progress or failure status
- BackgroundTasks: per-task Retry now dispatches to the correct backend —
retryFailedEmbeddings for embedding failures, queueTaggingJobs for tagging
failures, or both; previously always called embedding retry only
- commands: tag-cloud cache key now hashes both image IDs and embedding bytes
(xxh3) so re-embedding a file after reindex correctly invalidates the cache;
removed now-dead fnv_hash_ids helper
- db: update_folder_path uses SUBSTR instead of replace() to rewrite only the
leading path prefix, preventing corruption when the old folder name also
appears in a subdirectory name
- db: add_user_tag promotes an existing AI-owned tag to user-owned on conflict
instead of DO NOTHING, preventing the tagger from deleting a manually added
tag that coincides with an AI tag
- db/commands: add clear_duplicate_scan_cache / invalidate_duplicate_scan_cache
so deletion removes the stale persisted cache entry; without this a restart
would reload groups containing deleted images
- store: setSimilarScope re-runs loadSimilarByRegion (with saved crop) when the
active collection is Region Search Results, instead of silently switching to
whole-image similarity and discarding the crop
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
- 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
- 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