Files
DumiFlex-ComfyUI-Wildcard-P…/wp_api
DumiFlex 2c8d94bb9e feat(api,spa): phase b+c — unified push-to-library with bundle propagation
Lands the broader save-to-library rethink across the server + extension
surfaces. Closes Bugs 1-5 from the 2026-05-19 live QA report; Bug 6
(payload validation) was already plugged by the previous commit.

API contract (Phase B):

- PUT /wp/api/modules/{id} now accepts {payload, name, description,
  tags, propagate_to_bundles} and persists all of them in one
  transaction. Returns bundles_updated[] so the caller can surface
  "this save touched N bundles" feedback.
- PUT /wp/api/modules/{id}/payload kept as a backwards-compat alias
  that mirrors the same body shape (payload + meta + propagate). The
  older route silently dropped meta; now it routes through the same
  helpers as the canonical PUT.
- Bundle propagation: when a module write happens, every bundle whose
  children[].id matches the updated module gets its frozen child
  snapshot rewritten in lockstep (payload + meta) and its
  payload_hash recomputed. Atomic via shared db_session.
- GET /wp/api/bundles?contains_module=<id> filters the list to bundles
  that reference that module — drives the modal's "this save affects
  N bundles" preview.
- 7 new pytest cases in test_save_to_library_unified.py covering meta
  persistence on both PUT routes, opt-in/opt-out propagation, and the
  bundles filter.

SPA (Phase C):

- New PushToLibraryModal.vue. Owns editable name/description/tags +
  payload preview + bundles-affected list + propagate checkbox. Two
  buttons: Save as new entry (always available — POST /modules) and
  Update existing (greyed when payload_hash is empty). Replaces the
  five per-kind onXxxSaveToLibraryClick handlers + their five copies
  of the same PUT body that lived in ModuleEditModal.
- ContextWidget right-click menu entry becomes Push to library and
  routes to the same modal. Predicate relaxed from
  isMissingFromLibrary(m) to !!m.payload, so inline-created modules
  (no payload_hash) can finally reach the library — they get the
  fork-only path in the modal.
- The five instance modals canSaveToLibrary computeds drop the
  isLibraryTracked + isModified gate. Button is visible whenever
  there is a payload; the modal decides what to do with it. Tests
  updated to match the new contract.
- 8 new vitest cases in PushToLibraryModal.test.ts covering field
  seeding, button disabling, PUT/POST request shape, bundle list
  rendering, and the propagate opt-out round-trip.
- Legacy saveToLibrary(m) function in ContextWidget is gone (no
  callers since the menu predicate change). Its bypass POST to
  import-from-workflow lost the meta-editing path the new modal
  exposes, so deletion is net positive.

Size note: total extension bundle is now 306254 / 307200 bytes
gzipped — 946 bytes of headroom on the size gate. Future feature
work touching this surface needs to factor in budget.

Live QA pending: extension code needs ComfyUI restart to reload.
2026-05-19 18:12:16 +03:00
..