- audio_engines.js: F5-TTS and GPT-SoVITS (the separate Anomalous_TTS node
pack), detected through /object_info/<node class>. Both engines' voices are
normalised into one voice-group shape so cards, sidebar and Script Director
share one implementation.
- The audio page shows an engine switch; a missing engine stays listed as
"not installed" with install steps (no popups). The F5-TTS library still
works without the F5-TTS node; GPT-SoVITS is never scanned when missing.
- GPT-SoVITS cards come only from the node's HTTP contract: preview reference
clips, drag a character onto AnomalousTTS_CharacterSpeech, and edit the
emotion references ("Edit emotions"), saved through /anomalous_tts/settings
with unknown fields preserved and the node's validation messages shown.
- Drop targets and the Script Director are per engine: voices of one engine
are refused on the other engine's node with the reason.
- Audio gallery reads the character of GPT-SoVITS generations.
- Usage guide (in-app and docs/guides/audio-studio.md) covers both engines.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeQEub5
- audio_node_targets.js is the only list of nodes the audio studio writes
into: F5-TTS (Audio / Advanced / FromModel) takes a whole character, so the
card header sets its main voice; ComfyUI's Load Audio takes one exact clip,
so a row sets that file. Unlisted nodes are refused instead of matched by
widget name, and a single emotion clip is never written into F5-TTS's
sample (it would break {emotion} tags).
- While dragging, the hint says what releasing will do, or why a hovered node
is refused and what to do instead (shared bindMaterialDrag targetHint /
rejectHint).
- Script Director uses the same table and refuses nodes whose sample_audio is
linked.
- In the audio domain the header "!" opens a five-step usage guide;
docs/guides/audio-studio.md is the full guide (docs/guides is now tracked).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeQEub5
Conflicts:
- api/__init__.py, web/styles.css: keep audio routes/styles and add the
version manager.
- README.md, CHANGELOG.md: take main's released text; this branch's
0922b27 was an earlier alignment of the same v1.57 notes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeQEub5
- api/version_manager.py: installed version (local only), published
releases on request (GitHub API, git tag fallback), switch to a
published tag, return to the default branch (fast-forward only), undo
the last switch; refuses to overwrite modified tracked files
- header version chip and "Version & updates" panel; nothing goes online
until "Check for updates" is clicked; restart via ComfyUI Manager
- zh/en strings, styles, architecture notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeQEub5
Conflicts resolved:
- entry trigger files, web/main.js, api/__init__.py: main carries the squashed
entry fix (09b06d1), identical to this branch before its later cleanup, so
this branch's versions are kept
- ARCHITECTURE.md, docs/architecture/backend.md, web/modules/ui_sidebar.js:
both sides' additions kept
Verified on the merged tree: 107 Python tests, all JS tests except the orphaned
material_parameter_cross_node.mjs, jsdom walkthroughs of the audio studio,
domain switching and the gallery search blocks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeqEub5
- api/image_search.py reads only the PNG text chunks before IDAT (ComfyUI
prompt/workflow, A1111 parameters), builds one small record per image and
caches it by mtime; all space-separated terms must match
- hex terms of 8+ characters also match SHA256 values recorded in the
workflow (extra.anomalous_hashes) and local model files with that hash, so
renamed models are still found; A1111 "Model hash" text matches as text
- gallery_images accepts q; the search box above the gallery debounces input,
shows the match count, keeps paging/infinite scroll and the detail viewer on
the filtered list, and lets a newer query supersede one still loading
On the local output (774 PNG) the first search reads ~10 MB of text chunks;
later searches use the cache.
Verified: tests/test_image_search.py (prompt, seed, AND terms, A1111, file
names, recorded and local-index hashes, cache, chunk reader), full Python suite
(106), jsdom walkthrough of the gallery search box.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeqEub5
- entry: one explicit legacy-coordinate cleanup instead of three module-load
side effects, no ?v= import, shared size estimate and DEFAULT_MIN_SAFE_X
instead of literals, drop unused exports; drag behavior unchanged
- explain the !important topbar-entry rules as AGENTS.md requires
- docs: restore the model_identity.py entry, describe the F5-TTS voice layout,
ingestion guarantees, the no-cache/no-?v= module rule, the shared all-in-one
adapter table and the no-cross-role prompt rule; remove pixel values and
promotional wording, fix the contradictory trigger position text
Verified: tests/floating_trigger_position.mjs (9 pass), jsdom setup of the real
browser entry plus an audio-domain navigation walkthrough (outside the repo).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeqEub5
Keep a persistent header guide button, restore upward label transitions, remove duplicate CSS and obsolete notice events, and move replay styling to CSS.
Document proportional UX checks and interruption recovery checkpoints. Validated update_guide.mjs, 48-module parse/link check, diff check, and live ComfyUI manual open, Escape, replay, Help and sidebar keyboard labels. No backend behavior changed; mobile and alternate themes were not exercised.