- Expand onboarding tour from 8 to 11 steps: marquee drag-select,
drag card to sidebar folder, and the three context menus
(card / bulk / global); enrich bulk-mode step with range-select
and exit tips
- Add Replay Tutorial button to help modal Getting Started tab
- Add Shortcuts cheat-sheet tab to help modal, opened directly via
the '?' key when not typing
- Fix trigger-word tooltip to mention double-click to edit
- Keep checkpoint/embedding send tooltips truthful (no replace mode)
Sync new i18n keys to all locales (placeholders pending translation)
The Add button silently returned when no parameter or value was
provided, looking clickable but doing nothing. Keep it disabled until
both inputs are filled, validate the numeric value, surface save
failures via toast without clearing user input, and confirm additions
vs overwrites with success toasts. Includes translations for all
locales.
With hardware acceleration disabled, Chrome rasterizes in software and a
full-viewport backdrop-filter forces a per-frame CPU blur over everything
behind the modal, freezing the whole browser.
Detect software rendering via the unmasked WebGL renderer string at app
startup and drop the backdrop blur in that case. Also route the download
modal's sticky toolbar through the shared --modal-backdrop-blur variable
instead of a hardcoded blur(8px).
- Wheel on the main viewer: horizontal deltas always switch examples;
vertical deltas switch only at the modal scroll boundary, then stay in a
sticky session (down = next, up = prev) until the pointer leaves the area
- Touch/pen horizontal swipe switches examples; the synthesized click after
a swipe is swallowed so the media viewer does not open
- '[' / ']' switch examples while the gallery is expanded; ArrowLeft/Right
stay reserved for model-level navigation
- Direction-aware slide transition on every switch for visual feedback
(respects prefers-reduced-motion)
Add a de-emphasized meta footer to the recipe modal, mirroring the model
modal's hash footnote: a clickable file location on the left (opens the
recipe JSON via the generic open-file-location route, with the Docker
clipboard fallback) and a middle-truncated recipe ID with copy button on
the right.
The recipe detail API now exposes recipe_json_path so the frontend does
not have to guess the on-disk storage layout. Translations for the new
recipes.modal.* keys are filled in for all 9 locales, reusing the model
modal's openFileLocation wording per locale.
Checkpoint entries that cannot be restored by download (deleted,
unresolvable hash, or name-only remnants with no CivitAI identifiers)
now get the same remediation chain LoRAs already had:
- scanner: parameterized reconnect-suggestion ranking, update/restore/
set-hash-invalid for the checkpoint entry, and clear hashInvalid on
rematch write-back (was only done for LoRAs)
- persistence/handlers/routes: reconnect/restore/reconnect-suggestions/
mark-hash-invalid endpoints under /api/lm/recipe/checkpoint/*
- modal: checkpoint reconnect UI (deleted/hash-invalid badges, inline
form with suggestions, undo for reconnected entries); download
failures mark the hash invalid only on explicit unresolvable signals
(not found/deleted/404/410), matching the LoRA rule
- css: checkpoint undo button shares the LoRA undo styles
- i18n: the 14 new keys translated in all 9 locales
Record import provenance on every recipe: a new import_info block
(channel, machine-readable no-LoRA reason, diagnostic details) built at
import time across all channels (batch import, single URL, local file,
upload, widget save, re-imports) and persisted in the recipe JSON plus
the SQLite persistent cache (new import_info_json column with ALTER
TABLE migration).
The recipe modal renders the empty LoRA list with a collapsed details
panel showing the import method, the reason (CivitAI API returned no
LoRA resource data, API meta missing, no embedded metadata, ComfyUI
workflow metadata, video, unparsable format), and recorded diagnostics.
Legacy recipes without import_info fall back to heuristics labeled as
inferred. Genuine no-LoRA generations show no panel.
CivitAI images are always classified by API meta shape: the onsite
generator writes A1111-style EXIF without LoRA references, so parsed
EXIF cannot prove "no LoRAs used".
Adds recipes.resources.noLoras* i18n keys (all 10 locales) plus
frontend vitest and backend pytest coverage.
Enhance the deleted-LoRA reconnect flow in the recipe modal:
- Suggest local reconnect candidates when the panel opens, ranked by
identity (same hash / same CivitAI version) then filename/name
similarity, with a hard filter on confident base-model mismatches;
the input gets a Combobox backed by the same endpoint as you type.
- Snapshot the pre-reconnect entry and offer a permanent restore:
reconnected entries show an undo icon at the right end of the info
row, with the original filename in the tooltip.
- Relax the manual reconnect base-model guard to a three-tier check:
exact/unknown labels pass silently, same-architecture families
(e.g. Pony <-> Illustrious) pass with a warning toast, and only
cross-architecture mismatches stay hard-rejected.
- fix .reconnect-input overflow (calc(100% - 20px) -> border-box 100%)
- replace nested-card border/background with a dashed top separator
- route reconnect copy through translate(); add recipes.resources
.reconnectInstructions/reconnectExample/reconnectPlaceholder keys
and translate them in all 9 locales
- show reconnect failures inline in the panel (role=alert) instead of
a transient toast; errors clear on input/show/hide
- drop dead .reconnect-instructions code CSS; add regression test
- Add an icon-only copy button next to Send to ComfyUI in the header
actions row, styled as a textless variant of the neighboring pill
buttons
- Restore fetchAndCopyRecipeSyntax() wiring against the existing
/api/lm/recipe/{id}/syntax endpoint (context menu action unaffected)
- Add recipes.actions.copyRecipeSyntax i18n key, reusing the existing
per-locale translations of the identical context menu string
- Sync modal test fixtures and add copySyntax tests
The recipe card pill counted LoRAs deleted from the source (isDeleted) as
available, showing a green 'ready 2/2' for recipes that cannot be fully
reproduced. LoRAs with an unresolvable hash (hashInvalid) were counted as
missing/downloadable even though downloads always fail, and recipe syntax
generation emitted broken tokens for them.
- Four-state status on RecipeCard pill and RecipeTab badge: ready (all in
library), missing (downloadable, red, keeps the action cue), partial
(unobtainable entries skipped when used, amber, fa-circle-minus),
unavailable (nothing usable, gray, fa-ban)
- Pill numerator is now the real in-library count; tooltips spell out
missing vs unavailable (deleted from source or unresolvable hash)
- get_recipe_syntax_tokens skips hashInvalid entries like deleted ones
instead of emitting tokens pointing at nonexistent files
- Bulk missing-download manager and recipe context menu exclude
hashInvalid LoRAs, matching the modal's per-item download block
- New locale keys loraStatus.missingAndUnavailable/partial/noneUsable,
translated for all 9 non-en locales
import-modal.css is loaded after recipe-modal.css and its unscoped
.missing-badge/.deleted-badge (equal specificity) were clobbering the
recipe modal's badge family, leaving invalid-hash-badge (no import
counterpart) at a different size. Scope the recipe status-badge sizing
under #recipeModal so import-modal.css can't override it. Also remove the
duplicate .deleted-badge block in import-modal.css.
- import: prefer A1111 Lora hashes (12-char AutoV3) over conflicting Hashes
JSON values; recover the quote-wrapped AutoV3 from CivitAI image API meta;
merge EXIF-parsed LoRAs when the API-only parse yields none (meta=null)
- rematch: treat entries whose hash failed CivitAI resolution (hashInvalid)
as unresolved candidates; clear the flag on rematch/reconnect write-back
- download: persist hashInvalid and show a distinct toast when hash lookup
returns "Model not found", so unresolvable entries become recoverable
- ui: add Unresolvable Hash badge styling and reconnect affordance
- i18n: translate the new keys across all 10 locales
- Badges are pure status indicators with tooltips; remediation moves to a
per-item action row (Download / Reconnect), matching the versions-tab
badge/button pattern
- Civitai link inlines with the model title; the action row renders only
when real actions exist, removing empty-row whitespace
- Single-LoRA download resolves identifiers from hash on demand (same
fallback as the bulk missing-download flow) and shows immediate
'Preparing download' feedback while resolving
- Successful downloads (LoRA and checkpoint) refresh the resources
section and the recipe card in place, mirroring the bulk flow
- Row navigation is limited to in-library items with keyboard support;
checkpoint type renders as muted text instead of a chip; badges use
tonal styling; the local-path hover tooltip is removed
- Add resourceItems frontend tests and translate the new keys for all
10 locales
- Recipe card: compact status pill with state icon + available/total
fraction (e.g. "2/3"), pinned to the footer bottom-right like model
card actions; status is encoded by icon + color, never color alone
- Recipe modal: "N missing" is now a real <button> with a persistent
border, leading download icon, focus-visible ring and aria-label;
clicking opens the download-missing flow
- Fix context menu missing-LoRA detection selector after badge refactor
- i18n: add recipes.status/loraStatus keys with translations for all
10 locales, and fill pending rate-limit translations
- Extract a shared BaseModelPicker (search, keyboard navigation,
filename-based suggestions, dynamic API models such as MiniMax H3
under 'Other (API)') used by both the single-model metadata modal
and the bulk base model modal
- Rework the bulk base model modal into a dedicated inline-list
layout: fixed modal size, sticky-free footer with app-standard
modal-actions/primary-btn/cancel-btn buttons, and an inline option
list that scrolls itself instead of an overlay dropdown covering
the footer
- Selecting an option in change mode now filters the list to the
selection instead of resetting and scroll-jumping to it
- Restore opaque sticky section headers in the bulk modal so scrolled
items no longer bleed through
- Three-column layout (preview | generation parameters | resources) with
independent per-pane scrolling and a content-sized modal shell that
shrinks to fit short recipes and caps at viewport height for long ones
- Blurred, darker backdrop to focus attention on the modal
- Preview frame hugs the image instead of a fixed-size box
- Move recipe-level 'Send to ComfyUI' into the header actions row to match
the model detail modal convention; remove the modal 'Copy Recipe Syntax'
button (context menu action is unaffected)
- Add recipes.actions.sendRecipe i18n keys with translations
- Sync modal test fixtures to the new structure
CivitAI's PaidAccess cutover deprecated the availability=EarlyAccess and
earlyAccessEndsAt signals; gated versions now report availability=Public
with a paidAccess DTO that LoRA Manager previously ignored, so "Hide
Early Access Updates" missed paid/early-access models and downloads
failed with 401.
Parse and persist paidAccess from model-level, bulk, and by-hash
responses; treat timed paid gates as early access and permanent paid
versions as a distinct is_paid state; add a hide_paid_updates setting
with a "Paid" badge in the versions tab; warn before downloading gated
versions. Includes SQLite migration, i18n for all locales, and
backend/frontend tests.
Make the import modal a flex column with a scrollable step area so the
Back/Import buttons stay visible on short viewports (1080p / 150% zoom)
instead of being cut off at the bottom of the scroll flow.
Also reset step scroll positions via class since 'locationStep' has a
duplicate id in the download modal template.
- Add POST /api/lm/switch-channel endpoint with git init / ZIP fallback
- Add _backup_git/_restore_git helpers with safe rollback
- Version-info endpoint now returns has_git flag for auto-detection
- Check-updates always returns releases (changelog) regardless of channel
- Nightly mode shows 'N commits behind main' with commit hash and date
- View on GitHub link points to /commits/main in nightly mode
- Channel toggle UI with pill-style buttons in update modal
- Confirmation dialog with Esc / backdrop-dismiss support
- Channel derived from has_git on every page load, no localStorage
- i18n: 11 new keys translated across 9 non-English locales
- CSS: unified card-style sections in _base.css
- Tests: 8 new tests covering switch-channel, nightly response, init_git_repo
Changes:
- Backend: _validate_folder_paths() now checks checkpoints↔unet overlap
within the same library using os.path.realpath() for symlink resolution
- Backend: set() calls _validate_folder_paths() for both folder_paths and
extra_folder_paths before writing
- Backend: extracted _normalize_path_set() helper to eliminate duplicated
normalization logic
- Frontend: inline error display with red border + error message below the
conflicting input, no save triggered
- Frontend: path normalization (strip trailing slash, lowercase) in pre-check
to reduce false negatives vs backend realpath
- Frontend: asymmetric error UX — message only on the user-edited side,
red border on the pre-existing conflict side
- CSS: has-error styles with hardcoded rgba fallback for older browsers
- i18n: checkpointUnetOverlap + checkpointUnetOverlapInline keys added to
all 10 locale files
- Merge Relink to Civitai and new Link to HuggingFace into a single
'Link Model' submenu with sub-options for each source
- Add POST /api/lm/set-hf-url endpoint to associate a model with a
HuggingFace repo URL, saving hf_url to .metadata.json
- Add link_hf_modal.html for URL input, following relink-civitai pattern
- Use update_single_model_cache instead of add_model_to_cache to
prevent duplicate cache entries after linking
- Remove os.path.realpath usage for consistency with relink-civitai
- Raise errors instead of silently falling back to LoRA scanner when
model root cannot be determined
- Scope .input-group CSS rules to modal IDs to fix style conflicts
with download-modal.css
- Add i18n keys across all 10 locales with translations for
zh-CN, zh-TW, ja, ko, de, es, fr, he, ru
- Replace hardcoded provider list with PROVIDER_PRESETS (OpenAI, Ollama,
DeepSeek, Groq, OpenRouter, OpenCode Go, Custom)
- Load model lists from models.dev/api.json catalog at startup
- Add Combobox vanilla JS component for model/base-URL selection
- Fetch local Ollama models via live API instead of catalog
- Hide API key values from frontend (boolean-only llm_api_key_set)
- Add i18n translations for all 9+ locales
- Update snapshot tests for new response fields
Replace native <select> with a searchable dropdown that:
- Filters options as the user types
- Shows filename-inferred suggestions at the top in a "Suggested" section
- Supports keyboard navigation (ArrowUp/Down/Enter/Escape)
- Allows typing custom values not in the list
- Removes dead .base-model-selector CSS
Adds 3 new i18n keys (baseModelSearchPlaceholder, baseModelSuggested,
baseModelNoMatch) with translations for all 9 locales.
- Unify single-URL and multi-URL HF repo flows to use the same batch
preview interface (remove separate repoFileStep)
- Remove unnecessary cloud icon from HF batch preview items
- Use formatFileSize() instead of hardcoded MB text
- Change default selection to unchecked (no preselected files)
- Add select all / deselect all checkbox with dynamic Next button
- Clean up dead CSS, HTML template, and JS methods from removed
repoFileStep
- Add selectAll i18n key with translations for all 10 locales
- Fix batch progress bar name fallback for HF items