User-created characters now live in a Subjects -> Mine view with an 'Add
subject' tile; the character menu gains Delete (hide base) / Remove (drop
add). apply_overlay gains include_adds=False (used by the paginated
character browser + detail) so adds never leak into a LIMIT/OFFSET page.
- NSFW hide toggle (🔞) beside Tags/Natural-Language: hides designated NSFW
groups + leaked NSFW items from the picker browser only; build state /
round-trip / emit untouched. Manifest-driven, default hidden.
- NSFW Actions category: surfaces the dormant nsfw_action bucket (451 acts)
as a toggle-gated 🔞 category; emits like a normal action. Backend already
existed; frontend-only.
- Card/list view toggle (▦/☰) in the browser header: compact list rows with a
tiny left thumb, persisted; pure CSS restyle, works in every view.
Safety: delete 19 curated tag-builder items that should not exist at all
(non-consent, bestiality, guro, and minor-sexualization tags across
appearance/expression/nsfw_action/cast items), per a content-safety audit.
Also: add /characters/identity-index so the picker recognizes all 1,486
normalized characters in existing prompts (was capped at 200).
The default 'all' view mounts ~4,200 cards at once; almost all are off-screen.
Add content-visibility:auto so the browser defers layout/paint of off-screen
cards until they scroll into view. Initial open is now noticeably faster;
behaviour is unchanged (cards stay queryable/scrollable/findable).
Delete the legacy v1 Tag Builder (components, entry, bridge, constants, build
artifact) and its 'Tag Builder (Legacy)' right-click menu item. Fully superseded
by v2 'Add Tags'/'Edit Tags', which are untouched. ~3,000 lines of source and a
~155 KB bundle removed; shared modules kept.
The rail capped at the top 60 by popularity with no way to browse the rest of a
narrowed category (anime/video_game). Add loadMoreCharacters + an
IntersectionObserver sentinel that appends the next page on scroll.
The All-view filter re-rendered thousands of card DOM nodes synchronously on
every keystroke. Drive the filter off a debouncedQuery that lags the input by
200ms so the grid updates ~5x/sec while typing instead of per keypress; the
input stays instant, category switches clear it, jumpToTag stays synchronous.
Backend:
- H4 get_db reconnect storm: gate the one-time schema/normalize/reconcile helpers
behind a process-level flag so the ~11,529-row reconcile stops re-running on the
asyncio loop on every spurious mtime reopen.
- H5 tag_search write-on-read: cache last-good fingerprint (return it on transient
lock instead of zeros -> no spurious 5-10 min re-embed) + mtime-gate the query.
- Remove dead /clothing/assemble + /furniture/assemble routes.
- Escape LIKE %/_ in 3 character-prefix lookups; NULL-guard /props/assemble.
- New POST /tag-builder/maintenance (idempotent orphan cleanup + alias dedup).
Frontend:
- Customizer output-mode: thread real isNaturalMode into the 3 customizers; preview
matches the actual emit per mode; focus checkbox disabled (not silent no-op) in
tag mode.
- Event-driven timers: drop 3 setTimeout(0) click-outside deferrals + the 1100ms
flash timer (animationend instead).
- Tag-builder: port ~1,477 v1 characters into the v2 chip format so the
character picker shows 1,486 characters (was 9); 1,390 carry rich per-chip
descriptions restructured from each character's own bio. Adds
scripts/port_v1_characters_to_v2.py.
- Ideogram: rewrite caption to the real Ideogram-4 schema + broaden refusal
detection; sampler updates.
- Pose-studio, regional-detailer, attention-couple: assorted fixes.
- Add validate_templates / test_regions / test_crop_windows scripts.
- Image editor: layers with masks/blend modes, lightweight groups, Camera Raw
scoped to the selected layer, full-frame i2i, Copy Merged, Photoshop keyboard
shortcuts, and a large batch of Photoshop-parity bug fixes.
- LoadImage right-click "Open in PromptChain editor" bridge (edit -> lineage
child re-pointed onto the node).
- Krea 2 Turbo/Realism templates and editor modal integration; remove the
krea2 Text-to-Image 3D Regional template.
- ControlNet depth + 3D-pose: wire Poser true-depth straight into Apply
ControlNet on pose paths.
- Sidebar: drag-to-LoadImage now uploads to the input root so the widget value
is a valid bare filename; "Copy as path" emits native Windows backslashes.
- Contributor/relicensing docs and packaging tweaks.
Ticking Realism on a Krea 2 Turbo i2i edit now drops the author's
ClownsharKSampler_Beta recipe defaults (sampler/steps/cfg/denoise) into
the dials, while still honoring any value the user has guided away from
- the same preset pattern as the 'engine' picker. Unticking restores the
engine defaults. Realism still always swaps in the abliterated encoder,
wan VAE, and the projector+realism LoRAs regardless of sampler choice.
Registers Ideogram / Ideogram 4 in the model enum so the New Workflow picker
shows a proper "Ideogram" group. Completes the Ideogram 4 integration already
in this repo: local-model recognition, text-to-image template, prompt-template
library, and the JSON-envelope caption + auto-retry sampler that work around the
model's built-in safety-block false positives.
Render modals now remember and restore the user's last setup per image,
surviving close/reopen and restart, via a server-side sidecar keyed by image
content hash.
- New core/modal_setup_api.py sidecar (sibling of edit-docs): POST(merge per
kind)/GET/DELETE, manifest + binary planes, LRU budget, tombstone-aware.
- Re-pose: AUTO-restores recipe/model/prompt/strength and the full 3D pose on
open (seed-before-mount), lineage-aware so a re-posed result/edit resumes its
source's setup. Plus a Re-Apply button.
- Inpaint: restores engine/mode/dials, the PuLID/Style-Reference cluster, the
prompt, and the painted mask (alpha plane).
- Upscale: restores dials + prompt via an opt-in chip, doc-dims keyed.
- Also: before/after Compare wipe on Upscale + Re-pose; Fit/Compare controls
relocated with click-fix + double-click-to-fit.
A focused range slider (opacity/feather) or <select> is not a text field, so
Delete/Backspace there now still removes the lasso selection instead of being
swallowed.