Commit Graph
120 Commits
Author SHA1 Message Date
DemonGatanjieuandClaude Opus 5.5 17a2c2f03d Full window for the browser; more room on Voice-over
A full-window button beside Dock (and a double-click on the title bar)
makes the window fill the ComfyUI page, remembered; it is neither dragged
nor resized then, and docking turns it off. Voice-over: one row per line
card, a divider between the lines and the generating side (dragged and
remembered, ui_split_bar.js; about half each by default), "Into your own
workflow" folded, who reads and their voices on one row, the how-to line
only until there are lines. On a wide side the modes' scale and numbers
are shown open unless the fold was closed before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 22:20:17 +08:00
DemonGatanjieu 613034f3ec Merge branch 'feature/next' into feature/model-import
# Conflicts:
#	web/styles.css
2026-10-15 12:55:22 +08:00
DemonGatanjieu 785b48bb1b Merge branch 'main' into feature/next
# Conflicts:
#	CHANGELOG.md
#	web/styles.css
2026-10-15 12:53:20 +08:00
DemonGatanjieuandClaude Opus 5.5 7ceb591cbf Fix the list column's :has() rule slowing every style change (#22)
The rule that hides the list column while a workspace is open matched
the workspace panel's style attribute inside :has(). Chrome then treats
every inline-style write on the page as a possible change and restyles
the whole page, so extensions that move their buttons every frame took
a large workflow's canvas down to 2-3 fps. The container now gets an
anomalous-workspace-open class from a MutationObserver on the panel's
style (every module opening a workspace sets its display), and the CSS
keys off that class.

Found, measured and fix proposed by Lindemellis in issue #22.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 12:52:49 +08:00
DemonGatanjieuandClaude Opus 5.5 48e273f5c7 Tidy: opened workflows count as use; packs with a page part set apart
A node put on the canvas or a workflow opened and never run read as
"never used". The page now notes what each opened workflow holds
(usage_notes.js, POST /anomalous/usage/opened, kept apart from runs in
the run record) and the open tabs just before a check.

Packs whose nodes went unused but which also add to the page (buttons,
menus, monitors) get their own group: unused nodes do not say the pack
is. The packs count covers only packs that work through nodes alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:49:32 +08:00
DemonGatanjieuandClaude Opus 5.5 e0abbd277a Folder column: the current type's folders, with 📂 to open one in Explorer
The list column showed every type's tree (raw folder names, [Root] rows with 0, nothing marking
where you are), repeating the type chips above it. Now (ui_folder_list.js) it follows the chips:
the type's heading with "📂 Open", All, its subfolders as a tree whose numbers count their
subfolders (empty ones dimmed, folding per session in owner.collapsedFolders), and "In the top
folder" for models directly in the type's folder; the listed one is marked.

A Bilibili comment asked for quick ways to open model folders: POST /anomalous/open_model_folder
without a file name now opens the folder itself (type root or subfolder; still by type, index
and subfolder, never a path, local only). Tests in tests/test_model_folder.py.

Gone: the every-type tree, Expand / Collapse all, expandedFolders and their locale keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:28:03 +08:00
DemonGatanjieu 244af6a1e0 Merge feature/next: Esc closes, Show in folder, insert a picture as a node
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	ARCHITECTURE.md
#	api/__init__.py
#	web/modules/locales.js
#	web/modules/ui_detail.js
2026-10-13 01:12:43 +08:00
DemonGatanjieu 1af47f255c Merge main: Esc closes, Show in folder, insert a picture as a node
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	CHANGELOG.md
#	api/__init__.py
#	web/modules/browser_entry.js
#	web/styles.css
2026-10-13 01:11:13 +08:00
DemonGatanjieuandClaude Opus 5.5 e0129eaa2f Esc and the shortcut close the browser; Show in folder; insert a picture as a node
From a Bilibili comment (2026-10-13):
- Esc closes the top layer: a dialog or menu (the plugin's alert and confirm
  now close on Esc, as OK / Cancel), else the Workflows / Combos workspace,
  else the browser. One capture listener decides before the layers act, so a
  dialog closing on the same Esc still counts as above. The shortcut and the
  Extensions entry toggle the browser.
- A model's file card has Show in folder: POST /anomalous/open_model_folder
  (api/model_folder.py) takes type, folder index, subfolder and file name,
  never a path, and opens Explorer / Finder with the file selected; a POST,
  so local_guard keeps it to this computer. The card moves out of
  ui_detail.js into model_location.js.
- A gallery card's right-click menu (gallery_card_menu.js): Insert as a Load
  Image node reads the output file in place ("name.png [output]"), and View
  Parameters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:09:29 +08:00
DemonGatanjieuandClaude Opus 5.5 4a0ea14b40 Merge feature/next: only this computer can change things (v1.58.1)
Import, Tidy and scan choices take the local check from local_guard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:41:56 +08:00
DemonGatanjieuandClaude Opus 5.5 a44c93bf44 Merge main: only this computer can change things (v1.58.1)
MCP now uses local_guard.is_local (one local check). A backup upload
request that is no upload answers 400 instead of 500. tests/test_local_guard.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:40:28 +08:00
DemonGatanjieuandClaude Opus 5.5 aa9c237f98 Only this computer can change things; other devices can look (v1.58.1)
With ComfyUI started with --listen, other devices could use most of AMB's
actions: delete and rename models, save and delete workflows and prompts,
start downloads and scans, export a backup of all data, translate with the
user's key, change settings, switch the plugin version. A probe of all
routes as a LAN device found 9 of 112 refusing.

api/local_guard.py is one middleware in front of every /anomalous/ route:
anything but GET answers only this computer unless it is a read sent as POST
(OPEN_POSTS); a GET is open unless it is more than a read (LOCAL_GETS:
backup file, GitHub releases, local folders). Local = loopback peer, no
proxy headers, loopback Host (DNS rebinding is refused too). Refusals are
403 local_only with a bilingual message; GET /anomalous/access lets the page
show a "view only" chip (remote_view.js). AGENTS.md rule 4 now names it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:38:20 +08:00
DemonGatanjieuandClaude Opus 5.5 f7447b2222 Import dropped model files into the right folders; version labels; settings tabs
- Models page: "+ Import" chip and model files dropped on the grid open an import
  window. model_kind.py tells a file's type (LoRA, checkpoint, VAE, text encoder,
  diffusion model, ControlNet, embedding, CLIP Vision, upscaler) and base model from
  its safetensors / GGUF header only; .ckpt/.pt are never opened. api/model_import.py
  finds the dropped file in Downloads/Desktop (name, size, time) and moves it, or
  takes an upload; checks it against Civitai and the scanned models; never replaces
  a file (" (2)"). New files are scanned after.
- Model cards show the Civitai version name (metadata version_name).
- Settings page in tabs (Look, Models, Workflows, Prompts, Backup, Help); the
  download folder is a choice of ready-made folders or typed by hand; default is now
  by base model ({base}).
- The scanner's offline base model uses model_kind (LoRAs, Qwen, Wan, Chroma...).
- AD-019: no Civitai browser inside the plugin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:07:43 +08:00
DemonGatanjieuandClaude Opus 5.5 430a83af00 Make light theme text clearer
Grey secondary and hint text is darker in the light theme. Labels and
buttons laid over pictures (model card names, recipe cover labels, the
gallery's View parameters button) keep the dark tokens, including
ComfyUI's palette variables, so their text no longer turns dark on a dark
backing. Prompt role badges, the red close crosses and the voice import
button get colors that read in every theme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 18:25:01 +08:00
DemonGatanjieuandClaude Opus 5.5 7b363bdac8 Light theme: follow ComfyUI, dark, light or Abyssal Scarlet
Settings -> Appearance -> Theme (and the ComfyUI setting
Anomalous.ModelBrowser.Theme, which replaces the Abyssal Scarlet switch)
picks Follow ComfyUI (default), Dark, Light or Abyssal Scarlet. Following
ComfyUI watches the dark-theme class ComfyUI sets on <html> for a dark
palette and repaints at once; an older Abyssal switch reads as Abyssal.

The light theme is html.amb-theme-light with its own --amb-* values. Hard
coded colors were turned into tokens whose dark values are the colors they
replace (checked: every stylesheet resolves to the same dark values):
rgba(var(--amb-ink-rgb), a) for tints, status shades, tooltip, float,
dialog, sunken, scrim and note tokens. Older rules and inline styles that
wrote a dark color now write var(--amb-lt-<role>, <that color>); the
--amb-lt-* tokens exist only in the light theme. Inside the plugin's
windows ComfyUI's palette variables (--bg-color, --fg-color ...) follow the
plugin's theme when the two differ. Surfaces over images stay dark, and the
image viewer gets the dark tokens back. The ready banner on a recipe reads
green instead of pink. Stylesheet cache versions are bumped.

Checked on a test ComfyUI in light and dark: home, models, gallery and its
viewer, workflows and a recipe's tabs, combos and a combo, prompts and the
docked drawer, voices, audio library, settings, scan, Model Check, current
node and its model picker, a model's detail with notes, share, save
recipe, update guide, versions, GPT-SoVITS settings and the prompt dialog;
light with a dark ComfyUI, and Abyssal Scarlet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 17:27:02 +08:00
DemonGatanjieuandClaude Opus 5.5 b78747c9a8 Prompts is a page like the others; "Beside the canvas" docks it
The rail's Prompts entry used to fold the browser away and open Prompt
Studio in a drawer by the canvas, the one page that left the window. It is
now the browser's Prompts page (owner.promptPanel): the rail, the 7 key,
opening the browser with a text node selected, Current node's "Edit in
Prompt Studio" and a kept prompt all go there, and reopening the browser
returns to it. "Beside the canvas" on the page moves the studio into the
drawer as before (side and width remembered, browser folded away); the
drawer has "Back to the window" and Close.

Only one studio is shown at a time. The page's studio stops when another
page is shown, a workspace opens or the browser closes (its 400 ms poll
with it) and is made again when the page is shown; closing a workspace
opened from the Prompts page returns to it.

Checked live on a test ComfyUI: a CLIP Text Encode opens the page aimed at
it; docking, Back to the window and Close; 3 then 7; Workflows opened and
closed from the page; reopening the browser.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 17:06:27 +08:00
DemonGatanjieuandClaude Opus 5.5 ca003d20d2 feat: Hugging Face first with the mirror, model card covers, text encoders shown, header search
- Downloads: with the China mirror on, a Civitai match whose very file (same
  SHA-256) is on Hugging Face too, by the workflow's link or ComfyUI-Manager's
  list, is fetched from Hugging Face; Civitai's name, base model and page stay.
- A file downloaded from Hugging Face gets its model card's first example
  image as cover and its base model, trigger words and example prompts as
  notes, with the repository as link (api/hf_card.py), never over what the
  user or a scan set.
- Text encoders, CLIP vision and upscalers are shown (and scanned) by
  default, so shared workflows carry their fingerprints; older configs get
  them turned on once (folder_defaults_version 2).
- The models page's search sits in the header (ui_model_search.js) instead
  of inside the folder list; it searches the whole type by name, file name,
  folder, trigger words, base model and notes, every word; Esc clears it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 03:37:17 +08:00
DemonGatanjieuandClaude Opus 5.5 a8b75d33a6 Faster model cards, video posters, and a settings page
Card thumbnails lived in ComfyUI's temp folder, which ComfyUI empties on
every start, so each first visit after a restart remade them all. They now
live in <user>/anomalous/cache/card_thumbnails (still capped at 256 MB).
Listing a model type queues the missing ones for one background thread;
the first screen of cards loads before the rest. A video cover gets a
first-frame poster (PyAV) and fetches nothing until it plays; hover-play
is now the default, as the setting already recommended.

The gear opens a settings page instead of a pop-up with a dialog inside:
look and language, model cards and memory with the thumbnail cache (size,
empty), folders, workflow fingerprints, opening mode and window, help.
Display preferences live behind owner.displayPrefs. Also removes a dead
overlay rule that shared the new page's id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:00:47 +08:00
DemonGatanjieuandClaude Opus 5.5 65ffa602e2 Give voice-over its own page
The Script Director was a drawer behind one of four equal buttons on
Voices, over the character cards, and its name did not say what it does.
It is now Voice-over (配音), a rail page between Voices and Audio
(ui_script_page.js mounts the director); each character card has a
Voice-over button that opens it with that character chosen, and Home's
"Give a character a voice" goes there. Generate is the main button;
pushing, dragging and copying sit under "Into your own workflow", and a
push or drop is one Ctrl+Z step. Plainer words throughout; the Voices
page keeps import, refresh and search.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:19:08 +08:00
DemonGatanjieuandClaude Opus 5.5 4dd183ead4 Make Model Sources a view of the Models page
The Sources chip at the end of the model types now shows, in place of the
cards, where each model is downloaded: for this workflow or all models,
filtered by with / without a link, searchable. Each row's link can be
typed or pasted (any site), found, opened and saved with one button; a
link goes to the model's own information (the editor's download link) and,
for the workflow's models, into the workflow too, as one Ctrl+Z step. The
canvas note and the clipboard list stay. Model Check's "Where to download"
opens the view on this workflow.

The pop-up goes, with its lock-then-edit links and four ways of saving;
ui_model_sources.js (815 lines) splits into the view and
model_source_links.js (data and actions). Old hub CSS and locale keys go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:41:42 +08:00
DemonGatanjieuandClaude Opus 5.5 054cb91b9b style: one palette for every page, from the theme tokens
Pages made at different times used their own greys (slate here, neutral
there) and accents (sky, violet, indigo), and most ignored the Abyssal
Scarlet theme. About 1,850 literal colours in web/styles and in CSS and
inline styles written from JS now use the --amb-* tokens by what they are
for: surfaces, text (new --amb-text-soft and --amb-text-dim), borders (new
--amb-border-strong), the primary button, and one accent (new --amb-link,
tinted with color-mix). Both themes define the new tokens.

Literal colours stay where the colour is the meaning: status, prompt
roles, voice emotions, canvas node colours, shadows and overlays; theme
override rules are untouched. The share-code dialogs move from inline
styles to .anomalous-share-* classes. Stylesheet versions are bumped.

Checked: text contrast on every rail page, Prompt Studio, Prompt Notes,
Model Sources, settings, model detail and editor, share codes, in both
themes; structure check and JS tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:19:55 +08:00
DemonGatanjieuandClaude Opus 5.5 307381c439 feat(shell): every tool opens from its page; the toolbox goes
The rail keeps scan, Model Doctor and Current node (ui_rail_tools.js,
which replaces ui_toolbox.js). The tools the toolbox held now sit where
their things are:

- Workflow share codes (AMB0/AMB1 import / export): the Workflows page's
  top bar, in place of the disabled "import" button.
- Prompt Studio and Prompt Notes: the Material Library's top bar.
- Model Sources: the end of the type chips on Models (library) and
  "where to download" in Model Doctor (the open workflow).

Removed with it: the toolbox popover, its tool catalog and custom-item
hook (no plugin used it), the generic tool dispatch (Home opens the doctor
directly), the tour step, its styles and the toolbox and old "planned
tools" strings. The scan button's tooltip no longer says "wizard".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 06:20:28 +08:00
DemonGatanjieuandClaude Opus 5.5 2358649f03 feat(doctor): Model Doctor checks each opened workflow and says what to do
A bar over the canvas appears when an opened workflow uses models this
computer does not have: how many, and how many are here under another
name or folder (same hash), with one press to put those in. The doctor
page is redone on the scan page's layout: what needs you first, why in
plain words, and a button per row (put in, use a same-size file, pick
one, look it up on Civitai); models that are fine fold away.

- model_check.js: the check (no DOM, changes nothing) and the fixes,
  which call the node's widget hooks so ComfyUI drops its red mark;
  the node picker does the same now.
- Opening the doctor no longer rewrites the workflow by itself.
- Removed: the auto-detect switch (nothing read it), the doctor's own
  deep hash scan and its routes (the resolver hashes same-size files on
  demand; the page points to the scan page), the hash dialog, the old
  resolver in hash_resolver.js, the unused pick-for-node path in
  ui_detail.js, 45 old strings.
- Node Assistant's diagnoseNode and LoRA insertion moved to
  ui_node_assistant.js.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 03:36:41 +08:00
DemonGatanjieuandClaude Opus 5.5 fb21e6c6e9 feat(scan): the scan page, scan runner and scanner changes (completes 5af9b6d)
5af9b6d was committed with only the removal of ui_scan_wizard.js staged;
this adds everything its message describes, so the branch works again:

- ui_scan_page.js / scan_runner.js / 18-scan-page.css: the scan page with
  matched / unmatched / not-scanned counts, one scan button, "look up the
  unmatched models again", progress in the page, Advanced options.
- api/scan_summary.py: GET /anomalous/scan_summary.
- scraper.py: --retry-unmatched (saved hash when the file is unchanged,
  covers kept); display names set in the editor survive scans.
- api/scanner.py: one request-to-switch mapping (_scraper_flags) and one
  cache-clearing helper for both scan routes.
- model_identity.py: sidecar_info / is_unmatched shared by scraper and API.
- Shell wiring (rail, Home, panel lists, close), the provenance switch in
  Settings -> Model settings, locale keys, docs and CHANGELOG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 01:14:54 +08:00
DemonGatanjieuandClaude Opus 5.5 3a221b71d3 feat(models): type chips head the model grid; voice tag buttons say what they copy
The models page starts with a chip per models folder (Checkpoint, LoRA, ...)
and its count. A chip lists the whole folder with its subfolders
(GET /anomalous/type_models); a folder picked in the list narrows the grid
to that folder, shown as a crumb whose x goes back to the whole type. The
chosen type is remembered.

owner.modelScope now says what the grid lists; currentType/PathIdx/Subfolder
stay the folder of the model at hand, set from each card (focusModel), so
the editor, the scanner and "add to canvas" get the right subfolder.

Voice clips: the copy button reads "Copy {tag}" with a tooltip on what
pasting it does, and is gone for characters with only a main voice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 01:09:40 +08:00
DemonGatanjieuandClaude Opus 5.5 376284e647 feat(activity): log what Anomalous changed on the canvas and in files
A new Activity page on the rail (and the home page's recent list) shows, by day,
what the plugin changed. Record only; undo comes later (AD-018).

- api/activity_log.py keeps the newest 500 entries in the ComfyUI user folder.
  A middleware records this plugin's and Anomalous_TTS's write requests after
  they succeed (including the 200 + {"status": "error"} style as failure), from
  one route table; the log never fails the request it records.
- activity_canvas.js: a press inside Anomalous snapshots the canvas; the next
  press or key outside it (or the next press inside) logs the difference, so
  every button, drag and dialog that writes nodes is covered and the user's own
  edits are not. Opening another workflow is logged as that. <html> carries an
  Anomalous class and does not count as the plugin's interface.
- activity_diff.js: pure snapshot and difference; activity_log.js: client and
  wording; ui_activity.js: the page (filters, details, find on canvas, clear)
  and the home list.
- Tests: tests/activity_diff.mjs, tests/test_activity_log.py (local).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:00:28 +08:00
DemonGatanjieuandClaude Opus 5.5 46facb9115 feat(shell): icon rail, per-page list column and a home page
The browser now navigates from one narrow icon rail on the left: Home, Models,
Gallery, Workflows, Materials, then Voices and Audio, then scan, Model Doctor,
Node Assistant and the toolbox, with settings at the bottom. It replaces the
header tabs, the image/audio toggle and the tool bar under the folder list, so
the list column holds only a list and can close without hiding a command.

- ui_shell_rail.js builds the rail; ui_shell_nav.js owns goTo(page), which page
  has a list and whether it is open (remembered per page; below 760 px it starts
  closed and overlays), the page title in the header and the page reopened next
  time. Clicking the current page's icon toggles its list (from a model's detail
  it returns to the grid).
- ui_home.js: task cards and first steps; the first open lands there.
- Window drag/resize moved to ui_shell_frame.js and scan polling to
  ui_scan_watch.js; ui_sidebar.js goes from 864 to 464 lines.
- Workspaces (recipes, notes, materials) keep the rail visible; the list steps
  aside while one is open.
- Removed what the rail replaced: sidebar_actions.js (bottom-bar hover labels and
  tooltip bubble), the domain toggle button, their CSS and unused text keys.
- Spotlight tour: the rail step replaces the header-tabs step, cards open to the
  right of rail items, and the audio tour points at the rail's Audio entry.
- Decision record AD-017; architecture map, frontend and update-guide docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:08:16 +08:00
DemonGatanjieuandClaude Opus 5.5 e341b8a26d feat(audio): sampling parameters in the Script Director, roomier drawer, no audio workflow tab
- Generate section: top_k / top_p / temperature / repetition_penalty folded
  under "Advanced", ranges and defaults read from the node's /object_info;
  "save as this character's default" keeps language, speed and these (only
  values that differ from the node's defaults). The seed is not saved.
- Drawer 560px wide, line cards keep 180px, footer scrolls; for GPT-SoVITS
  the bundle preview is hidden and the canvas buttons are compact.
- The audio domain no longer shows the "Audio Workflows" header tab (the
  recipe library filtered to "audio"); a `hidden` header button now really
  hides despite the header's display !important rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 02:16:07 +08:00
DemonGatanjieuandClaude Opus 5.5 685de2fa15 fix(workspace): keep the header tabs usable, close with Esc, restore after the translator
- The recipe / notes / material workspace (nbPanel) starts below the 48px
  header instead of covering it, so Models / Gallery / Workflows stay
  clickable while it is open.
- Esc closes that workspace like a click beside it, unless one of this
  plugin's dialogs or a ComfyUI dialog is above it or a text field has focus.
- Closing the Prompt Translator shows the browser again when opening it had
  folded the browser away (not after sending text on to the studio).

Found in a browser audit; checked in an isolated ComfyUI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 14:24:52 +08:00
DemonGatanjieuandClaude Opus 5.5 9f45fef85b feat(audio): explicit drop targets, drag hints and an in-app usage guide
- 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
2026-09-24 11:43:31 +00:00
DemonGatanjieu ca32fe09ed Merge main (version in update guide) into feature/audio-voice-studio 2026-09-23 14:53:50 +00:00
DemonGatanjieuandClaude Opus 5.5 eabff31c1c fix(ui): show the version in the update guide instead of the sidebar footer
The footer version sat right under the tool dock and invited misclicks.
The "!" update guide now opens with the current version and a
"Check for updates / switch version" button that closes the guide and
opens the version panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeQEub5
2026-09-23 14:53:49 +00:00
DemonGatanjieu 7b79e2b7d9 Merge main (version number in sidebar footer) into feature/audio-voice-studio 2026-09-23 14:28:16 +00:00
DemonGatanjieuandClaude Opus 5.5 61b828c716 fix(ui): move the version number to the sidebar footer
In the header it pushed the dock and close buttons out of view when the
browser is docked or the display is scaled. It now sits under the tool
dock and hides with the collapsed sidebar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeQEub5
2026-09-23 14:28:16 +00:00
DemonGatanjieuandClaude Opus 5.5 49514025c2 Merge main (v1.58 version panel, docs) into feature/audio-voice-studio
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
2026-09-23 13:50:55 +00:00
DemonGatanjieuandClaude Opus 5.5 e622850349 feat: version panel with manual update check, switching and rollback
- 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
2026-09-23 13:42:58 +00:00
DemonGatanjieuandClaude Opus 5.5 c5eaca1dc4 Merge main (gallery search, model hash index fix) into feature/audio-voice-studio
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
2026-09-23 10:08:10 +00:00
DemonGatanjieuandClaude Opus 5.5 1476fafd8a feat(gallery): search output images by prompt, model, seed and model hash
- 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
2026-09-23 10:00:00 +00:00
DemonGatanjieuandClaude Opus 5.5 66979f698a fix(audio): align voices with ComfyUI-F5-TTS multi-voice layout and repair studio UI
ComfyUI-F5-TTS resolves {happy} to <sample stem>.happy.wav beside the selected
sample, so `Arona_happy.wav` + `{Arona_happy}` could never run. Voices now use
Character.wav (main, {main}) and Character.<emotion>.wav ({emotion}); the
catalog groups a main voice with its variants and marks tags that F5-TTS
cannot resolve (missing main, missing .txt, different format).

- script director: one character per script, untagged lines pinned to {main},
  pushes sample (main voice, node's own combo spelling) and speech together,
  confirms before overwriting and re-checks the node after the dialog
- pure rules (splitting, composing, planning, combo spelling) in audio_script.js
- one module instance per file: drop ?v= imports that duplicated
  ui_audio_gallery/ui_audio_studio state, so studio playback stops the gallery
- all user/file-derived text goes through textContent (no innerHTML)
- studio/sidebar/gallery renders ignore stale responses; errors are shown
- gallery: count badge no longer overwrites the title, paging via "load more",
  deletion errors surfaced, timeupdate instead of a 100ms timer
- sidebar: filter selection updates in place instead of refetching; the header
  tabs, sidebar and domain switch share browser.switchAudioTab
- uploader: createViewScope lifecycle (Esc/overlay/close release listeners and
  object URLs, Esc no longer reaches the parent), 409 -> confirm -> overwrite,
  sends the pre-romanization text as original_text, no hard-coded character
- workflow template: confirm before replacing the canvas, clear message when
  the template file is missing, align sample paths to the node's combo values
- static styles moved from inline JS into 11-audio-studio.css; strings localized

Verified: tests/audio_script_rules.mjs, tests/test_audio_catalog.py (15), a
jsdom walkthrough of studio/gallery/director/uploader with a stubbed app
(outside the repo), JS syntax and import/export link check. Not yet checked in
a live ComfyUI session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeqEub5
2026-09-23 08:02:33 +00:00
DemonGatanjieuandClaude Opus 5.5 3ec4b1de61 chore(checkpoint): save uncommitted Script Director work from previous session
未完成/验证待完成:剧本台(ui_script_director.js、13-script-director.css)、
音频面板返回状态与 locales 文案来自上一轮会话,尚未验证。仅作为恢复点,
后续修复另行提交。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeqEub5
2026-09-23 07:42:41 +00:00
DemonGatanjieu e6758759f2 fix(audio): eliminate browser media caching with timestamp cache-buster and HTTP no-cache headers 2026-09-23 00:10:40 +08:00
DemonGatanjieu 28a24da0c1 feat(audio): complete audio sidebar, audio vault gallery, and domain navigation 2026-09-20 12:35:13 +08:00
DemonGatanjieu 3bb144655a feat(audio): add dual-domain mode switcher and Audio Voice Studio workspace 2026-09-20 11:54:38 +08:00
DemonGatanjieu 3018c17fc7 fix(scan): remove blocking alert and route model scan feedback to progress panel 2026-09-19 14:21:08 +08:00
DemonGatanjieu 1e42033ac0 refactor(sidebar): separate settings toolbox and navigation 2026-09-17 00:53:52 +08:00
DemonGatanjieu 2a53e3edf5 refactor(sidebar): extract scan and support dialogs 2026-09-17 00:45:48 +08:00
DemonGatanjieu 6d25e4aa74 style(toolbox): add 3-row grid height and enhance popover prominence 2026-09-16 21:27:14 +08:00
DemonGatanjieu be96077b3c feat(recipe-detail): default expand parameter nodes & integrate prompt notes into toolbox 2026-09-16 21:01:46 +08:00
DemonGatanjieu 143f076751 fix(ui): remove beta footer text and add popover anchor caret with smooth spring transition 2026-09-16 19:53:30 +08:00
DemonGatanjieu a165921889 style(ui): streamline toolbox modal with frameless compact 40px tiles and clean 216px footprint 2026-09-16 19:46:32 +08:00