Conversation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Thanks for working on this. I like the direction of the source tree and the separate preview/edit area. I checked commit The UI cases below were reproduced using the actual rendering/grouping functions from this commit with a small mocked DOM and synthetic catalogs. These are code-level reproductions, not a full live-ComfyUI browser test. No existing project was modified. 1. A child assigned to another folder is displayed under its parent's folderRelevant code: Reproduction:
The crop is displayed beneath the original in
Please keep folder membership authoritative for placement and counts. A child whose parent belongs to another folder should remain visible as a root item in its own folder. The related-edits strip can still show its relationship to the original; that relationship should not override where the user put it. 2. Role tabs can hide matching children and show nonmatching onesRelevant code: full-catalog lineage lookup Reproduction:
The parent is filtered out, but the child is also skipped because the parent still exists in the unfiltered catalog. The result is an empty browser despite having a matching semantic asset. Switching to Images shows the semantic child beneath the image parent instead. Please build the main tree relative to the active filter as well as folder membership. A matching child whose parent is outside that visible scope needs its own visible entry. Expanding a parent should not bypass the active role filter. This filtering rule can be separate from the intentionally cross-role related-assets strip. 3. Version stacks disappear when their parent is deletedRelevant code: Reproduction:
Both remaining assets disappear from the main tree. They are still in the catalog; this is a display problem, not deletion of their files.
Please fall back to displaying the stack at the appropriate visible root when its attachment point is absent or outside the current scope. A stale parent reference must not make surviving assets inaccessible. 4. Version naming needs a compatibility policy, and names alone are not enough to identify a familyBackend naming / frontend grouping
Please preserve existing tags and prompt references. Explicit family/version metadata would be safer than inferring identity entirely from a naming convention. For old assets where the relationship cannot be established reliably, keeping them separate and accessible is preferable to guessing or renaming them automatically. Please document how existing captured takes are handled and test mixed old/new catalogs. To be clear: the PR does not rename existing tags, and the three failing capture tests are not evidence of broken prompt resolution. They currently assert the old naming contract. Those expectations need to be reconciled with the chosen behavior, while retaining their collision, concurrency, and capture-integrity checks. 5. Please separate the unrelated motion-decoding changeRelevant code: This PR also changes early-EOF handling from a bounded last-frame display interval to repeating the final frame through the entire remaining request. I tested the decoder with a synthetic 12-frame, 24 fps video and a requested window of Please remove this from the carousel PR and discuss it separately, with an explicit policy and tests for short references versus unexpected early EOF. This reproduction calls the decoder directly; it does not establish that every higher-level preflight path allows such a request. Also please remove the fork-specific status section added to the upstream README. Verification and requested regression coverageCurrent results in the isolated PR checkout:
Please add regression tests for moving a child between folders, a folder containing only derived children, parent/child roles across tabs, missing/deleted family parents, mixed legacy/new capture tags, and unrelated assets with version-looking names. Include a save/reload check so placement and visibility remain correct after reopening a workflow. The layout can stay; the important part is that organizing or filtering assets must not make them appear in the wrong place or disappear. A small, scope-aware grouping fix with tests is enough here—we do not need a storage migration or automatic project rewrite. |
isLineageRoot() only considered parent_asset_id, so a crop moved to a different folder than its parent still rendered nested under it, and the crop's real folder showed as empty with a hardcoded zero count. isLineageRoot() and collectChildItems() now also check that a child shares its parent's folder_id before treating it as nested; a folder mismatch surfaces the child as its own root item in its real folder instead. The crop/edit relationship itself is unaffected and still shown in the bottom detail row. Reported by ethanfel on PR ethanfel#71. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
assetFamilies() grouped purely by tag text, so an image and an unrelated audio reference sharing a coincidental -vN tag pattern (e.g. @hero and @hero-v1) were treated as versions of each other. Groups (and looks them up) by tag *and* kind together via a new familyGroupKey(), so a family can never mix images/video/audio. No change to the "no migration" behavior for older bare-digit capture tags (@char_bob, @char_bob1, @char_bob2) — they intentionally stay separate and untouched, since a naming pattern alone can't prove two old assets are actually related. Documented that explicitly in docs/PROJECT_ASSETS.md. Also updates tests/_review_frame_capture_test.py's three assertions that hard-coded the old bare-digit suffix contract to expect -vN instead; their actual purpose (collision handling, concurrent-capture uniqueness, disabled-asset non-collision) is unchanged, only the literal expected tag strings were stale. One assertion's input was also changed to request the exact prior "-v1" tag rather than the old scheme's coincidental "hero1", so it still exercises a genuine collision against a "-vN" tag. Reported by ethanfel on PR ethanfel#71. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rees Reshapes the Asset Carousel DOM widget into a left source-tree column (crops/edits nested via parent_asset_id, tag-family "-vN" versions grouped and nested at their correct attach point) alongside a preview+editor stage, with a bottom panel showing the selected asset's combined crop and version relationships. Also gives the node an actual horizontal resize floor (ComfyUI's DOM widgets only report one for height by default) and switches Review Gate's capture-family tag suffix from a bare digit to "-vN" to avoid false-positive matches like @vehicle-van or @char-venessa. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
isLineageRoot() only considered parent_asset_id, so a crop moved to a different folder than its parent still rendered nested under it, and the crop's real folder showed as empty with a hardcoded zero count. isLineageRoot() and collectChildItems() now also check that a child shares its parent's folder_id before treating it as nested; a folder mismatch surfaces the child as its own root item in its real folder instead. The crop/edit relationship itself is unaffected and still shown in the bottom detail row. Reported by ethanfel on PR ethanfel#71. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
assetFamilies() grouped purely by tag text, so an image and an unrelated audio reference sharing a coincidental -vN tag pattern (e.g. @hero and @hero-v1) were treated as versions of each other. Groups (and looks them up) by tag *and* kind together via a new familyGroupKey(), so a family can never mix images/video/audio. No change to the "no migration" behavior for older bare-digit capture tags (@char_bob, @char_bob1, @char_bob2) — they intentionally stay separate and untouched, since a naming pattern alone can't prove two old assets are actually related. Documented that explicitly in docs/PROJECT_ASSETS.md. Also updates tests/_review_frame_capture_test.py's three assertions that hard-coded the old bare-digit suffix contract to expect -vN instead; their actual purpose (collision handling, concurrent-capture uniqueness, disabled-asset non-collision) is unchanged, only the literal expected tag strings were stale. One assertion's input was also changed to request the exact prior "-v1" tag rather than the old scheme's coincidental "hero1", so it still exercises a genuine collision against a "-vN" tag. Reported by ethanfel on PR ethanfel#71. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
84fcc3f to
291e433
Compare
The tree/family placement logic (isLineageRoot, assetFamilies, familyAttachPoint, collectChildItems, and the whole grouping decision in renderCarousel) lived only as closures nested inside mount(node), so nothing outside a live ComfyUI widget could exercise it directly — this is exactly why several of the placement bugs fixed earlier in this PR went unnoticed until manual testing. Moves all of it, unchanged in behavior, into a new web/h3_project_asset_carousel_core.mjs following this codebase's existing "_core.mjs" pattern (h3_dom_wheel.mjs, etc.): plain exported functions taking explicit catalog data, no `state`/DOM dependency. renderCarousel() now calls one new pure function, computeCarouselPlacement(), which returns a plain placement plan (which assets are plain root items, which collapse into a family stack and where it attaches, which are grouped under a folder), and just walks that plan to build DOM — no behavior change, confirmed by the full test suite passing identically before and after. Adds tests/_project_asset_carousel_placement_test.mjs with direct, DOM-free regression coverage for every scenario raised in review: moving a child between folders, a folder containing only derived children, parent/child roles split across tabs, a deleted/missing family parent, mixed legacy (hero1/hero2) and new (-vN) capture tags coexisting without cross-grouping, unrelated same-tag different-kind assets, and a JSON save/reload round-trip producing identical placement. Reported by ethanfel on PR ethanfel#71. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Update: folder placement, tab scoping, and naming-policy fixesAddressed the review feedback with four targeted fixes plus a testability 1. Folder placement is now authoritative over crop lineage
2. Tree/tab scoping fixed at the root causeThe tree's 4. Naming convention kept as-is; explicit media-kind guard addedAgreed with the review's core point that a naming pattern alone can't prove What was a real bug, fixed separately: 3 & 5, briefly
On the regression-coverage requestAdded One thing I'm intentionally not doing: adding Chrome/headless-browser-based |
|
Thanks, this is much closer. I checked One folder-placement case still slips through when the children form a version stack:
Expected: the two unfiled assets appear as a top-level stack outside Actual: the stack is nested under the source inside I reproduced this with the actual Please apply the same folder/scope rule to stack attachment and fall back to a visible root when the parent is in another folder. Don't just filter the stack out after hoisting, as that would hide it instead. A regression comparing the single-child case with the two-member stack, including a JSON save/reload, should cover this without requiring Chrome. The existing JS tests pass here, including the browser tests on my machine; the asset-store and all 12 capture tests also pass. This is a remaining display-placement bug, not deletion or movement of the underlying files. I used synthetic catalogs and did not modify an existing project. |
|
that last issue or rather two issues are chrome based, and I'm trying to restrict how much google has access to my stuff. That includes preventing playwright from using chromium modules. edit: I tried to have claude come up something to test for the issue but it still seems majority of it is chrome based. Otherwise I've included some additional testing to try and validate without having chromium module. |
…hildren familyAttachPoint() nested a version-family stack under its crop-parent whenever the parent existed, without checking that the members actually share the parent's folder. A source in one folder with unfiled -vN version children hoisted the stack out of the plain per-child folder path but then attached it back under the parent anyway, leaving it invisible: not in the parent's folder listing (folder rule excludes it) and not surfaced at the root either. Fall back to the root attach point when any member's folder_id differs from the parent's, matching the folder-authority rule already applied to plain children in isLineageRoot/collectChildItems. Adds a regression comparing the single-child case (unaffected) against the two-member stack case, plus a save/reload round-trip.
…g carousel fixes Extract the wheel-forwarding decision in bindNodeWheel into a pure resolveWheelRouting() (h3_dom_wheel_core.mjs), mirroring the DOM-free core pattern already used for the carousel placement logic. Behavior is unchanged; this only lets the routing matrix (inactive vs. active panel, already-handled gestures, read-only override) run under plain Node without needing the Chrome binary the existing _dom_wheel_browser_test.mjs requires for verifying real native-scroll physics.
Summary
Reshapes the Project Asset Carousel's DOM widget from a flat top-controls-plus-card-strip layout into a source-tree layout that surfaces two kinds of asset relationships that previously had no visual representation: crop/edit lineage and tag-based version families.
Layout
Crop/edit lineage tree
Cropping or editing an asset already created a new catalog entry carrying a
parent_asset_idback-reference (register_derived_image()inproject_assets.py) — a backward pointer only, with no forward index anywhere. The left column now builds that forward index client-side (lineageChildren()) and nests a source asset's crops/edits under it with an expand/collapse toggle, instead of listing every asset as a flat strip.Tag-family version stacking
Adds recognition of the
-v<N>tag suffix (@char_bob,@char_bob-v1,@char_bob-v2, ...) as a "version family":Backend:
-v<N>capture-tag suffixReview Gate's frame-capture flow already had a "re-use the same tag as an updated take" behavior (
_capture_family_tag()inproject_assets.py) for exactly this use case, but it used a bare trailing digit (@char_bob1,@char_bob2). Switched to-v<N>and made the ordinal scan match the suffix pattern exactly rather than viastartswith, so a tag that merely ends in a number or the letterv—@vehicle-van,@char-venessa,@char_bob_house— can no longer be misread as a version of an unrelated family. This only affects newly-created capture tags; no migration of existing data.Other fixes bundled in
minWidth: 0from its defaultcomputeLayoutSize()— overrode it directly on this widget to report an actual floor derived from the layout's column minimums.Testing
node --test tests/*.mjs— full JS suite passes (53 tests on this branch; literal-string assertions intests/_project_asset_manager_js_test.mjsetc. are unaffected).PYTHONPATH=. python tests/_project_asset_store_unit_test.py/tests/_asset_store_unit_test.py— pass, including new coverage for the-v<N>capture-tag scheme and a regression guard against the@vehicle-van/@char_bob_housefalse-match case.Known limitations
-v<N>suffix match) — it can't detect a typo (@human_herm-v1vs@human-herm-v1won't match) and has no relation to the underlying asset content.