* refactor(web): split koolook_sidebar.js into 7 sidebar modules Pure mechanical split — zero behavior change. Implements the design from issue #49 (common-case layout with patchCanvasMenu extracted). Old: web/koolook_sidebar.js (1973 lines, monolithic) New: web/koolook_sidebar.js (48-line entry) + 7 modules in web/sidebar/ - constants.js (130) — REPOS, TAB_*, storage keys, event names, URLs, ensureStyle, toast, compareNames - picks_store.js (117) — localStorage user picks: load/save/add (tri-state) /remove/notify/seed/export - workflows_store.js (347) — workflowsCache + persistMutation + snapshotCache + commit + persist*/load*/seed* + in-memory ops; cache is module-private - canvas_io.js (192) — serialize*/canvasIsNonEmpty/loadWorkflowOntoCanvas /insertNode/getSelectedNodeTypes - modals.js (384) — makeModalShell + showInputModal/showConfirmModal /showSaveWorkflowModal/showContextMenu - canvas_menu.js (45) — patchCanvasMenu (idempotent LGraphCanvas patch) - tree.js (825) — pathStates (module-private) + gatherers + DOM row factories + buildFolder + workflow/dir context menus + rebuildTree + renderPanel Encapsulation invariants verified: - workflowsCache: zero references outside workflows_store.js - pathStates: zero references outside tree.js - All 8 files pass node --check - CSS string byte-identical to original - URL constants resolve to same targets after the extra `..` adjustment Documentation updated: dev-iteration-loop.md and workflows-sidebar.md now point pathStates references at web/sidebar/tree.js. Other doc references to koolook_sidebar.js as the entry remain accurate. Closes #49. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(web): drop unreachable defensive guard in gatherWorkflows Review feedback on #51: the `if (!dir) continue;` after `dirOf(dirName)` is unreachable — `listDirectoryNames()` enumerates the same module-private `workflowsCache.directories` keys that `dirOf()` reads, synchronously, within a single event-loop turn. Removing the guard restores strict "byte-identical move" semantics for the file-split refactor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
64 lines
3.2 KiB
Markdown
64 lines
3.2 KiB
Markdown
# 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.
|
||
|
||
## 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. 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 — nodes | `web/curated_defaults.json` (in repo) | seeded once into user `localStorage` on first ComfyUI load |
|
||
| 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/curated_defaults.json`](../../web/curated_defaults.json) — node defaults
|
||
- [`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) — node-defaults round-trip detail
|