CMK Positive / Negative Text
The boring node that stops you editing the same prompt twice
- txt_pos
- txt_neg
Two multiline text boxes, and the same two strings back out as separate outputs. That is the entire node. If you are reading this because you googled it after seeing it in a CMK workflow, the honest answer is that it does almost nothing - and that almost-nothing is worth having, which is why every mature workflow ends up with a node like it.
The category is CMK/Toolbox/Text. The Toolbox half of CMK Flow is the open, mix-and-match side of the pack: plain utility nodes that do not participate in the pack's closed -Pipe- generation chain and do not care whether you are running SDXL, Z-Image Turbo or something else entirely. This node is squarely Toolbox.
Why you'd wire one up
The problem it solves is repetition. A positive prompt usually needs to reach more than one place: the CLIP Text Encode feeding the sampler, and often a second encode for a detailer pass, or an inpaint module that re-uses the same wording. Type it into two nodes and the first time you tweak one and forget the other, you get a mismatch you will spend ten minutes diagnosing. Break the value out of the widget once and fan it out from a single socket. That's the whole class of node - ComfyUI's own PrimitiveStringMultiline is the core version of the same idea - and CMK's twist is just that it carries a matched positive/negative pair so the two halves stay adjacent in the graph instead of drifting apart.
There's a second, less flattering reason it exists. Its docstring calls it "two multiline prompt fields with matching positive/negative outputs" - a compatibility shim. The pack has legacy workflows and subgraphs from earlier CMK versions that expected a paired prompt node, and this keeps them loading. If you're building fresh, use it because it's convenient, not because it's clever.
Inputs and outputs
Both inputs are required and both are multiline:
txt_pos- default empty. Your positive prompt.txt_neg- default empty. Your negative prompt.
Two outputs, same names: txt_pos and txt_neg, each a STRING. Wire the positive output into your positive CLIP Text Encode (and any other consumer), the negative output into your negative encode. Nothing is processed, trimmed, or tokenised - the node even coerces with str(... or ""), so a None becomes an empty string rather than an error.
Because it hands back plain strings, it plays nicely with the CMK LoRA text loader convention: that pattern is a prompt string containing inline <lora:name:1.0> tags, which a LoRA-capable encoder parses for you. A dual-text node is a fine place to keep such a prompt.
Install
ComfyUI Manager → search CMK Flow → install the cmkflow entry → restart. Manual install:
cd ComfyUI/custom_nodes
git clone https://github.com/CMKFlow/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py
The helper is required, not decorative - a manual clone never triggers pip, and the script resolves the right interpreter (this matters on ComfyUI Desktop, where system Python, standalone-env and ComfyUI/.venv all coexist). It finishes with CMK dependency check: OK.
Common issues
- Do not expect token counting. It's a string box. Long prompts past the encoder's limit get truncated downstream by the encoder, not here. If you're on a modern model with a language-model text encoder, the old 77-token panic doesn't apply anyway - see our prompt-engineering notes.
- Node registers but the text is gone after reload. Widget values live in the workflow, so make sure you saved the graph rather than a baked API export.
- Pack-wide startup warning about Vue Nodes. CMK wants the ComfyUI setting Vue Nodes / Nodes 2.0 enabled. Without it the dynamic CMK nodes fall back to the old LiteGraph canvas rendering and some of their dropdowns and auto-sizing stop behaving. For a text box you won't notice; the moment you start dragging CMK pipe nodes around you will.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| txt_pos | STRING | — | |
| txt_neg | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| txt_pos | STRING | — |
| txt_neg | STRING | — |