{"id":34711470,"url":"https://github.com/mobcat40/comfyui-promptchain","last_synced_at":"2025-12-25T00:01:03.808Z","repository":{"id":326339125,"uuid":"1103491186","full_name":"mobcat40/ComfyUI-PromptChain","owner":"mobcat40","description":"A visual prompt engineering toolkit for ComfyUI. Chain prompts together, see what fires, lock what works.","archived":false,"fork":false,"pushed_at":"2025-12-04T19:14:47.000Z","size":9246,"stargazers_count":1,"open_issues_count":2,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-08T02:55:04.788Z","etag":null,"topics":["ai-art","comfy-ui","comfyui","comfyui-custom-nodes","generative-ai","prompt-engineering","randomization","stable-diffusion","wildcards","workflow-automation"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mobcat40.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-25T00:10:01.000Z","updated_at":"2025-12-04T19:14:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mobcat40/ComfyUI-PromptChain","commit_stats":null,"previous_names":["mobcat40/comfyui-promptchain"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mobcat40/ComfyUI-PromptChain","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobcat40%2FComfyUI-PromptChain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobcat40%2FComfyUI-PromptChain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobcat40%2FComfyUI-PromptChain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobcat40%2FComfyUI-PromptChain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mobcat40","download_url":"https://codeload.github.com/mobcat40/ComfyUI-PromptChain/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobcat40%2FComfyUI-PromptChain/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28013340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-art","comfy-ui","comfyui","comfyui-custom-nodes","generative-ai","prompt-engineering","randomization","stable-diffusion","wildcards","workflow-automation"],"created_at":"2025-12-25T00:00:42.085Z","updated_at":"2025-12-25T00:01:03.796Z","avatar_url":"https://github.com/mobcat40.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ComfyUI-PromptChain\r\n\r\nA visual prompt engineering toolkit for ComfyUI. Chain prompts together, see what fires, lock what works.\r\n\r\n## The Problem\r\n\r\nComplex prompts with randomization become unreadable fast:\r\n\r\n```\r\n{warrior|mage|rogue}, {iron|steel|mythril} {sword|axe|staff},\r\n{{fire|ice|lightning} enchantment|no enchantment}, {dragon|demon|undead} slayer\r\n```\r\n\r\nNow nest a few levels deeper. Add 20 options per group. Good luck debugging which path fired.\r\n\r\n## The Solution\r\n\r\nPromptChain makes the hierarchy *spatial*. Instead of parsing nested braces in your head, you see the decision tree as connected nodes:\r\n\r\n![PromptChain Workflow](screenshots/Intro.png)\r\n\r\nEach node shows exactly what it can output. Chain them together, see the whole prompt path at a glance.\r\n\r\n## Installation\r\n\r\n```bash\r\ncd ComfyUI/custom_nodes\r\ngit clone https://github.com/mobcat40/ComfyUI-PromptChain.git\r\n```\r\n\r\nRestart ComfyUI. No external dependencies required.\r\n\r\n## Features at a Glance\r\n\r\n- **Dual prompt support** — Handle both positive and negative prompts in a single chain\r\n- **Inline wildcards** — Write `red | blue | green` directly in nodes. No external files required.\r\n- **Comments** — Use `//` or `/* */` to annotate your prompts without affecting output\r\n- **Syntax highlighting** — Operators and comments are color-coded for easy reading\r\n- **Visual chaining** — Connect nodes to build rich, meaningful structures\r\n- **Dynamic inputs** — Inputs auto-expand as you connect more nodes\r\n- **Live preview** — See what fired, when it fired, in real-time\r\n- **Lock system** — Freeze outputs with upstream propagation\r\n- **Disable system** — Mute entire branches with one click\r\n- **Import/Export** — Convert to/from Dynamic Prompt syntax\r\n- **Tag deduplication** — Automatic duplicate removal\r\n- **Three modes:**\r\n  - `🎲 Roll` — Pick one random path from connected inputs\r\n  - `➕ Combine` — Merge all paths with intelligent interleaving\r\n  - `🟢 Switch` — Manually select which input to pass through (shows selected option name)\r\n\r\n---\r\n\r\n## Nodes\r\n\r\n### PromptChain (Main Node)\r\n\r\nThe core node for all prompt processing, combining, and randomization.\r\n\r\n#### Outputs\r\n\r\n| Output | UI Label | Description |\r\n|--------|----------|-------------|\r\n| `chain` | `out` | Bundle containing both positive and negative prompts (for chaining to other PromptChain nodes) |\r\n| `positive` | `positive` | Plain positive prompt text (connect to CLIP positive) |\r\n| `negative` | `negative` | Plain negative prompt text (connect to CLIP negative) |\r\n\r\n#### Menubar Controls\r\n\r\nThe menubar at the top of each node provides quick access to all controls:\r\n\r\n| Control | Description |\r\n|---------|-------------|\r\n| 🔒/🔓 Lock | Freeze output (orange when active). Label shows when node is wide enough. |\r\n| ⛔ Disable | Mute node (red when active). Label shows when node is wide enough. |\r\n| ℹ️ Preview | Show live output preview. Label shows when node is wide enough. |\r\n| `+` checkbox | Show/hide positive prompt text field (blue) |\r\n| `-` checkbox | Show/hide negative prompt text field (red) |\r\n\r\n#### Mode Selector\r\n\r\nBelow the menubar is a mode dropdown that controls how inputs are processed:\r\n\r\n| Mode | Description |\r\n|------|-------------|\r\n| 🎲 Roll | Pick one random input (shows winning input name after execution) |\r\n| ➕ Combine | Merge all inputs with breadth-first interleaving |\r\n| 🟢 [name] | Switch mode — manually select which input to use (shows selected input's name) |\r\n\r\nThe dropdown shows \"No Inputs\" when no inputs are connected.\r\n\r\n---\r\n\r\n### PromptChain Debug (Utility Node)\r\n\r\nInspector node for debugging text flowing through your prompt chain.\r\n\r\n**Purpose:** Logs the text reaching your CLIP/KSampler nodes to help debug complex chains.\r\n\r\n**Inputs:**\r\n- `text` — Text to inspect\r\n- `label` — Optional label for the debug output (default: \"positive\")\r\n\r\n**Output:**\r\n- `text` — Passes through input unchanged\r\n\r\n**Usage:** Insert between any connection to see what's actually being passed. Check `debug.log` in the extension folder (`custom_nodes/ComfyUI-PromptChain/debug.log`) for output.\r\n\r\n---\r\n\r\n## Dual Prompt Support\r\n\r\nPromptChain handles both **positive and negative prompts** in a single unified chain.\r\n\r\n### How It Works\r\n\r\nEach PromptChain node has two text fields:\r\n- **Positive prompt** (dark background) — Your main prompt content\r\n- **Negative prompt** (subtle red-tinted background) — Things to avoid\r\n\r\nBoth prompts flow through the chain together via the `chain` output. At the end of your chain, use the separate `positive` and `negative` outputs to connect to your CLIP nodes.\r\n\r\n### Visibility Toggles\r\n\r\nUse the `+` and `-` checkboxes in the menubar to show/hide each prompt field:\r\n- `+` — Toggle positive prompt visibility\r\n- `-` — Toggle negative prompt visibility\r\n\r\nThis helps reduce clutter when you only need one prompt type in a particular node.\r\n\r\n### Example Setup\r\n\r\n```\r\n[Style Node]                    [Subject Node]                    [Final Node]\r\n┌──────────────────┐           ┌──────────────────┐              ┌──────────────────┐\r\n│ + cinematic |    │           │ + warrior | mage │              │                  │──→ positive → CLIP\r\n│   dramatic       │──chain──→ │                  │──chain──→    │                  │\r\n│ - blurry | ugly  │           │ - deformed       │              │                  │──→ negative → CLIP\r\n└──────────────────┘           └──────────────────┘              └──────────────────┘\r\n```\r\n\r\n---\r\n\r\n## Modes\r\n\r\n### 🎲 Roll (Randomize)\r\n\r\nPicks **ONE random input** from all connected inputs.\r\n\r\n- The node's text field is prepended to the selected input\r\n- Use for branching logic where you want one path chosen randomly\r\n- Each execution may select a different input\r\n\r\n### ➕ Combine\r\n\r\nMerges **ALL inputs** using breadth-first interleaving.\r\n\r\nTags round-robin across branches so no single branch dominates the token budget:\r\n\r\n```\r\nInput branches: [\"a, b, c, d\", \"X, Y\"]\r\nOutput:         \"a, X, b, Y, c, d\"\r\n```\r\n\r\nNot `\"a, b, c, d, X, Y\"` — the interleaving ensures balanced representation.\r\n\r\n### 🟢 Switch\r\n\r\n**Manually select** which connected input to pass through.\r\n\r\n- A dropdown appears showing all connected inputs by their source node names\r\n- Click the dropdown or use arrow keys to cycle through inputs\r\n- The node's text field is prepended to the selected input\r\n- Perfect for A/B testing or debugging specific paths\r\n\r\n---\r\n\r\n## Wildcard Syntax\r\n\r\nWrite wildcards directly in text fields — no external files needed.\r\n\r\n| Symbol | Meaning | Example | Result |\r\n|--------|---------|---------|--------|\r\n| `\\|` | OR (pick one) | `red \\| blue \\| green` | `blue` |\r\n| `,` | AND (include both groups) | `red \\| blue, dress \\| skirt` | `blue, dress` |\r\n\r\n### Multiline Wildcards\r\n\r\nLines ending with `|` continue the OR group:\r\n\r\n```\r\nwarrior |\r\nmage |\r\nrogue\r\n```\r\n\r\nEquivalent to `warrior | mage | rogue` — picks one randomly.\r\n\r\n### Multiple Groups\r\n\r\nComma separates independent wildcard groups:\r\n\r\n```\r\nred | blue | green, large | small, fluffy | smooth\r\n```\r\n\r\nThis picks one from each group and combines them: `\"blue, small, fluffy\"`\r\n\r\n---\r\n\r\n## Comments\r\n\r\nAdd notes to your prompts without affecting the output. Great for documenting complex prompts or temporarily disabling tags.\r\n\r\n### Single-Line Comments\r\n\r\nUse `//` to comment until end of line:\r\n\r\n```\r\nphotorealistic,      // main style\r\n1girl,               // character\r\ndetailed background  // setting\r\n```\r\n\r\nOutput: `photorealistic, 1girl, detailed background`\r\n\r\n### Block Comments\r\n\r\nUse `/* */` for multi-line comments:\r\n\r\n```\r\ncinematic lighting,\r\n/* TODO: experiment with these later\r\ngolden hour,\r\nrim lighting,\r\n*/\r\nsoft shadows\r\n```\r\n\r\nOutput: `cinematic lighting, soft shadows`\r\n\r\n### Use Cases\r\n\r\n- **Documentation** — Explain why certain tags are included\r\n- **Quick disable** — Comment out tags instead of deleting them\r\n- **Notes to self** — Leave reminders for future editing\r\n- **Version history** — Keep old variations as comments\r\n\r\n---\r\n\r\n## Syntax Highlighting\r\n\r\nAll text fields feature live syntax highlighting with a Monokai-inspired color scheme:\r\n\r\n| Element | Color | Example |\r\n|---------|-------|---------|\r\n| Operators (`\\|`, `,`) | Pink, bold | `red \\| blue` |\r\n| Comments (`//`, `/* */`) | Gray, italic | `// note` |\r\n| Regular text | Light gray | `portrait of a warrior` |\r\n\r\nThe highlighting updates in real-time as you type, making it easy to:\r\n\r\n- **Spot structure** — Instantly see where your wildcards and groups are\r\n- **Find comments** — Gray italic text stands out from active prompts\r\n- **Identify operators** — Bold pink pipes and commas show decision points\r\n\r\nThe preview panel also uses syntax highlighting, with the \"Prompt result:\" label displayed in gray bold to distinguish metadata from actual prompt content.\r\n\r\n---\r\n\r\n## Lock System\r\n\r\nClick the **lock icon** (🔒/🔓) to freeze the current output. (For when you need to lock in that sweet Mythril Ice Enchanted Sword!)\r\n\r\n![Locked Nodes](screenshots/Locked.png)\r\n\r\n### When Locked\r\n\r\n- Node returns cached output instead of re-processing\r\n- Randomization results preserved across executions\r\n- Perfect for keeping a roll you like\r\n\r\n### Visual Indicators\r\n\r\n| State | Appearance |\r\n|-------|------------|\r\n| Locked | 🔒 Orange icon + **bold yellow \"Lock\" text** + gold background with diagonal stripes |\r\n| Unlocked | 🔓 Dim gray icon and text |\r\n\r\n### Upstream Propagation\r\n\r\n**Locking a node also locks all its input nodes** (the entire upstream chain). This ensures your complete prompt path stays frozen — from source nodes all the way to the locked node.\r\n\r\n### Persistence\r\n\r\nLock state and cached output save with your workflow.\r\n\r\n---\r\n\r\n## Disable System\r\n\r\nClick **⛔ Disable** in the menubar to temporarily exclude a node from the prompt chain.\r\n\r\n![Disabled Node](screenshots/Disabled.png)\r\n\r\n### When Disabled\r\n\r\n- Node outputs an empty string\r\n- Downstream nodes ignore this input entirely\r\n- The node and its upstream chain are visually marked\r\n\r\n### Visual Indicators\r\n\r\n| State | Appearance |\r\n|-------|------------|\r\n| Disabled | ⛔ Red icon + **bold red \"Disable\" text** + dark red background with diagonal stripes |\r\n| Enabled | ⛔ Dim gray icon and text |\r\n\r\n### Upstream Propagation\r\n\r\n**Disabling a node also disables all its input nodes** (the entire upstream chain). This lets you mute an entire branch with one click.\r\n\r\n### Use Cases\r\n\r\n- A/B testing different branches without rewiring\r\n- Temporarily muting parts of complex prompt trees\r\n- Quick toggling of optional modifiers\r\n\r\n### Persistence\r\n\r\nDisabled state saves with your workflow.\r\n\r\n---\r\n\r\n## Live Preview\r\n\r\nToggle the **Preview** button (ℹ️) in the menubar to see real-time output.\r\n\r\n### Preview Shows\r\n\r\n- **Last run timestamp** — Shows elapsed time since execution (e.g., \"20 mins ago\"), updates in real-time\r\n- **Execution time** — Shows how long the workflow took to execute (in milliseconds)\r\n- **Word count** — Shows word count for positive and negative prompts (e.g., \"15 words / 8 neg\")\r\n- **Selected wildcards** — See exactly which options fired\r\n- **Full output** — The complete processed result for both positive and negative prompts\r\n- **\"Awaiting first run...\"** — Shown until node executes for the first time\r\n\r\n---\r\n\r\n## Import \u0026 Export\r\n\r\nRight-click any PromptChain node → **Import** or **Export**\r\n\r\n### Import\r\n\r\nPaste existing prompts and auto-generate clean node structures:\r\n\r\n| Format | Example | Result |\r\n|--------|---------|--------|\r\n| Plain tags | `red, blue, green` | Converts to `red \\| blue \\| green` |\r\n| Dynamic Prompts | `{warrior\\|mage}, {sword\\|staff}` | Creates connected node tree |\r\n| Nested braces | `{a\\|{b\\|c}}` | Recursively expanded into node hierarchy |\r\n| Top-level OR | `option A \\| option B` | Creates separate input nodes |\r\n\r\n### Export\r\n\r\nConvert your node tree back to Dynamic Prompt format:\r\n\r\n- Traverses all connected upstream nodes\r\n- Converts wildcards to brace syntax\r\n- Respects modes: Randomize → `{a|b}`, Combine → comma-joined\r\n- Opens dialog with exportable string ready to copy\r\n\r\n---\r\n\r\n## Tag Deduplication\r\n\r\nDuplicates are automatically removed. **First occurrence wins:**\r\n\r\n```\r\nInput:  \"red, blue, RED, green, Blue\"\r\nOutput: \"red, blue, green\"\r\n```\r\n\r\n- Case-insensitive matching\r\n- Special tags like `[BREAK]` are always preserved\r\n- Early nodes = intentional placement; later duplicates from merges get removed\r\n\r\n---\r\n\r\n## Dynamic Inputs\r\n\r\nInput slots automatically expand as you connect more nodes:\r\n\r\n- Connect a node → new empty slot appears\r\n- Disconnect → empty slots are cleaned up (keeps at least one)\r\n- Input labels show connected node titles for easy identification\r\n- No manual slot management needed\r\n\r\n---\r\n\r\n## Example Workflows\r\n\r\n### RPG Character Generator\r\n\r\n```\r\nNode 1 (Randomize):            Node 2 (Randomize):           Node 3 (Combine):\r\n┌─────────────────┐           ┌─────────────────┐           ┌─────────────────┐\r\n│ warrior |       │           │ steel | mythril │           │ fire enchant,   │\r\n│ mage | rogue    │──────────→│ sword | staff   │──────────→│ dragon slayer   │\r\n└─────────────────┘           └─────────────────┘           └─────────────────┘\r\n\r\nPossible output: \"warrior, mythril staff, fire enchant, dragon slayer\"\r\n```\r\n\r\n### Style + Subject with Negative Prompts\r\n\r\n```\r\n[Style]                        [Subject]                      [Output]\r\n┌────────────────┐            ┌────────────────┐            ┌────────────────┐\r\n│ + cinematic |  │            │ + portrait of  │            │                │→ positive\r\n│   moody | soft │──chain────→│   a warrior    │──chain────→│                │\r\n│ - cartoon      │            │ - bad anatomy  │            │                │→ negative\r\n└────────────────┘            └────────────────┘            └────────────────┘\r\n\r\npositive: \"cinematic, portrait of a warrior\"\r\nnegative: \"cartoon, bad anatomy\"\r\n```\r\n\r\n### A/B Testing with Switch Mode\r\n\r\n```\r\n[Option A]─────┐\r\n               │\r\n[Option B]─────┼──→ [Switch Node] ──→ Output\r\n               │    (manually select)\r\n[Option C]─────┘\r\n```\r\n\r\nUse the dropdown to instantly swap between options without rewiring.\r\n\r\n---\r\n\r\n## Trait Mixing Networks\r\n\r\nWire Randomize nodes in a **mesh** instead of a tree for combinatorial trait mixing:\r\n\r\n```\r\n[Fur Type]──┐     ┌──[Randomize]──┐\r\n            ├────→┤               ├────→[Combine]──→ Final\r\n[Fur Color]─┤     └──[Randomize]──┤\r\n            │                     │\r\n[Creature]──┴─────[Randomize]─────┘\r\n```\r\n\r\nEach Randomize node acts as selection pressure. Cross-wire your trait pools and every run produces a unique combination — like breeding.\r\n\r\nExample pools:\r\n- `Shiny Fur | Matted Fur`\r\n- `Silver | Black | Red`\r\n- `Werewolf | Bear`\r\n\r\nNatural output: \"Red, Shiny Fur, Werewolf\" — emergent behavior from simple primitives.\r\n\r\n---\r\n\r\n## Prompt Palette\r\n\r\nUse Switch mode to build a reusable prompt control panel:\r\n\r\n![Prompt Palette](screenshots/Palette.png)\r\n\r\n**How it works:**\r\n\r\n1. Create a Switch node for each category (Style, Pose, Character, Outfit, etc.)\r\n2. Connect pre-built prompt options to each Switch\r\n3. Use the dropdown or arrow keys to flip between presets\r\n4. All Switches feed into a final Combine node\r\n\r\n**Why this pattern is powerful:**\r\n\r\n- **Instant iteration** — Change any category without rewiring\r\n- **Saved presets** — Your options persist with the workflow\r\n- **Mix and match** — Combine any style with any pose with any character\r\n- **Quick comparison** — Flip through options to find what works\r\n\r\nBuild your prompt palette once, reuse it forever. Each workflow becomes a custom prompt mixer tailored to your subject.\r\n\r\n---\r\n\r\n## Prompt Library Mode\r\n\r\nDisconnected PromptChain nodes act as prompt storage:\r\n\r\n- Drop a node, paste your prompt, leave it unwired\r\n- Sits on your canvas as a visual \"sticky note\"\r\n- Saves with your workflow\r\n- Connect when you want to use it, disconnect to deactivate\r\n\r\nBuild a library of prompt fragments right in your workflow. Zero config, just nodes.\r\n\r\n---\r\n\r\n## Why PromptChain?\r\n\r\n| Pain Point | Dynamic Prompts | PromptChain |\r\n|------------|-----------------|-------------|\r\n| Nested syntax | `{a\\|{b\\|{c\\|d}}}` | Visual node tree |\r\n| Debugging | Read the string | See what lit up |\r\n| Positive + negative | Separate handling | Unified chain |\r\n| External files | Required | None |\r\n| Migration | — | One-click import |\r\n\r\n---\r\n\r\n## Tips \u0026 Tricks\r\n\r\n1. **Use Lock for iteration** — Find a random combination you like? Lock it before further experiments.\r\n\r\n2. **Disable for comparison** — Instead of deleting nodes, disable them to quickly compare with/without.\r\n\r\n3. **Hide unused prompts** — Use `+`/`-` toggles to hide prompt fields you're not using in a node.\r\n\r\n4. **Preview everything** — Enable preview on your final node to see the complete output.\r\n\r\n5. **Chain outputs** — Use `chain` output when connecting to other PromptChain nodes; use `positive`/`negative` only at the end for CLIP.\r\n\r\n6. **Debug complex chains** — Insert a PromptChain Debug node to log what's actually flowing through a connection.\r\n\r\n7. **Comment out experiments** — Use `//` to disable tags without deleting them: `// golden hour, soft lighting`\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT License — free to use forever!\r\n\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobcat40%2Fcomfyui-promptchain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmobcat40%2Fcomfyui-promptchain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobcat40%2Fcomfyui-promptchain/lists"}