Commit Graph
132 Commits
Author SHA1 Message Date
DemonGatanjieuandClaude Opus 5.5 80b42fd834 Revert the merge of "Models that are links: taken as named"
This reverts merge 25f1f6d (feature/next's 851a8cb and this branch's
adaptations of the scan choice, the editor's covers, Tidy's move and
move_into). The owner keeps the cloud-server work in 1.61
(feature/remote-access); 1.60 is back to 4bc559e.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:34:05 +08:00
DemonGatanjieuandClaude Opus 5.5 25f1f6d7b7 Merge feature/next: models that are links, taken as named
1.60's own places that took a model file by name use the new helpers
too: the scan choice (model_file_within), the editor's covers, Tidy's
move (model_reference_within). Opening a folder keeps 1.60's "no file
name opens the folder". move_into tells a rename from a copy by where the
link is (lstat), so Tidy moving a linked model renames the link instead
of copying the model disk's file onto the server. The open-folder test
stubs through path_utils and also refuses "..".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:18:31 +08:00
DemonGatanjieuandClaude Opus 5.5 851a8cb2d5 Models that are links: taken as named, covers and info beside the link
On an AutoDL server every model in the models folder is a link into the
platform's shared, read-only model disk, named like 6b4679... without an
extension. Scans wrote the .info beside the link, but get_metadata
resolved the path and read beside the disk's file: a scanned model
showed as not scanned, under the disk's file name. Delete, edit, open
folder, MCP and saved-workflow lookups resolved the file too, so they
refused it as outside the models folder (or, for a link inside it, would
have acted on the file behind it).

path_utils.model_file_within joins a resolved folder with a bare name
(require_filename, which now refuses "." and ".." too);
model_reference_within resolves the subfolders of a relative path inside
the root, through links as before, and takes the file as named.
get_metadata reads beside the path it is given (abspath). Edits, renames
and deletes act on the link; nothing writes into a model file.

Checked with a link stood in by patching realpath (this computer cannot
make links): the info beside the link is read and the name is the
link's; "..", ".", "a/b" and a relative path leaving the root are refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:12:15 +08:00
DemonGatanjieuandClaude Opus 5.5 4bc559eaa4 Scan page: quick with many models or a network drive; says it is counting
On a cloud server with 1041 models not scanned yet, on the platform's
network model disk, GET /anomalous/scan_summary took 79 s, each time the
page opened, and the page stayed blank meanwhile: it read each new
model's header (for "looks like no drawing model") one after another.

The headers are now read 16 at a time (HEAD_READERS) and through
get_metadata, whose cache keeps each answer until the file changes, so
the page opened again reads none of them and the picker after it finds
them there. Opened afresh, a count slower than 400 ms shows "Counting
your models…" instead of a blank page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 19:39:15 +08:00
DemonGatanjieuandClaude Opus 5.5 afd45520d4 Tidy: "I still use it" for node packs no record can judge
A pack used only through its panels or buttons leaves no record, so the
user can mark it as still in use (POST /anomalous/usage/keep, kept in
user/anomalous/usage_kept.json, only packs ComfyUI loaded). Marked packs
leave the groups for a list of their own; Unmark undoes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:59:50 +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 bf9c46d728 Tidy: a run record, careful judging and a node pack page
ComfyUI keeps no lasting note of what a run used, so AMB now notes each
queued run's node types and model files (on_prompt hook, user/anomalous/
usage_ledger.json). "Not used lately" reads it with the outputs, now
sounds too, and the saved workflows, and judges nothing that came in the
last 30 days; while the record is younger than the group shown, the page
says so.

Node packs get their own page: installed for how long, whether they add
to the page, which packs take what only they make, and a button opening
ComfyUI Manager's node list searched for the pack. Packs without nodes
are listed apart, as nothing can tell whether they are used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:18:37 +08:00
DemonGatanjieuandClaude Opus 5.5 f70d890e61 Tidy: models and node packs not used lately
A Bilibili user asked for a way to clear out models and node packs they
tried once and no longer use, without breaking other workflows.

api/model_usage.py (GET /anomalous/usage/check, this computer only, run
on a press): when each model and node pack was last used, from the PNG
outputs' prompts (image_search's cached records now keep node types) and
the saved ComfyUI workflows, recipes, combos and parameter sets; models
match by path, file name or scanned SHA-256; reading is capped and
nothing is deleted there.

ui_model_usage.js under Tidy's two steps: not used for 30 / 90 days or
never, biggest first, the last output's date, a warning when a saved
workflow still names a model; picked models go to the Recycle Bin. Node
packs are only listed, with a button that opens the installed ComfyUI
Manager's node list (Manager 4 or 3, probed by its own routes; without
one it says so).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:28:44 +08:00
DemonGatanjieu a0f7fa3f9c Merge branch 'feature/next' into feature/model-import
# Conflicts:
#	ARCHITECTURE.md
#	api/__init__.py
#	api/network_check.py
#	web/modules/locales.js
#	web/modules/ui_scan_lists.js
#	web/modules/ui_settings_page.js
2026-10-14 20:13:35 +08:00
DemonGatanjieuandClaude Opus 5.5 6f4347d88d Settings -> Network: a proxy for the plugin, and why Civitai cannot be reached
A Bilibili user's scan said Civitai could not be reached while their
browser reached it through a VPN app: the plugin's urllib requests only
use HTTPS_PROXY or the Windows proxy, not a PAC script or a browser-only
proxy.

net_proxy.py: the proxy address saved in api/config.json (NETWORK_PROXY)
that every request of the plugin goes through (Civitai, Hugging Face,
GitHub, translators), handed to the scan process as HTTP(S)_PROXY; empty
keeps the old behaviour. It also names why a request failed (timeout,
refused, dns, ssl, reset, proxy, http:<code>).

Settings -> Network has the address (SOCKS and malformed ones refused
with what to write) and Test connection, which calls 1.60's
/anomalous/civitai_check (brought here unchanged, now through the proxy
and with the failure's name). A scan that loses Civitai records why
(civitai_error) and the scan page and activity log say it with what to
try.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:10:34 +08:00
DemonGatanjieuandClaude Opus 5.5 103ee6a25d First-run setup on Home: check Civitai, optional key, scan everything, then the tour
New users did not know to scan first. Until anything is scanned, Home shows a card with four
steps and "Set up for me": GET /anomalous/civitai_check (api/network_check.py, local requests
only) says whether Civitai answers and whether a set key is refused; when it does not, the card
offers Retry (with a proxy) or an offline scan. The scan never renames files or refetches,
whatever the scan page was set to; the card follows its progress. Never a popup; "Later" hides it
per browser and Home's "New here?" line brings it back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 22:26:13 +08:00
DemonGatanjieuandClaude Opus 5.5 c59927e701 Read the LoRAs of popular third-party nodes wherever AMB reads a workflow's models
AMB read models only from ordinary drop-downs, so rgthree's Power Lora Loader (rows are
{on, lora, strength} objects) was invisible: Model Check never reported its missing LoRAs.
Now its switched-on rows are Model Check boxes (lora_nodes.js powerLoraRowBoxes: ComfyUI's LoRA
list as choices, a fix changes only the row's LoRA; downloads put files in the same way), saved
fingerprints and a picture's model search read them, the workflow summary lists them, and saved
model references include them and Easy-Use LoRA stack rows (nodeModelValues /
_model_reference_values, mirrored). Only these widely used nodes; ComfyUI's loaders stay the
reference.

recipe_parser.js was over 600 lines: which LoRAs a node loads moves to recipe_loras.js and the
box readers to recipe_widgets.js.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:57:36 +08:00
DemonGatanjieuandClaude Opus 5.5 06461c4f9a Combos put LoRAs in rgthree's Power Lora Loader or Easy-Use's LoRA stack
Stacking many LoRAs made a long chain of Load LoRA nodes. A default combo now says which LoRA
node it is laid out with (data.loraNode: ComfyUI's own chain, rgthree's Power Lora Loader, or
Easy-Use's LoRA stack + Apply LoraStack), chosen under New or in its editor; the third-party ones
are offered only when installed, and a missing one falls back to ComfyUI's own and says so.

Save as combo lost a Power Lora Loader's rows (object values were not stored): they are kept as
the node's rows, made again before the slots are filled, each row's LoRA a slot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:36:08 +08:00
DemonGatanjieu 37d1feebe3 Merge feature/model-import: folder column follows the type, opens folders
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	web/styles.css
2026-10-13 20:28:15 +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 3b157d22e5 Merge feature/model-import: videos in the gallery (PR #21)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	ARCHITECTURE.md
#	web/modules/ui_gallery.js
#	web/modules/ui_gallery_card.js
#	web/styles.css
2026-10-13 14:30:50 +08:00
DemonGatanjieu 208bcfdfdd Merge feature/next: videos in the gallery (PR #21)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	ARCHITECTURE.md
#	docs/architecture/frontend.md
#	web/modules/ui_settings_page.js
2026-10-13 14:29:19 +08:00
DemonGatanjieuandClaude Opus 5.5 4f0fd38dd2 Videos in the gallery: All / Pictures / Videos, formats in Settings, fixes
Follow-up to PR #21:
- The header shows All / Pictures / Videos beside the search (only once the output folder has
  a video) instead of twelve chips; the formats move to Settings -> Gallery, stored as hidden
  so a format added later shows.
- GET /anomalous/gallery_images lists pictures only unless media= says otherwise, so the recipe
  cover picker and the MCP image search are unchanged; hide= drops formats (jpg covers .jpeg);
  has_videos tells the gallery whether to offer the switch. .avi is left out (Chrome cannot
  play it), .avif is a picture format in the filter too.
- The viewer stops the video however it closes (Esc included).
- Video cards have no View parameters, star or right-click menu, and the workbench steps
  through pictures only.
- 图库, not 画廊; the 1.59 CHANGELOG entry credits cocorang and wkdtjs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:27:48 +08:00
DemonGatanjieu c1b7408456 Merge branch 'feature/model-import' into feature/param-compare 2026-10-12 01:42:11 +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 f326018d8d Current node says which set was last put into the node
A line on top of the parameters: the set last put into this node and when,
what changed since (with Put them back), and a "last put in" mark on its
card and column. Remembered in this browser per workflow and node (the
newest 100), forgotten when the receipt undoes it, and dropped from view
once none of the values it changed is left. Without a record, the line says
which saved set the values match or come closest to (at most 3 apart).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:04:35 +08:00
DemonGatanjieuandClaude Opus 5.5 2777d86831 Current node: where saved values came from, their picture, side by side
Each saved set for the selected node is a card with the picture made with
its values (or the kept picture it came from) and a line per source: a
workflow's parameter set (with how many pictures it made, Open shows that
set), a kept picture (See it), or saved here, with the day. Changes are
drawn: numbers as two bars with an arrow, choices as old -> new; what stays
says why; Show all lists every value. Compare opens the whole workflow
against the canvas. With two sets or more, a side-by-side table (picture on
top of each column, changed values marked, Use N under each).

Backend: materials/by_node_type tells each record's origin, kept picture and
preview; parameters/by_node_type gives each set's signature; new GET
/anomalous/parameter_pictures counts the pictures of many sets in one pass,
reading each picture's signature once per file version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:41:23 +08:00
DemonGatanjieu 20ac73a46f Merge branch 'feature/model-import' into feature/param-compare 2026-10-11 16:26:20 +08:00
DemonGatanjieuandClaude Opus 5.5 4f46676452 Model editor redone, with a source link; inferred information says so
The editor is rebuilt (it was inline styles everywhere): the cover large
with its choices under it (the current one, Civitai's own when the user
replaced it, the newest pictures, upload, the whole gallery), Name, Source
link and Notes with a word each, Reset / Cancel / Save at the foot. Nothing
is written before Save; fields left as they were are not sent. The source
link (asked for in the "not found" list's hint, but nowhere to type it) is
kept in the user layer; update_metadata refuses one that is no http(s)
address. GET /anomalous/model_covers tells the editor Civitai's kept cover.

A model Civitai does not know: its card reads "推断 <base>", its details
open with a note on what was read from the file and a button to add a name
and link (instead of the English placeholder description), and the scan
page says an online scan infers what Civitai does not find.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:26:14 +08:00
DemonGatanjieu 1ab5d75ebe Merge branch 'feature/model-import' into feature/param-compare 2026-10-11 15:53:39 +08:00
DemonGatanjieuandClaude Opus 5.5 58d5432014 Scan page: covers instead of the ring
The scan card opens on two rows of the models' covers, newest first, with an
empty dashed frame for each model not scanned yet (they pulse while a scan
runs): what a scan does, in a picture. The ring, which said the same as the
line under it and the state bar, is gone; narrow, nothing sits alone above
the card any more. The scan summary carries up to 48 covers of scanned models
(components left out) for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:53:33 +08:00
DemonGatanjieu 326a96c4d3 Merge branch 'feature/model-import' into feature/param-compare
# Conflicts:
#	web/styles.css
2026-10-11 13:27:46 +08:00
DemonGatanjieuandClaude Opus 5.5 22edc20d0f Scan page: pick beside the button, settings in place, components apart
"Pick models to scan" sits beside the scan button; the picks are named
under it and the button scans them, "clear" goes back to everything, so
the all/picked switch is gone. Under the button the page says what this
scan will do, each line with how many of its models are components.

The settings card (ui_scan_settings.js, holding the scan options and the
Civitai key prompt) unfolds in place instead of opening its own page.

The summary counts and lists models in component folders (VAE, text
encoders, CLIP, CLIP Vision, upscalers) apart. The counts at the top and
the not found / not scanned lists leave them out; a card and a list of
their own say that many are not on Civitai and that this is no fault.
The not found list looks up again just the models it shows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:27:24 +08:00
DemonGatanjieu 75780601be Merge branch 'feature/model-import' into feature/param-compare
# Conflicts:
#	web/styles.css
2026-10-11 12:50:35 +08:00
DemonGatanjieuandClaude Opus 5.5 2af526c6b9 Scan settings say what a scan will do; a new model picker
"All models" now lists, from the scan summary, how many models a scan
looks up, keeps, leaves for "look up again" and leaves out, following
the offline and fetch-again switches. "Only ones I pick" names the picks
with their size and says when found ones would only be read again.

The picker (ui_scan_picker.js, GET /anomalous/scan_pickable) lists the
.safetensors files a scan reads with the scan page's states, folder,
base model and size, as a list or covers, narrowed by folder, state,
search and picked-only; "pick these" picks what is shown, shift-click a
run. Picks go to the scan as targets. The old inline-styled selector and
its batch_select route are gone; setWidgetValuePath keeps its own file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:50:20 +08:00
DemonGatanjieuandClaude Opus 5.5 d0880b9fc2 Merge feature/model-import: models you never want scanned
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:39:34 +08:00
DemonGatanjieuandClaude Opus 5.5 908ad72ec2 Models you never want scanned: asked, marked, left out; not on Civitai no longer warns
- The scan summary marks new models whose safetensors header reads but names no drawing model
  kind (a voice model such as F5-TTS) as not_drawing; the scan page asks: don't scan them,
  scan them, or see each. The choice lives in <model>.anomalous.json ("scan": "skip" / "scan",
  model_identity.scan_choice), saved by POST /anomalous/scan_choice (api/scan_choice.py, this
  computer only, at most 2000 models, only readable .safetensors layers).
- "skip": a scan of a whole folder leaves the model out (picked by hand it is still scanned),
  the summary counts it apart (excluded) with its own list to change it back, the card and the
  details say "不扫描"; the details have the same button.
- The unmatched count warns only for damaged files or lookups still to do; not-found rows say
  the fingerprint is kept for repairing workflows.
- model_kind.inspect_file now gives format None when the header cannot be read, as its text said.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:38:29 +08:00
DemonGatanjieuandClaude Opus 5.5 4c83b14657 Merge feature/model-import: damaged model files are named as such
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 03:36:18 +08:00
DemonGatanjieuandClaude Opus 5.5 45353ffea1 Scans name damaged model files instead of calling them unknown
A model Civitai has no record of now has its safetensors header checked (model_identity.
safetensors_damage: too short, header longer than the file, not JSON, or a tensor ending past
the file's end; only the header is read). Such files get the unmatched reason "damaged": a red
badge on the card, a line in the details, a warning on the scan page (the summary counts them)
and first place in the unmatched list, with advice to download the model again.

Tests: header cases, a scan telling a damaged file from a whole one; the scan report fixtures
are whole safetensors files now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 03:35:23 +08:00
DemonGatanjieuandClaude Opus 5.5 ca02bdb385 Merge feature/next: damaged model files are named as such
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 03:35:23 +08:00
DemonGatanjieuandClaude Opus 5.5 9fdbaa847b Focus stars answer at once and save light
A star turns at once with a little bounce, the value fades in (one unmarked fades out), a failed save turns it back; quick presses queue instead of being refused. Focus values save alone through POST /anomalous/recipe_focus (this computer only, size-capped read, only focusParams written, no version), instead of a full recipe update that kept a version and re-read every model each time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:11:31 +08:00
DemonGatanjieuandClaude Opus 5.5 227063cce3 Merge feature/model-import: offline-found models keep their name
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:05:19 +08:00
DemonGatanjieuandClaude Opus 5.5 b60756c06c Test: models found offline keep their name across scans
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:04:23 +08:00
DemonGatanjieuandClaude Opus 5.5 ff82d489a5 Merge feature/next: offline-found models keep their name
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:04:23 +08:00
DemonGatanjieuandClaude Opus 5.5 b323d82220 Focus values: mark what matters most in a workflow
- Every node value under the details' "every node's values" has a star; marked values show at
  the top of the workflow's own values and of each set as tiles (node, value, a note, and on a
  set the default when it differs). Set rows list them first; the comparison window leads its
  key values with them and their note.
- Kept in the recipe's params as focusParams [{node, type, widget, note}]; the server refuses
  any other shape (at most 12, short strings, notes up to 120 characters). Kept while the node
  of that id and type is there, also when the workflow is updated from the canvas.
- compareParams' isKey now also receives the node ids, so a mark holds for one node only.
- Tests: tests/recipe_focus.mjs, focus values in test_recipe_roundtrip.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 01:03:40 +08:00
DemonGatanjieuandClaude Opus 5.5 5c0448f009 Key parameters and parameter sets in view
Star a value in the comparison (key_params.js: node type + widget name, a hidden ComfyUI
setting) and it stays at the top of every comparison; equal values can be listed to be
starred. Recipe cards show 参数方案 N (sets unlike the recipe, from the new read-only
GET /anomalous/parameters/signatures) and open the Parameters tab; each set there shows
its key values, how many values differ from the recipe, and ⇄ to compare
(ui_param_set_keys.js). The window also compares saved workflows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:56:14 +08:00
DemonGatanjieuandClaude Opus 5.5 ffe0cb4f40 Compare: say which side is which
A and B each get their own colour, shown on the side cards, the column heads and every
text line. Prompts list the tags only A has and only B has (each once) instead of
removed/added; long texts take one line per side with the differing part marked; values
wrap whole instead of ending in an ellipsis.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:37:01 +08:00
DemonGatanjieuandClaude Opus 5.5 b920a711d1 Compare parameters: two pictures, or a picture and the canvas
The gallery card's ⇄ picks a picture, a second picture's ⇄ or Compare with the canvas
completes the pair; the picture details' ⇄ compares with the canvas. The window says
whether both use the same nodes and lists only the values that differ (prompts as tags
removed and added with their role, seeds folded), pairing nodes by id, then by a type
each side has once. Ticked picture values go onto the canvas as one Ctrl+Z step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:26:09 +08:00
DemonGatanjieuandClaude Opus 5.5 cf117381a4 Merge feature/next: keeping a picture no longer changes the canvas
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:20:43 +08:00
DemonGatanjieuandClaude Opus 5.5 a60c33fbf4 Merge main: keeping a picture no longer changes the canvas
Adds tests/detached_graph.mjs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:20:39 +08:00
DemonGatanjieuandClaude Opus 5.5 81fcc6ebc4 Merge feature/next: picker scroll, combo save burst, activity long-text fixes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:36:15 +08:00
DemonGatanjieuandClaude Opus 5.5 99576e60bd Fix picker jumping to the top, combo saved per tag, unreadable long-text activity
- Current node's model picker redrew the whole grid to mark the chosen card, so
  choosing one further down scrolled back to the top. The cards are repainted in
  place (paintCard) instead.
- The classic combo editor saved when its bilingual tags were shown and again for
  each tag's translation as it arrived: a long prompt wrote the combo dozens of
  times in a second (34 note_save entries in one user's log). Rendering no longer
  saves and the translations share one save half a second after the last. Its
  prompt placeholder moves into locales.js (no inline language branch).
- Activity values are capped at 400 characters from the start, so an edit late in
  a long prompt logged identical before and after. A long before/after pair is now
  cut around its first difference (test included).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:36:15 +08:00
Claude ca2cdecf7e fix(models): import upload and Tidy moves only from this computer
PUT /anomalous/import/upload and POST /anomalous/placement/move wrote
into the model folders for any caller, while place and identify already
answered only the computer ComfyUI runs on. With ComfyUI started with
--listen, another device could upload model files or move models
between folders. Both now check mcp_server._is_local first and answer
403 not_local, which the import and Tidy screens already show.

Tests drive both routes through a proxy header and check nothing was
written or moved; they fail without the check. Full suite: structure
check, every tests/*.mjs and 234 Python tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018P2T2R7TFbJsc3C9maCD8B
2026-10-08 20:35:57 +00:00
Claude 1b8839d2c6 Merge feature/next: Anomalous_TTS interface 13, no local paths
Brings stage 2 into stage 3: the gallery drag fix and the change that
follows Anomalous_TTS interface 13. No conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018P2T2R7TFbJsc3C9maCD8B
2026-10-08 20:23:55 +00:00