* fix(threads): stop and join the prompt cleanup thread, the image worker and the observer (#302, #370)
- PromptTracker: the cleanup thread waits on a stop event instead of
time.sleep; new shutdown(timeout=2) joins it and returns whether it ended.
- ImageGenerationHandler.shutdown(timeout=5) now joins the worker and
returns a bool; new close() is final: schedule() refuses and a sealed
run's history re-check is dropped, so no worker restarts afterwards.
- ImageMonitor.stop_monitoring(timeout=5) closes the handler first, then
stops and joins the watchdog observer within one deadline.
- Every test that builds a real tracker, handler or monitor ends with its
final stop and an assertion, before its folder and databases go.
- #370: the wrapper/session history test drains before dispose(); the
held-write bound test uses 30 s ceilings instead of tight wall clocks.
* test(history): drain the writer before asserting a bounded close it does not test (#370)
* fix(threads): a later stop waits again for a worker or observer an earlier stop left running (#302)
Review findings on #372:
- ImageGenerationHandler keeps the workers a stop signalled that had not
ended; every later shutdown/close joins them again, so a second call no
longer returns True while the first worker still runs.
- ImageMonitor.stop_monitoring keeps an observer or handler it left
running and stops and joins it again on the next call.
- A closed handler takes no awaiting history path, and a re-check that
raced close() is not kept due.
- Tests: second stops of a busy worker and a live observer, the closed
handler's re-check paths, the handle test asserts the worker ended and
stops before it asserts, and a no-new-thread check instead of set
equality.
* test(browser): the System reset restores every settings value, safety_backup included
The frontend coverage shard of #372 failed in workspace-system-tagging:
the review read "No safety backup (the policy is off)". The backups spec
saves safety_backup=false, and /__test__/system/reset restored config.json
but not PromptManagerConfig.SAFETY_BACKUP (nor INFINITE_SCROLL), so a
later spec on the same worker server saw the policy off. The reset now
captures and restores every non-tagging value POST /settings can change.
* fix(search): PromptSearchList crash, filters, and batch output (#52)
- Fix empty list crash (OUTPUT_IS_LIST requires at least one element)
- Add partial tag matching (LIKE instead of exact)
- Add preview and count outputs for batch visibility
- Add skip_multipart filter for Clip_N video prompts
- Add LoRA-only prompt filter
- Collapse newlines for StringOutputList compatibility
* feat(db): add tag_partial parameter for LIKE tag matching (#52)
Allows search_prompts to use LIKE matching for tags instead of exact.
Used by PromptSearchList for discovery-style search.
Existing callers default to exact matching (unchanged behavior).
* feat(tracker): add FIFO prompt queue for batch image linking (#52)
Batch workflows encode all prompts first, then save all images later.
The queue preserves encode order so each image links to the correct
prompt by position (pop on save matches push on encode).
* fix(monitor): multi-strategy image-to-prompt linking (#52)
Previous approach relied on live prompt tracker state, which was
always stale for batch workflows (all images linked to last prompt).
New 5-strategy priority chain:
1. FIFO queue pop (batch-correct by position)
2. Metadata-based DB lookup (extracts prompt from PNG)
3. Prompt snapshot at file-creation time
4. Live prompt tracker
5. Most recent DB prompt fallback
* test: add tests for prompt queue and search filters (#52)
- 6 queue tests: FIFO ordering, batch simulation, exhaustion
- 15 filter tests: newline collapse, Clip_ filter, LoRA-only filter
- Fix _make_tracker helper to include queue fields
* chore: bump version to 3.2.2
* fix: address code review — regex backtracking and queue expiry (#52)
- Replace backtracking-prone LoRA-only regex with subtraction approach
(re.sub removes tags, check if anything remains). Fixes CodeQL alert.
- Add expiry check to pop_next_prompt — skips stale entries to prevent
incorrect linking from accumulated queue entries across sessions.
- Cleanup thread now also prunes expired queue entries.