feat(studio): collapsible child cards — core-owned card fold (G1 R-B) - #396
Draft
Yona-Appletree wants to merge 2 commits into
Draft
feat(studio): collapsible child cards — core-owned card fold (G1 R-B)#396Yona-Appletree wants to merge 2 commits into
Yona-Appletree wants to merge 2 commits into
Conversation
… SetCollapsed (G1 R-B) The whole-card collapse was a web-local use_signal seeded from a controller bit nothing ever wrote: amnesia across re-renders, invisible to e2e, and the sim-lens subscription gate that read it was documented as 'becomes real when the UI state audit moves live collapse state into core'. This is that move. - NodeCardUiState gains collapsed (default false) and NodeUiOp gains SetCollapsed, keyed by node address like every drawer bit. - node_subscribes_products' sim arm reads the card-UI store, ancestors included: collapsing a card folds its whole child column away, so a hidden card must not keep streaming just because its own bit is clear. Explicit subscribe intent still wins; the device arm (focused-only) is untouched. - NodeControllerState.collapsed and UiNodeView.collapsed retire — the DTO carries the fold in card_ui, and ui_nodes() now overlays the store exactly like editor_view(). - e2e: fold rides the action seam, survives a tree resync, never touches the selection; sim-lens subscriptions drop on fold (self and ancestor) and return on expand. Co-Authored-By: Claude Fable 5 <[email protected]>
…tory NodePane's collapse toggle now dispatches NodeUiOp::SetCollapsed through the action seam instead of flipping a view-local signal — the same wiring as every drawer, so the fold persists per node address, child cards inherit it through into_node_view, and folding a card stops its sim previews streaming. PanelWalk learns the SetCollapsed op so the rail stays live in the walkable stories (root card and children alike), and the grouped pattern column gains a folded story: everything but fire collapsed to its header, judging whether a mostly-folded column still reads as the same grammar. Co-Authored-By: Claude Fable 5 <[email protected]>
Yona-Appletree
force-pushed
the
claude/collapsible-child-cards-r-b
branch
from
August 8, 2026 07:43
5084a70 to
c321e25
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #380 (
claude/jovial-knuth-b627fc). Implements the R-B ruling from the module-authoring G1 gate (2026-08-07): collapsing child cards, scoped out of #380 but wanted "soon" now that pattern projects ship rigs (strip + matrix + outputs + effect module) and the child column runs long.What changed
The fold moves into core. It was a web-local
use_signalseeded fromNodeControllerState.collapsed— a bit nothing in production ever wrote. So the fold died with the component instance (amnesia across re-renders and remounts), was unreachable by e2e, and the sim-lens subscription gate that read it carried a comment saying it "becomes real when the UI state audit moves live collapse state into core". This is that move.NodeCardUiStategainscollapsed(defaultfalse) andNodeUiOpgainsSetCollapsed, keyed by node address path — the same convention as every drawer bit, so child cards inherit it throughinto_node_viewfor free.NodeControllerState.collapsedandUiNodeView.collapsedretire: one source of truth, carried oncard_ui.ui_nodes()now overlays the card-UI store exactly likeeditor_view()already did.Collapse nodebutton from the root card's header (PaneCollapse/StudioPane) — every card already rendered throughNodePane, so they all get it by construction.The subscription consequence, verified.
node_subscribes_products' sim arm now reads the real fold state — ancestors included. Collapsing a card folds its whole child column away, so a hidden card must not keep streaming just because its own bit is clear. Folded cards stop streaming previews, which is the desirable behaviour the ruling asked us to confirm. ExplicitSubscribed/Unsubscribedintent still wins over the fold, and the device arm (focused-only) is untouched.Selection is untouched. Collapsing never focuses, unfocuses, or otherwise moves the one-live-surface selection — asserted directly.
Tests
node_card_ui_state: default is expanded;SetCollapsedround-trips; the card fold is its own bit (expanding the card leaves drawers where the user left them); every op names its node.collapsing_a_child_card_rides_the_seam_and_never_touches_the_selection: fold rides the action seam, is keyed per address, survives a tree resync, leaves selection alone.collapsed_cards_stop_streaming_under_the_sim_lens: subscriptions drop on fold, return on expand, drop again when an ancestor folds, and explicit subscribe intent still wins.Stories
child_grouping_folded— the grouped pattern column with everything butfirefolded. Verified rendering locally: folded cards keep the full identity row (chevron, name, export chip, kind label, ⓘ), and both the sageexportsheader and therigheader still place each folded card, so the ships/stays-home split survives the fold.PanelWalklearnedSetCollapsed, so the rail is genuinely clickable in the walkable stories rather than a static prop.Baselines are not committed here — they are CI-canonical (
validate-storiesauto-commits; macOS rendering differs from the pinned CI environment).Validation
just check test— green, exit 0, 7270 tests passed, no clippy/fmt diffs. All four new tests confirmed executing by name.One caveat worth recording: the first gate run reported success while its output ended in
error: Recipe fmt-check failed, and a later run failed with what looked like dependency breakage (extern location for futures_core does not exist) that was actually build-cache corruption left by an out-of-disk build — the dev machine's volume filled up (3.6 TiB used, unrelated to this repo; worktree caches total only 11 GB). Cleared by wiping this workspace's cache shard and rebuilding builtins. The green run above is from that clean cache.🤖 Generated with Claude Code