Commit Graph
37 Commits
Author SHA1 Message Date
Chris 74fb777188 delete the task.md 2026-06-27 23:39:58 +02:00
ChrisandClaude Opus 4.8 e0db3b8415 Wizard: rename 'Clear & apply' -> 'Clear & apply & close'; close after
The button now clears the wizard, applies the cleared state to the builder,
and closes the modal in one click.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 23:17:23 +02:00
ChrisandClaude Opus 4.8 92824b96de Wizard: clearing now clears the builder's photo/art_style; add Clear & apply
Bug: after "Clear all" + "Apply", the builder's photo (or art_style) field
stayed filled. applyToBuilder computed kind=null when both were empty and
skipped the style block entirely, leaving the builder's previous value.

Fix: mirror the wizard exactly — when both are empty, set the builder's
"style" combo to "none" (its DynamicCombo drops the photo/art_style
sub-widget, actually clearing it), matching how the builder's own
applyCaption handles a style-less import.

Also add a "Clear & apply" button (clears the wizard and pushes the cleared
state to the builder in one click).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 23:09:11 +02:00
ChrisandClaude Opus 4.8 9bf33e0d56 Wizard: enlarge status line, make 'not connected' state red
Bump the Pick-tab status text 11px -> 13px and color the not-connected
warning red (bold) instead of orange, so it reads clearly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 23:02:03 +02:00
ChrisandClaude Opus 4.8 2dfe428e4c Fix stray ')' that broke the Style Wizard module load
An extra ")" in the parsePresets() error-message concatenation closed the
string early and left a dangling token, so web/js/ideogram4_style_wizard.js
failed to parse as an ES module. The whole extension never registered:
the node showed its raw wizard_data widget with no "Open Style Wizard" button.

`node --check` on the .js false-passed; validated now as strict ESM (.mjs)
and via a mocked import()+onNodeCreated harness (button is added again).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 22:56:58 +02:00
Chris 5d1d22e8b3 updated-builder 2026-06-27 21:46:37 +02:00
Chris be17938d49 style wizzard update 2026-06-27 19:49:17 +02:00
Chris dd7870c365 added new wizard node 2026-06-27 18:58:06 +02:00
ChrisandClaude Opus 4.8 632bfbb99c Release 1.0.2 (Overview "Move to root" + prior fixes)
Bump version to publish the Overview right-click "Move to root" item (and everything since 1.0.1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 23:49:13 +02:00
ChrisandClaude Opus 4.8 44909e9c19 Overview right-click: add "Move to root"
The context menu gains a "Move to root" item that unparents the right-clicked node (or the whole
selection if that row is part of it) — a discoverable alternative to dragging onto the header.
Disabled when nothing in the target is nested. The node's subtree comes with it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 23:37:36 +02:00
Chris e44286ce2c fix bug 2026-06-26 20:03:25 +02:00
ChrisandClaude Opus 4.8 39d694bdd5 Registry metadata: PublisherId littlegod, version 1.0.0, banner
Set the Comfy Registry publisher to "littlegod", bump to the first release version 1.0.0, and point
the registry Banner at the repo's banner asset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 13:58:58 +02:00
ChrisandClaude Opus 4.8 8709ec6613 Fix: lock a child's enable toggle whenever its group is off
The lock condition was "(effectively off) && (not own-disabled)", so a child that was ALREADY
individually disabled stayed clickable after the group was disabled — and clicking it merely flipped
it into the locked state. Lock now keys purely on whether a parent group is off (ancestorOff), so
once a group is disabled ALL its children are consistently 🚫 + non-toggleable until the group is
re-enabled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 10:35:18 +02:00
ChrisandClaude Opus 4.8 2cfb42e5e0 Disabled group now shows its children as hidden in the tree
The per-row eye reflected only the box's OWN state, so children under a disabled group still showed
👁 even though they were hidden everywhere. Now the eye shows EFFECTIVE visibility: a child of a
disabled group reads as 🚫, faded and non-toggleable (the group is the master switch — flip it to
show them again). The whole disabled row dims for a clear hidden look.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 09:18:33 +02:00
ChrisandClaude Opus 4.8 a4d56abd0b Make the row enable/disable toggle a visible 👁 button
The enable toggle was a tiny native checkbox at the left of each Overview row — easy to miss on the
dark dock. Replaced it with a clear button: 👁 when enabled, 🚫 when disabled (click to toggle),
styled like the other row buttons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 08:50:37 +02:00
ChrisandClaude Opus 4.8 6158eab5ef Overview: per-row enable/disable toggle (cascades through groups)
Each region and group row in the Overview gets an enable checkbox. Disabling a box (or a group —
which cascades to all its members) hides it from the canvas AND excludes it from the exported prompt,
the bbox output, and the preview render. Still listed in the Overview (dimmed) so it can be re-enabled.

- JS: isDisabled(b) walks the parent chain (own or any ancestor disabled); applied in the canvas draw,
  hit-testing, and buildCaptionObject (so token estimate reflects it too). Row checkbox toggles
  b.disabled and commits; effectively-disabled rows render dimmed. State persists + round-trips via
  the _ai2go sidecar / workflow.
- Python: _eff_disabled(box, by_id) mirrors the cascade; skips disabled in execute (elements + bboxes)
  and in _render_preview.

JS + Python parse clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:18:44 +02:00
ChrisandClaude Opus 4.8 121f8e8603 Add banner + how-it-works images and show them in the README
- Move AI2Go-Banner.jpg and How-It-Works.jpg into assets/.
- README: banner at the top, how-it-works image in the node section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 16:21:23 +02:00
ChrisandClaude Opus 4.8 a69836318d Repo is reference-only: auto-close PRs + README note
- Add .github/workflows/close-prs.yml — politely auto-closes any opened/reopened pull request
  (pull_request_target, no PR-code checkout, so it's safe for fork PRs).
- README: note up front that issues are disabled, PRs are auto-closed, no support/contributions,
  and that forking under GPL-3.0 is welcome.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 15:46:20 +02:00
ChrisandClaude Opus 4.8 43b36771ae docs: README reflects the full feature set + KJNodes credit
Documents the region editor, the Overview scene tree, parenting, named groups (hide/show, scale,
duplicate, mirror), and the _ai2go copy/paste interop. Strengthens the GPL-3.0 credit to Kijai /
ComfyUI-KJNodes as the base of the Ideogram 4 editor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 15:24:56 +02:00
ChrisandClaude Opus 4.8 4dccbaf4f4 Strip _ai2go sidecar from the wired-import prompt output
If a JSON containing the _ai2go sidecar is wired into import_json (always mode), the node passed it
straight through to the `prompt` output. Strip _ai2go from the emitted caption so the model prompt
stays clean; the full imported caption (with _ai2go) is still mirrored to the editor via ui.caption,
so hierarchy/groups still restore in the editor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 14:34:59 +02:00
ChrisandClaude Opus 4.8 31acac11b2 Copy/paste carries an _ai2go layout sidecar (KJ ↔ AI2Go two-way compatible)
Copy and templates now emit the clean caption PLUS an "_ai2go" sidecar holding the full editor box
list (groups, parenting, ids, names, collapse/lock). Paste/import/template-load restores from it when
present, so AI2Go→AI2Go round-trips losslessly. KJNodes (and the model) ignore the unknown key, so:
- AI2Go → KJ: pastes as a normal flat scene.
- KJ → AI2Go: no sidecar → imports flat (as before).
- AI2Go → AI2Go: hierarchy + groups fully preserved.

The sidecar is added only when there's hierarchy/groups to keep (plain scenes stay clean). The Python
`prompt` output and the token estimate use the clean caption — the sidecar is clipboard/template-only.

JS parses clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 14:33:13 +02:00
ChrisandClaude Opus 4.8 70235dd35d Harden group duplicate + mirror (review fixes)
- Duplicate: derive the shift delta from the copy's actual bounding box (not the group frame, since a
  member can protrude after individual editing) and apply one uniform delta with no per-clone clamp, so
  the copy's internal layout is preserved exactly. Falls back to a negative shift when the group is
  pinned to an edge (no more copy-on-top-of-original).
- Mirror: skip whole LOCKED sub-branches as a unit (collect members without crossing a locked box) so a
  nested sub-group frame and its children always mirror together; clamp the whole reflected interval
  (keeps box size, stays on-canvas) instead of one edge; validate the axis.

JS parses clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 14:04:40 +02:00
ChrisandClaude Opus 4.8 58d7d5194d Group actions: duplicate + mirror H/V
Three buttons in a selected group's panel:
- Duplicate: clones the group and its whole subtree (fresh ids, parents remapped within the copy,
  shifted slightly so the copy is visible and stays on-canvas; copy is editable).
- Mirror ⇆ / Mirror ⇅: flip the group's members left↔right / top↕bottom about the group's frame
  (frame unchanged). Locked and unplaced members are left as-is.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:58:33 +02:00
ChrisandClaude Opus 4.8 aa9463e5da Resizing a group scales its members
Previously a group frame could be resized but it did nothing to the children. Now resizing a
group's frame (corner/edge handle) scales its placed children proportionally about the same anchor
edge — reusing the existing group-resize transform. Skips locked sub-branches and unplaced (nobbox)
children. Resizing a normal region is unchanged (children don't scale). Show frames with 👁️ first
to grab a group's handles.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 12:54:55 +02:00
ChrisandClaude Opus 4.8 24af8e41e0 Group toggle: 👁️ icon, hidden by default
- Toolbar button icon is now 👁️ (lit/active = group frames visible).
- Group frames are HIDDEN on the canvas by default (showGroups defaults off; only `true` shows them).
  Click 👁️ to reveal them. Groups remain in the Overview tree at all times and are never exported.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:13:34 +02:00
ChrisandClaude Opus 4.8 ba9b03876f Group canvas-visibility toggle + live multi-drag feedback
- New 📁 toolbar button toggles on-canvas visibility of group frames (node.properties.showGroups).
  When off, group frames aren't drawn and aren't grabbable on the canvas — but groups still appear
  in the Overview tree. State persists and is restored on load. Groups are never exported regardless.
- Dragging a multi-selection in the Overview now shows live feedback WHILE dragging (not just on
  release): every dragged row fades, and a small pill follows the cursor showing "N regions → <target>"
  (the group/region you're about to drop onto, or "→ root"). Cleared on drop/cancel/teardown.

JS parses clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:03:17 +02:00
ChrisandClaude Opus 4.8 3b3b0d0b51 Polish multi-reparent (review nits)
- Locked rows no longer reparent (lock = frozen): pointerdown bails on a locked row, and locked
  boxes are filtered out of a multi-selection drag.
- Drop cue only highlights a target when at least one dragged box would actually change parent
  (no more misleading blue ring over a box's current parent).
- Trailing-click suppression now fires only when a reparent actually happens, so a tiny accidental
  drag that lands on nothing no longer eats the row's click.
- Keep _selAnchor in sync after a multi-reparent so a later Shift-click range starts correctly.

JS parses clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:51:55 +02:00
ChrisandClaude Opus 4.8 34a55ba928 Multi-select reparent in the Overview + group-review fixes
Headline (requested): dragging a row that's part of a multi-selection now reparents the WHOLE
selection — drop it onto a group to add all selected regions at once, or onto the header to send
them all to root. Only the selection's top-level boxes move (internal nesting preserved); cycle-
guarded against dropping onto any dragged box or a descendant. The moved boxes stay selected.

Group-review fixes:
- Major: selecting a group showed the region editor; its bbox fields silently detached the group
  from its children. Groups now get a dedicated panel (name + frame color only) — no bbox fields.
- Moving a parent/group no longer places its UNPLACED (nobbox) descendants (which would alter the
  export); only directly-selected boxes get placed on a drag.
- Groups no longer reserve a phantom number badge / invisible title hotspot (tagRects + titleAt skip them).
- Locked groups now show the tight frozen dash + a 🔒 glyph.
- Groups can't be duplicated into orphans (startPlacing/copySelection skip them; ⧉ hidden on group rows).

JS parses clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:46:13 +02:00
ChrisandClaude Opus 4.8 9d4b5bb557 Add named region groups (right-click → Create group)
Right-click the Overview → "Create group from selection" wraps the selected regions in a new,
named **group**. Groups are editor-only organizers — never exported to the caption.

- A group is a box with `group:true` + `name`, parented over the selection (its bbox = the
  selection's union + a small margin so its dashed frame is grabbable). Only the top-level selected
  boxes are reparented, so internal sub-hierarchies are preserved.
- Move the group on the canvas → the whole group moves (Phase-2 propagation). Drawn as a dashed
  named frame; shown in the Overview tree with a 📁 label and a collapse triangle.
- Double-click a group's Overview row to rename it.
- Deleting a group keeps its children (they promote to the group's parent) — already how delete works.
- Excluded from export in BOTH the editor (buildCaption) and the Python node (execute elements,
  bbox output, and preview render), so the Ideogram caption stays a flat list of real regions.

JS parses clean (ES module); Python parses clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:32:48 +02:00
ChrisandClaude Opus 4.8 c90c5c19eb Rename the Explorer to "Overview" + add Ctrl/Shift multi-select
- 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>
2026-06-25 09:14:44 +02:00
ChrisandClaude Opus 4.8 28fba64f87 Fix parenting review findings
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>
2026-06-25 00:57:08 +02:00
ChrisandClaude Opus 4.8 fdb7be3df8 Add region parenting / hierarchy (Phase 2)
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>
2026-06-25 00:48:31 +02:00
ChrisandClaude Opus 4.8 2c087f439a Fix Object Explorer review findings
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>
2026-06-25 00:13:31 +02:00
ChrisandClaude Opus 4.8 653f634a32 Add Object Explorer panel + stable region IDs (Phase 1)
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>
2026-06-25 00:02:22 +02:00
ChrisandClaude Opus 4.8 6f6f0f9ec1 Point repo metadata at github.com/Little-God1983
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>
2026-06-24 23:44:27 +02:00
ChrisandClaude Opus 4.8 48f911d97f Add AI2Go Ideogram 4 Prompt Builder (copy-and-own from KJNodes)
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>
2026-06-24 23:02:37 +02:00
ChrisandClaude Opus 4.8 d289b7d05a Scaffold ComfyUI-AI2Go-Utils custom node pack
Initial repository skeleton: GPL-3.0 LICENSE, README (AIKnowledge2Go info page),
pyproject.toml + Comfy Registry publish workflow, __init__.py with WEB_DIRECTORY
wiring, and nodes/ + web/js/ structure ready for the Ideogram 4 editor port.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 22:53:02 +02:00