Files
ausboss-ComfyUI-AusBoss/docs/adding_a_node.md
T
ausboss ac9cc58592 Report each failed input check once, and let ComfyUI check the rest
A VALIDATE_INPUTS that takes **kwargs makes ComfyUI skip its own range
and list checks for every input, and a failed check comes back once per
input: Image Crop + Rotate + Pad without a picture showed 20 copies of
"Select or upload a source file first". Each validator now names only
what it reads.

- Image Crop + Rotate + Pad, Load Video and LaMa Inpaint read one input
  and report one error, on it. Video Crop + Rotate + Pad (Frame and
  Clip) read the three that choose the source. LoRA Loader reads the
  stack and on_missing; Save Image reads its two names and output_dir.
- Save Video has no validator any more: ComfyUI's own check holds a
  typed fps to 0.01-240.
- Load Video and the Clip node check the trim window, force_rate and
  Fixed frames as they run, where a wired bound has its value. They are
  async, so ComfyUI starts them ahead of other nodes.
- The sources still skip ComfyUI's list check on purpose, so uploads,
  subfolders, MaskEditor saves and a stale video choice in local path
  mode keep working. The path checks behind them are unchanged.
- crop_aspect_ratio accepts any whole-number W:H, as the transform
  always has, so a workflow made with someone else's presets still runs;
  anything else is now refused before the run.

tests/test_validate_inputs.py pins what each validator names (runs in
CI) and, with ComfyUI, drives ComfyUI's own validation.
2026-09-29 21:43:01 -05:00

4.2 KiB

Adding a polished node

New public nodes are admitted deliberately. Start with the workflow problem and contract, not a prototype file.

Contract first

Record the following before writing code:

  • Purpose and repeated workflow it replaces
  • Permanent AUSBOSS_NODES_<Purpose> mapping key
  • Display name and 🆎 AusBoss/<Group> category
  • Required/optional input IDs in serialization order, types, defaults, limits, and tooltips
  • Output names, types, and order
  • Tensor shapes, batch behavior, caching, errors, side effects, and API-mode behavior
  • Compatibility or migration behavior

Every visible field and output must earn its place. Published IDs, input order, widget meaning, and output order are API.

Implement narrowly

  1. Put independently testable processing in an underscore-prefixed helper under nodes/.
  2. Add one V1 wrapper in nodes/node_<purpose>.py with INPUT_TYPES, RETURN_TYPES, FUNCTION, CATEGORY, and both mapping dictionaries — keys as string literals, never a NODE_ID variable, or registry scanners cannot see the node.
  3. Add the module to NODE_MODULES in __init__.py and the key to PUBLIC_NODE_IDS in scripts/validate_nodes.py; the validator fails on a registered key it does not know. A key kept only so old workflows load goes in LEGACY_NODE_IDS instead.
  4. Give the node its face. Any INT, FLOAT, BOOLEAN, COMBO or STRING widget on a public node is shown through a widget card entry in js/widget_cards/index.js (see AGENTS.md §Conventions: numbers scrub, booleans are off | on pills, one linkable widget per row, top: true or forceInput for values people wire). Write more frontend JavaScript only when the card grammar cannot provide the interaction (a stage, a player, an editor).
  5. Namespace every route, extension, event, DOM marker, CSS class, cache, and browser state with ausboss.
  6. Chain lifecycle hooks through chainCallback; never replace core or third-party prototypes directly.
  7. Keep normal workflow and API execution independent from the custom frontend.
  8. Ship user-facing toggles as ComfyUI settings under the AusBoss.* namespace. Node coloring is automatic for AUSBOSS_NODES_* classes via js/appearance/ — no per-node work.
  9. A VALIDATE_INPUTS names only the inputs it reads, never **kwargs. ComfyUI skips its own range and list checks for every input a validator names (naming input_types also switches off its link checks), and repeats a failed check once per named input. Checks that need several values can run in the node itself. tests/test_validate_inputs.py pins what each validator names.

Document and prove

  • Add rich help at js/docs/<exact-mapping-key>.md (the validator checks it exists) and a section in README.md. Name card controls the way the node face shows them, with the widget name alongside: Tone match (color_match).
  • Show the node in an example under example_workflows/, a new one or an existing one it fits: a Workflow Note, numbered groups holding every node, no overlaps, and a matching .jpg of a real output. AGENTS.md § Example workflows lists the rest.
  • A DOM panel goes into tests/panel_guards.test.mjs as mustGrow or fixedByDesign.
  • At the next release, name the node in the pyproject description: Registry and Manager search read it.
  • Extend scripts/validate_nodes.py when the new contract needs a permanent assertion.
  • Add the node to the API snapshot: AUSBOSS_COMFY_ROOT=<ComfyUI> python tests/test_node_api.py --update with ComfyUI's Python. From then on its inputs and outputs may only be appended.
  • Add pure Python and dependency-free JavaScript tests.
  • Compile with ComfyUI's embedded Python.
  • Verify /object_info/<mapping-key>, ownership, served assets, routes, API execution, and queued dimensions/masks.
  • Test the actual canvas in Classic and Nodes 2.0, including save/reload, duplication, graph zoom, source replacement, and teardown. Drag a real link onto every card row and socket and look at where it lands (docs/live_testing.md).
  • Scan the diff for paths, hosts, secrets, placeholders and non-ASCII import output.

Do not release a node that only works in the editor, only works for one source, or returns debugging outputs users do not need.