Files
malkuthro-ComfyUI-Koolook/docs/maintainers/dev-iteration-loop.md
T
malkuthroandClaude Opus 4.7 e87d111521 docs(designs): snapshot dialogs redesign mockup + Mermaid flow (WIP) (#136)
* docs(designs): snapshot dialogs redesign mockup + Mermaid flow (WIP)

Design exploration for consolidating the Snapshot Settings cog into the
Save and Load dialogs, plus the related autosave-newer fix. Discussion
artifacts only — no code changes.

- docs/designs/snapshot-dialogs.html: side-by-side mockups across six
  sections (toolbar, Save dialog, Load dialog with default / Recovery
  expanded / inline delete-confirm states, autosave-newer modal,
  button-state pattern, folder-browse picker)
- docs/designs/snapshot-dialogs-redesign.md: scope sketch + Mermaid flow
- docs/designs/README.md: register the two new design files in the index

Single-library design stays (documented intent per
docs/maintainers/curated-sidebar.md). Redesign only consolidates surface;
implementation lands in a separate PR after layout details are locked in.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(designs): refine autosave-newer modal + single-row recovery groups

Two scoped tweaks to the snapshot dialogs mockup:

- Section 4 (autosave-newer): drop the "Replace current state?" question
  since the user already chose Load; promote "Auto-save is newer than
  the saved version" to the only head message. Render the two options
  as standard preset-rows (filename + picks/workflows/date meta) so the
  layout mirrors the Load dialog list. Buttons collapse to NO /
  YES — load latest on one row.
- Section 3 (recovery expanded): show only the newest row per
  <preset>_autosave/ group — whichever of Pre-load or Periodic is most
  recent — instead of listing both kinds. Annotation also notes the
  Recovery section auto-expands when a preset row is clicked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(designs): lock recovery behavior — hidden by default, one row per clicked preset

When the user clicks a preset row (Koolook_v03, starter, etc.) the recovery
section opens and reveals only that preset's <preset>_autosave/ folder,
with a single row inside — whichever of Pre-load or Periodic is newest
(the system picks). _unsaved_autosave/ no longer renders inside this
preset-scoped view since it isn't tied to the clicked preset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(designs): polish section 6 + recovery row layout

Folder-browse picker (section 6):
- Switch to standard navigate-into model — clicking a folder drills in,
  body lists that folder's contents (subfolders clickable, files greyed-
  out for context). Path input shows where you are; "Use this folder"
  commits the current path. Drops the sibling-list + selected-tag model.
- Single-line toolbar: ↑ Up next to the path input; secondary parent-
  path strip removed.
- Path input keeps the END visible when overflowing (direction:rtl +
  text-align:left), so a long path shows the meaningful trailing folder
  instead of /Users/… — and example path is now long enough to
  demonstrate it.
- Header restyled to match other modal heads (15px title, dark bg,
  bigger padding); descriptive subtitle removed.
- Bottom bar: New folder… stays left; Cancel + Use this folder push
  right (.picker-foot .spacer rule, since the existing flex-spacer was
  scoped to .modal-actions).
- Redundant "SELECTED FOLDER" stripe removed — selected-row blue accent
  is sufficient confirmation; folder list gains the freed vertical room.
- Example folder rename _unsaved_autosave -> default_autosave (label
  only — on-disk constant unchanged; rename is an open suggestion to
  drop the self-contradicting "unsaved autosave" term).

Recovery row (section 3):
- Layout: badge on top, single combined meta line below in order
  "<picks> · <workflows> · <date>" — matches preset-row shape so both
  rows read the same way.
- Padding bumped to 10px 12px so recovery-row and preset-row are the
  same box size; badge nudged 1px up + meta nudged 1px down for
  breathing room.
- Recovery section now scopes to the clicked preset only: orphan
  _unsaved_autosave/ group removed from the "Koolook_v03 clicked" view,
  since when a preset row is clicked the dropdown should only show that
  preset's auto-saves.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: require visual verification before requesting design-driven review

When implementing a UI change that has a corresponding mockup in
docs/designs/ (e.g. snapshot-dialogs.html, sidebar-icon-proposals.html),
the design file is the spec. Before the work is brought to the
maintainer for review, the implementing agent must:

  1. Render the implementation in a real browser — dev-sync for runtime
     sidebar work, python3 -m http.server (or the Launch preview panel)
     for standalone HTML mockups.
  2. Screenshot the implemented UI at every state the mockup shows.
  3. Diff each screenshot against the mockup. Match it or document the
     deviation with a rationale.
  4. Only then request review.

The maintainer should never be the first set of eyes on rendered
output. Type checks and tests verify code correctness, not visual
fidelity to the design — if a mockup exists for the change, visual
verification is a hard gate, not optional polish.

Rule lives in three places, each hit from a different entry point:
- CLAUDE.md (loaded at every session start; canonical)
- docs/designs/README.md (discovered when opening the designs folder)
- docs/maintainers/dev-iteration-loop.md (step 4 in the iteration loop)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* skills(tdd): add project-specific TDD skill modeled on ForgeFlow's

When implementation work on docs/designs/ mockups begins, /tdd on this
repo should pick up a project-level skill that knows ComfyUI-Koolook's
actual machinery — not just generic TDD principles.

Two files:

- SKILL.md — keeps the global TDD philosophy (vertical slices,
  behaviour-not-implementation, refactor only after GREEN) and adds a
  project-specific tail covering:
  • code surface: where Python nodes vs sidebar JS vs design specs live
  • test surface: what CI runs today (ruff, compileall, bandit,
    preflight_release.py) and explicit guidance on introducing pytest /
    vitest "only when there's a behaviour that genuinely needs unit
    testing" — same PR as the first test, never speculative
  • the dev-sync iteration loop for runtime sidebar work
  • high-value test targets (node registration, route validation, VAE
    dispatch, snapshot row augmentation)
  • drift patterns specific to this codebase (vendored upstream into
    MAIN, renamed namespaced node IDs in saved workflows, hardcoded
    user paths, dev-sync triggered from an automated flow, …)
  • final scope-alignment check routing (clean → proceed; drift → show
    report, never revert)

- visual-verification.md — the secondary procedure for cycles whose
  assertion is CSS / layout / structural. Procedure split for the two
  shapes of work in this repo:
  • runtime sidebar (web/sidebar/*.js): dev-sync → restart ComfyUI →
    screenshot → diff against docs/designs/<feature>.html
  • standalone HTML mockups (docs/designs/*.html): Launch preview panel
    or python3 -m http.server (no new package installs per
    supply-chain rules)
  Plus a structured definition of what "diff against the mockup" means
  (spatial, hierarchy, states, chrome, text — not pixel-equality), so
  it isn't a vague gate.

Generic companions (deep-modules, mocking, refactoring, interface-
design, scope-check, tests) intentionally not copied — agents follow
the global ~/.claude/skills/tdd/ pointers in SKILL.md for those. Avoids
sync-drift on principle docs and keeps this skill focused on what's
genuinely project-specific.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 17:43:55 +02:00

95 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Iterative dev loop — sidebar work
How the Curated Nodes / Workflows sidebar was built, in case you come back
to it after a break. Optimized for fast iteration without the publish
round-trip.
## First-time setup on a new machine
`KOLOOK_COMFYUI_DEV_PATH` should point at the eventual Koolook subdirectory
inside your live ComfyUI `custom_nodes/` folder — **not** the `custom_nodes/`
parent itself.
| Platform | Typical path |
|---|---|
| macOS | `/Volumes/Data/ComfyUI/custom_nodes/ComfyUI-Koolook` |
| Linux | `/home/<user>/ComfyUI/custom_nodes/ComfyUI-Koolook` |
| Windows | `C:/ComfyUI_portable/ComfyUI/custom_nodes/ComfyUI-Koolook` (forward slashes work fine) |
```bash
cp .env.example .env # if you don't have one yet
$EDITOR .env # set KOLOOK_COMFYUI_DEV_PATH
python scripts/sync_to_dev.py --init # creates the leaf folder + first sync
# restart ComfyUI to pick up the new install
```
After that first run, drop the `--init` — plain `python scripts/sync_to_dev.py`
is enough for every subsequent edit. The `--init` flag is a one-shot guard
against typos: it refuses to create a Koolook folder unless the parent looks
like a ComfyUI `custom_nodes/` directory (named `custom_nodes` or sitting
inside a `ComfyUI` parent).
## The loop
1. Edit `web/koolook_sidebar.js` or any module under `web/sidebar/` (or related JSON) in the worktree.
2. `python scripts/sync_to_dev.py` — copies runtime files into your live
ComfyUI `custom_nodes/<koolook>/`. Reads `KOLOOK_COMFYUI_DEV_PATH` from `.env`.
3. Restart ComfyUI; verify visually.
4. **If a design mockup exists** for what you just implemented (look
under [`docs/designs/`](../designs/)), screenshot the running result
and diff against the mockup. Don't request review until visual parity
is reached or each deviation is documented. See the [project
CLAUDE.md](../../CLAUDE.md) *"Visual verification for design-driven
implementation"* section for the full rule.
5. Iterate.
End-to-end: ~10–30 seconds. No tag/publish round-trip.
## Trigger phrases when working with the agent
| You say | Agent does |
|---|---|
| `dev-sync` (or "sync to dev", "copy those files") | runs `scripts/sync_to_dev.py` |
| `go` | implements the most-recently proposed plan as code |
| paste exported JSON from the ↓ button | replaces the matching `web/<feature>_defaults.json` |
## What survives across re-syncs and ComfyUI restarts
| Data | Lives in | Persistence |
|---|---|---|
| Node favorites (per user) | `localStorage["koolook.curated.userPicks.v1"]` | survives JS updates, ComfyUI restarts, browser refreshes |
| Saved workflows incl. archive (per install) | ComfyUI `/userdata/koolook_workflows.json` | survives JS updates and ComfyUI restarts |
| Distributed defaults — starter preset | `web/starter_preset.json` (in repo) | copied once into the user's snapshot library as `starter.json` on first ComfyUI load (replaces the legacy `curated_defaults.json` localStorage seed) |
| Distributed defaults — workflows | `web/workflow_defaults.json` (in repo) | seeded once into `/userdata` on first ComfyUI load |
dev-sync + restart never wipes user state. Only `localStorage.clear()`,
deleting `/userdata/koolook_workflows.json`, or wiping browser data does.
## Commit / push / publish gates
- Commit after a stable batch of working changes — not after every edit.
- Pushing a feature/PR branch **never** triggers a Comfy Registry publish.
- Publish fires only when `pyproject.toml` changes and the push lands on
`main`. Full procedure: [`releasing.md`](releasing.md).
## Tips that paid off in this build
- **Annotated screenshots** (a red arrow on the spot you're talking about)
beat text descriptions for UI feedback every time.
- **Verify uncertain frontend APIs against `Comfy-Org/ComfyUI_frontend`
source before guessing.** E.g. the `loadGraphData(graph, true, true, wfName, {})`
4th-arg trick that names the workflow tab was pulled from upstream
`src/scripts/app.ts`, not guessed.
- **Defensive fallbacks** when calling a newer ComfyUI API surface —
multiple property paths inside try/catch so older frontends still work.
- **Persist folder expansion state across re-renders** so saving doesn't
collapse the user's view (the `pathStates` Map in `web/sidebar/tree.js`).
## Files this loop touches most
- [`web/koolook_sidebar.js`](../../web/koolook_sidebar.js) — sidebar entry (boots the extension; module bodies live in [`web/sidebar/`](../../web/sidebar/))
- [`web/starter_preset.json`](../../web/starter_preset.json) — bundled starter preset (replaces the legacy `curated_defaults.json` pick-only seed)
- [`web/workflow_defaults.json`](../../web/workflow_defaults.json) — workflow defaults
- [`scripts/sync_to_dev.py`](../../scripts/sync_to_dev.py) — dev sync helper
- [`docs/maintainers/curated-sidebar.md`](curated-sidebar.md) — starter-preset round-trip detail