Step 1: save plan, clean up old-style node registration and broken tests

This commit is contained in:
Immac
2026-03-01 16:38:08 -06:00
parent 3e39e9bb09
commit 4fb0aaa4bb
4 changed files with 61 additions and 63 deletions
+58
View File
@@ -0,0 +1,58 @@
# Migration Plan: Comfy-Org/ComfyUI-React-Extension-Template
Repo is being updated to match the `Comfy-Org/ComfyUI-React-Extension-Template` pattern,
adding a React/TypeScript Style Mixer UI alongside the existing custom nodes.
---
## Steps
### ✅ Step 0 — Save this plan (first order of business)
### Step 1 — Clean up the Python layer ← *currently here*
- [x] Save plan to `PLAN.md`
- [x] Delete broken tests (`tests/test_immac_tools.py` — asserts old-style class attributes that don't exist on `io.ComfyNode`)
- [x] Remove dead dict registration from `src/immac_tools/__init__.py` (`NODE_CLASS_MAPPINGS`, `NODE_DISPLAY_NAME_MAPPINGS`, `WEB_DIRECTORY`)
- [x] Remove unused `ExampleForwardingExtension` from `src/immac_tools/forwarding_nodes.py`
### Step 2 — Rewrite root `__init__.py` to match the template pattern
- Remove `WEB_DIRECTORY` re-export
- Set `NODE_CLASS_MAPPINGS = {}` (nodes registered via `comfy_entrypoint`)
- Wire `comfy_entrypoint` to `src/immac_tools/nodes.py`
- Register aiohttp static routes to serve `dist/immac_style_mixer/` at `/immac_style_mixer/`
- Register `nodes.EXTENSION_WEB_DIRS[project_name]` using `comfy_config` (with fallback)
### Step 3 — Add Style Mixer REST API (`src/immac_tools/api.py`)
- Load/save `style_mixer_data.json` in workspace root
- Schema: `{ "styles": [{ "id", "name", "value", "favorite" }], "mixes": [{ "id", "name", "styles": [{ "style_id", "weight", "enabled" }], "favorite" }], "current_mix_id": null }`
- Routes (registered from `__init__.py`):
- `GET /immac_style_mixer/api/data` → return full data blob
- `POST /immac_style_mixer/api/data` → replace full data blob
### Step 4 — Update `pyproject.toml`
- Change `includes = []` → `includes = ["dist/"]`
- Remove `[build-system]` / `[tool.setuptools]` blocks (not needed; ComfyUI loads directly)
### Step 5 — Scaffold `ui/` (React + TypeScript + Vite)
- `ui/package.json` — deps: `react`, `react-dom`, `vite`, `@vitejs/plugin-react`, `typescript`, `@comfyorg/comfyui-frontend-types`; build output → `../dist/immac_style_mixer`
- `ui/vite.config.ts` — output `../dist/immac_style_mixer`
- `ui/tsconfig.json` + `ui/tsconfig.node.json`
- `ui/src/main.tsx` — registers ComfyUI extension; mounts panel as a sidebar tab via `app.extensionManager.registerSidebarTab`
### Step 6 — Build UI components
- `hooks/useStyleMixerData.ts` — fetch/save via `/immac_style_mixer/api/data`
- `components/StyleCard.tsx` — name (editable), value, favorite star, delete
- `components/MixCard.tsx` — name, radio to activate, list of style entries (name + weight slider + ON/OFF toggle + remove), favorite star
- `components/StyleGallery.tsx` — grid of all styles; "Add Style" inline form
- `components/StyleMixerPanel.tsx` — top-level: **Current Mix** / **Mixes** / **Styles** sections
### Step 7 — GitHub Actions CI
- `.github/workflows/react-build.yml` — on push to `main`: `npm ci` + `npm run build` inside `ui/`
---
## Key Decisions
- Single `POST /immac_style_mixer/api/data` endpoint for all persistence (minimal backend; expand later)
- Sidebar tab (not floating window) for the panel
- `dist/` tracked in git — required for registry publishing via `includes = ["dist/"]`
- Styles are user-defined strings (prompt text snippets)
+2 -38
View File
@@ -1,40 +1,4 @@
"""ComfyUI-ImmacTools package exports used by ComfyUI.
"""ComfyUI-ImmacTools node package.
This module exposes the node registration mappings and the `WEB_DIRECTORY`
constant expected by ComfyUI web extensions.
Node registration is handled via comfy_entrypoint() in nodes.py.
"""
from .nodes import ConcatenateSigmasNode, SpliceSigmasAtNode, ResampleSigmas, SkipEveryNthImages, MatchContrastNode
from .forwarding_nodes import ForwardAnyNode, ForwardConditioningNode, ForwardModelNode
# Mapping from node_id to node class
NODE_CLASS_MAPPINGS: dict[str, type] = {
"ConcatenateSigmasImmacTools": ConcatenateSigmasNode,
"SpliceSigmasAtImmacTools": SpliceSigmasAtNode,
"ResampleSigmasImmacTools": ResampleSigmas,
"SkipEveryNthImagesImmacTools": SkipEveryNthImages,
"MatchContrastImmacTools": MatchContrastNode,
"ForwardAnyImmacTools": ForwardAnyNode,
"ForwardConditioningImmacTools": ForwardConditioningNode,
"ForwardModelImmacTools": ForwardModelNode,
}
# Mapping from node_id to human readable display name
NODE_DISPLAY_NAME_MAPPINGS: dict[str, str] = {
"ConcatenateSigmasImmacTools": "Concatenate Sigmas Node",
"SpliceSigmasAtImmacTools": "Splice Sigmas At Node",
"ResampleSigmasImmacTools": "Resample Sigmas",
"SkipEveryNthImagesImmacTools": "Skip Every Nth Image",
"MatchContrastImmacTools": "Match Contrast",
"ForwardAnyImmacTools": "Forward Any",
"ForwardConditioningImmacTools": "Forward Conditioning",
"ForwardModelImmacTools": "Forward Model",
}
# ComfyUI expects this for web extensions
WEB_DIRECTORY = "./web"
__all__ = [
"NODE_CLASS_MAPPINGS",
"NODE_DISPLAY_NAME_MAPPINGS",
"WEB_DIRECTORY",
]
+1 -4
View File
@@ -109,10 +109,7 @@ class ForwardModelNode(io.ComfyNode):
return io.NodeOutput(model)
class ExampleForwardingExtension(ComfyExtension):
@override
async def get_node_list(self) -> list[type[io.ComfyNode]]:
return [ForwardAnyNode, ForwardConditioningNode, ForwardModelNode]
-21
View File
@@ -1,21 +0,0 @@
#!/usr/bin/env python
"""Tests for `immac_tools` package."""
import pytest
from src.immac_tools.nodes import ConcatenateSigmasNode
@pytest.fixture
def example_node():
"""Fixture to create an Example node instance."""
return ConcatenateSigmasNode()
def test_example_node_initialization(example_node):
"""Test that the node can be instantiated."""
assert isinstance(example_node, ConcatenateSigmasNode)
def test_return_types():
"""Test the node's metadata."""
assert ConcatenateSigmasNode.RETURN_TYPES == ("IMAGE",)
assert ConcatenateSigmasNode.FUNCTION == "test"
assert ConcatenateSigmasNode.CATEGORY == "Example"