- The region panel is now titled "Overview" (with a tooltip describing the gestures); README updated.
- Overview rows: Ctrl/Cmd-click toggles a row in/out of the selection; Shift-click selects the
range from the anchor to the clicked row in displayed (tree) order. Plain click still single-selects
and sets the range anchor. Selection is shared with the canvas, so multi-selects show + move there.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adversarial review of the hierarchy change found three real bugs + polish:
- Major: keyboard Delete (removeSelected) dropped a deleted parent's children to ROOT, while the
per-row ✕ promoted them to the grandparent. removeSelected now promotes orphans to the nearest
surviving ancestor (skipping co-deleted parents), matching the ✕ behavior.
- Major: a cycle or self-parent (possible via a hand-edited/imported save) silently hid regions
from the tree — ensureParentsValid only nulled MISSING refs. It now also nulls self-parents and
breaks cycles by cutting the back-edge, so every box stays reachable from a root.
- Major: dragging a parent tore apart a locked sub-branch — a locked intermediate box stayed put
but its children still moved. Move-group build now skips locked boxes AND their whole subtree.
- Minor: snap-then-clamp could overflow the canvas by a grid cell (now reachable via single-parent
drag); snap first, clamp last so the clamp always wins.
- Minor: setParent now returns false when the parent is unchanged (no churn commit), and the drop
cue skips the box's current parent.
- Minor: clear any prior _exDragCleanup before a new row drag (no leaked listeners on overlap);
clear the click-suppress flag on consume.
JS parses clean as an ES module.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Editor-only parent/child hierarchy on top of the stable ids — never reaches the exported caption
(Python ignores unknown box fields).
- Data: each box gets an optional `parent` (another box's id). Helpers: boxById, isAncestor,
descendantIds, setParent (rejects self/missing/cycles), ensureParentsValid (drops dangling refs
to root on delete/import; runs in serialize()).
- Move propagation: dragging a box on the canvas moves its whole subtree (children follow). Resize
affects only explicitly-selected boxes — children don't scale. Locked descendants stay put.
- Object Explorer is now a tree: indentation by depth, per-parent ▶/▼ collapse (persists on the box).
Drag a row ONTO another to nest it (cycle-guarded, live drop highlight); drop on the "Regions"
header to send it back to root. Trailing-click after a reparent is suppressed.
- Delete promotes a box's children to its parent (no surprise subtree wipe).
- Paste/duplicate clear parent (become roots) so clones never carry stale parent ids.
- Z-order stays independent of hierarchy (still reorder via the right-click region menu).
JS parses clean as an ES module.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adversarial review of the Phase 1 change surfaced one real bug + polish:
- Major: drag-reorder called commit() -> renderExplorer(), which cleared the list and destroyed
the row whose _dragged guard was just set, so the trailing click wasn't suppressed and fired a
spurious re-select. Drag-end now repaints in place (serialize/renderPanel/drawCanvas/tokens)
without rebuilding the list — mirrors the right-click region menu.
- Leaked listeners: explorer drag binds document-level pointer listeners; store _exDragCleanup and
call it from onRemoved so a mid-drag node deletion can't leak them.
- Resizer stayed draggable while collapsed (silently mutating explorerW); hide it when collapsed.
(Also reordered the init call so applyExplorerCollapsed never references exRsz before it exists.)
- scrollIntoView fired on every commit; now only scrolls when the active row is actually off-view
and the rail isn't collapsed.
- startPlacing (duplicate from the list) now refreshes the explorer immediately.
- Hardened .ai2go-ideo-cv with explicit min-width:0; widened resizer max-clamp by the divider width.
JS parses clean as an ES module.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Object Explorer: a persistent, collapsible rail left of the canvas listing every region
(number, color swatch, label, lock, duplicate, delete, drag-reorder). Click a row to select
a region — two-way synced with the canvas — so regions can be picked and edited from the list
without dragging them by accident. Width + collapsed state persist in node.properties.
Stable IDs: each box gets a makeUUID() id (stamped in serialize via ensureIds; regenerated on
paste/duplicate). Editor-only groundwork for parenting — Python ignores unknown box fields, so
the id never reaches the exported caption.
JS parses clean as an ES module.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Set the GitHub repository URL (pyproject + README clone) and the publish
workflow's owner gate to Little-God1983.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port the Ideogram 4 Prompt Builder node and its visual bbox editor from
ComfyUI-KJNodes (GPL-3.0, by Kijai) into this pack, fully renamed so it can
coexist with KJNodes if both are installed:
- nodes/ideogram4_nodes.py class/node_id/display_name -> AI2Go*, category AI2Go/text
- web/js/ideogram4_prompt_builder.js extension name, CSS id + 'kjideo-' prefix -> 'ai2go-ideo-',
CSS vars '--kj-dock-' -> '--ai2go-dock-', template dir -> ai2go/ideogram4
- web/js/utility.js shared helpers the editor imports (sibling module)
- fonts/FreeMono.ttf preview font
- __init__.py registers AI2GoIdeogram4PromptBuilder
GPL-3.0 attribution headers added to each derived file. Python + JS syntax verified.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>