Commit Graph
13 Commits
Author SHA1 Message Date
Will Miao 4ece4b42ff refactor(settings): move unknown-base-model routing to Library > Folder Settings
The setting decides which library an unknown-model download lands in, so
it belongs next to the default-root selects rather than General >
Downloads. Element id, settings key and i18n keys are unchanged, and
loadSettingsToUI() populates it by getElementById on every modal open,
so no JS changes are needed.

Also drop "(recommended)" from the diffusion-models option label; the
default is already conveyed by pre-selection.
2026-10-02 10:47:17 +08:00
Will Miao 3aa32120df fix(downloads): route unknown checkpoint baseModels to diffusion models by default
CivitAI labels new DiT architectures (MiniMax H3, future Flux/Wan/Qwen
variants) as model.type "Checkpoint" with plain "Model" file entries,
so the DIFFUSION_MODEL_BASE_MODELS allowlist could never keep up and
such downloads were mis-routed to the checkpoint roots (e.g. model
2877206 / version 3374439). The set of true full-checkpoint families is
closed, so the baseModel fallback is inverted:

1. file type UNet/Diffusion Model -> unet (unchanged)
2. baseModel in DIFFUSION_MODEL_BASE_MODELS (now incl. MiniMax H3) -> unet
3. baseModel in new CHECKPOINT_BASE_MODELS (SD 1.x/2.x/3.x, SDXL, Pony,
   Illustrious, NoobAI) -> checkpoint
4. unknown/empty baseModel -> new unknown_base_model_routing setting,
   defaulting to diffusion models

The setting is exposed under Settings > Downloads, validated in
SettingsManager, and threaded into both the download manager and the
download routing endpoint so they keep agreeing.
2026-10-02 09:58:01 +08:00
Will Miao 7aee964448 feat(sidecars): surface storage location and cover excluded models in migration
After migrating to centralized sidecar storage users had no indication
where their files went, and portable-mode installs silently placed the
sidecar root inside the plugin folder where a reinstall or git clean
would delete it.

- Migration now also covers models excluded from the library view and
  returns the resolved sidecar root in its result payload
- get_settings exposes the resolved sidecar root, whether it is the
  default, and whether it lives inside the installation folder
- New POST /api/lm/sidecars/open-location endpoint opens (or copies)
  the sidecar storage folder
- Settings UI always shows the effective storage path with an
  open-folder button, and warns when the root is inside the
  installation folder (portable-mode hazard)
- Migration confirmation shows the destination; on completion a result
  dialog summarizes moved/skipped/conflict counts with the storage
  location and an open-folder action
- Ignore /sidecars/ at the repository root so portable-mode sidecars
  are never committed

Refs #1045
2026-09-26 23:08:29 +08:00
Will Miao a6fca8612f fix: address review — injective mirror roots, root relocation, full preview coverage, EXDEV-safe rollback
Codex review on #1124:

- P1: mirror layout root component is now <basename>-<roothash>
  (sha256 of the normalized root path), so two roots sharing a basename
  no longer map to the same mirror directory and overwrite each other's
  sidecars
- P1: changing sidecar_storage_path while centralized no longer strands
  assets in the old root — new relocate_root migration direction moves
  the whole mirror tree, rewrites preview_url prefixes inside sidecars,
  reconciles scanner caches, and prunes the emptied old tree; the
  settings UI detects the path change and offers the relocation
- P2: migration enumerates the same preview candidates as
  find_preview_file — case-insensitive variants (model.WEBP) and the
  legacy .example.0.jpeg suffix — instead of exact lowercase
  PREVIEW_EXTENSIONS only
- P2: _rollback_model_staging restores staged files with the
  EXDEV-tolerant mover, so a failed undoable-delete staging no longer
  strands a cross-filesystem centralized sidecar copy

Tests: same-basename root injectivity, mixed-case/example preview
migration, relocate_root happy path + guards + route 400, frontend
relocation prompt flow. Verified end-to-end in a sandboxed standalone
server: uppercase/legacy previews migrate, root relocation moves the
tree and the list API serves the new locations immediately without a
rescan.
2026-09-26 12:24:17 +08:00
Will Miao f5e983eaaa feat: optional centralized storage for sidecar metadata and previews (#1045)
Add an opt-in 'centralized' sidecar storage mode alongside the default
'alongside' layout. In centralized mode, .metadata.json sidecars and
preview assets live under a configurable root (sidecar_storage_path,
default <settings_dir>/sidecars), mirroring the library-relative
directory structure: <root>/<library>/<root_basename>/<rel_dir>/.

Backend:
- settings: sidecar_storage_mode / sidecar_storage_path with validation;
  changing either refreshes the preview allowlist
- config: centralized root added to preview-serving allowlist
- lifecycle: delete / move / rename / folder-rename / folder-delete and
  undoable-delete staging all operate on the mirror tree in centralized
  mode (model files themselves never move); EXDEV-tolerant cross-
  filesystem moves
- scanners: pending-hash filesystem scan walks the mirror tree in
  centralized mode; preview discovery reads from the sidecar dir;
  .civitai.info stays co-located in both modes
- migration: SidecarMigrationUseCase moves sidecars+previews between
  layouts both directions (keep-newer conflict resolution, preview_url
  rewriting, WebSocket progress), exposed as POST+GET
  /api/lm/sidecars/migrate with a mode guard (force=true for the
  settings-first flow)

Frontend:
- settings modal: sidecar storage section (mode select + path input with
  browse/validation), mode-change confirmation offering immediate
  migration (force=true), and a 'Migrate Sidecars Now' action
- i18n keys synced to all locales ([TODO: Translate] placeholders)

Docs: metadata-json-schema.md gains a storage-location section;
AGENTS.md records the sidecar_paths helper convention.
2026-09-26 10:00:58 +08:00
Will Miao 8b7ba59263 feat: support gated/private Hugging Face repos via access token
Add a huggingface_api_key setting (Settings UI, HF_TOKEN /
HUGGING_FACE_HUB_TOKEN env override) and attach it as a Bearer token
to Hugging Face file listing, model card fetching and downloads, so
gated and private repositories can be downloaded once the user has
accepted the repo terms.

- fetch_json/fetch_text accept custom headers; ModelSource gains an
  auth_headers() hook so handlers stay platform-agnostic
- 401/403 from the tree API now explain how to fix (configure token /
  accept gated terms)
- aria2 pre-resolves huggingface.co redirects and strips credentials
  before handing the signed CDN URL to aria2, mirroring the CivitAI
  handling so the token never leaks to the CDN
- settings API exposes huggingface_api_key_set only; the raw key joins
  _NO_SYNC_KEYS
2026-09-25 18:44:06 +08:00
Will Miao 2bc9860b24 feat(settings): filename templates for download and bulk rename (#1071)
Add per-model-type filename templates ({model_name}, {version_name},
{base_model}, {author}, {first_tag}, {hash_short}, {original_name}) so
downloaded files get informative names instead of e.g. V1.safetensors.
Empty template keeps the current filename (opt-in, off by default).

- apply template automatically after downloads; rename conflicts keep
  the original name and never fail the download
- record original_file_name in metadata on rename for traceability
- bulk apply via GET|POST /api/lm/{prefix}/apply-filename-template with
  WebSocket progress, sharing the auto-organize lock
- settings UI lives in the new Organization tab with validation, live
  preview, and per-type 'apply to library' actions
2026-09-19 09:04:24 +08:00
Will Miao 327da0465b feat(settings): split overloaded Library tab into a new Organization tab
Move download path templates, priority tags, and auto-organize
exclusions out of the Library settings section into a dedicated
Organization section, so Library keeps location-focused settings
(roots, extra paths, example images, metadata) and Organization holds
file-arrangement rules. Translated settings.nav.organization for all
locales.
2026-09-19 07:38:07 +08:00
Will Miao 3302147a43 fix(other-models): make clip_vision opt-in like controlnet
DEFAULT_ENABLED_OTHER_SUB_TYPES managed vae, upscaler, text_encoder and
clip_vision while controlnet was the sole opt-in type. That split was not
defensible on demand breadth: ControlNet is the broader category by install
base, and clip_vision is the narrower one (IPAdapter/SVD image conditioning,
usually one to three files) whose CivitAI type is retired upstream.

Keep the default set to the dependency-style assets every pipeline needs and
where "which one am I actually using" is the real problem - VAE, upscalers
and text encoders - and treat clip_vision and controlnet symmetrically as
opt-in. The feature is still unreleased, so the change needs no migration.

- Sync all five surfaces holding a default: DEFAULT_ENABLED_OTHER_SUB_TYPES,
  DEFAULT_SETTINGS, both DEFAULT_SETTINGS_BASE/createDefaultSettings lists,
  updateOtherModelsControls()'s fallback and the Jinja fallback.
- The selection is persisted per user, so only the untouched default moves;
  existing default_other_roots entries for a disabled sub_type are preserved.
- Fix the Jinja fallback using `or`, which treated an all-unchecked empty
  allow-list as "unset" and re-checked every box on render; `is none` keeps
  the empty list empty.
- Document the revised defaults and rationale in the plan.

Tests assert the new default trio, the normalize fallback, that both opt-in
types stay out of the default scan, and the auto-set iteration test now
enables clip_vision explicitly since it exercises the loop, not the default.
2026-09-13 20:12:49 +08:00
Will Miao 69a62d739c feat(frontend): opt-in Other Models toggles, hidden nav and announcement
- The Other nav entry is hidden while the feature is off
  (nav-item--hidden, toggled client-side after enabling) and now uses the
  fa-shapes icon.
- Shared utils/otherModels.js helpers (enable through the settings API,
  open the settings Library section) are reused by the disabled page, the
  announcement banner and the download modal.
- BannerService registers a one-time dismissible "other-models-announcement"
  banner while the feature is off; SettingsManager drops the banner and
  updates the nav when the master switch flips.
- A disabled download routing answer now surfaces a showActionToast with an
  "Enable Other Models" action.
- Settings UI: master toggle + five sub_type checkboxes whose default-root
  selects are disabled when unchecked; i18n keys added to en.json and synced
  (other locales keep TODO placeholders).
2026-09-13 07:59:28 +08:00
Will Miao fc3b2d7c13 feat(frontend): enable downloads on Other page and default_other_roots settings UI 2026-09-12 15:56:47 +08:00
Will Miao ec147bd677 feat(ui): add setting to keep the action bar visible while scrolling (#1095)
Adds a 'Keep Action Bar Visible' toggle (default off) under
Settings > Interface > Layout Settings. When enabled, the controls bar
(Refresh, Download, etc.) and the breadcrumb nav are wrapped in a shared
sticky container (.sticky-topbar) so both stay pinned as one unit; when
disabled, the wrapper is display: contents and the original behavior
(only the breadcrumb stays visible) is preserved.
2026-09-04 23:53:27 +08:00
Will Miao cb4fd3a0e6 refactor(ui): split settings modal into section templates with shared macros 2026-08-21 09:14:52 +08:00