Tutorial: 2026-07-07

2026-07-07

Newest entry on top.

ComfyUI target — fix "won't connect" (IPv4/IPv6) + auto-detect + diagnostics

Owner reported the plugin wouldn't connect to a running app, even after restarts. Root cause found by running the plugin's Python client against the live dev server: Vite binds [::1] (IPv6 localhost) only, but the client probed 127.0.0.1 (IPv4), so they never met — localhost:5173 worked in the browser (resolves to ::1) but 127.0.0.1:5173 was connection-refused. Fixes:

  • Use localhost (not 127.0.0.1) in the default + auto-detect candidates, so urllib tries BOTH IPv6 and IPv4 and reaches whichever the server bound (Vite = IPv6-only, desktop = dual-stack).
  • Auto-detect a running app on localhost:4173 / 5173 when nothing's configured (precedence now: Settings URL → RANDOM_AI_PROMPT_URL → auto-detect → default), so it "just connects."
  • Validate the probe actually returns a catalog (has lists/blocks), not just any HTTP 200 — a static/SPA server would 200 an index.html and false-positive.
  • Diagnostics: routes.py + __init__.py now print [Random AI Prompt] … lines (routes registered / resolved URL, or a WARNING + traceback) instead of silently swallowing a registration failure.

Verified the client end-to-end against the running dev server: auto-detected localhost:5173, fetched the catalog (88/90/26), and generated a seeded batch. Still feature/comfyui-target, 2.51.0. Landmine worth remembering: localhost ≠ 127.0.0.1 when a server binds IPv6-only (Vite does).

ComfyUI target — node polish + a bigger node set

Owner asked for "normal ComfyUI polish" + more specialized nodes. Done (all feature/comfyui-target, still 2.51.0):

  • Polish: per-input/output tooltips, a DESCRIPTION on each node, helpers grouped under a "Random AI Prompt/helpers" submenu, the app icon + on-brand node colours, and a status sidebar tab (engine connection + catalog counts, polling /random_ai_prompt/status).
  • New nodes: PromptBatch (N seeded variations as an OUTPUT_IS_LIST output), CombinePrompts (join wired prompt pieces, skipping empties — the manual-piping enabler), ShowPrompt (display + pass-through OUTPUT_NODE, text rendered via the JS onExecuted). Kept it curated — skipped a random-switch node (overlaps existing Comfy nodes).
  • Packaging: an Apache-2.0 LICENSE (pyproject referenced a missing one — would've blocked a Registry publish) + a drag-in example_workflows/random-ai-prompt.json (Generator → Show Prompt).

The JS (Show display, sidebar, colours, icon) + the example workflow JSON are structurally sound but need a live-ComfyUI check on the owner's machine — no ComfyUI runtime in CI.

ComfyUI target — ecosystem-fit refinements (testing round)

After the owner tried the nodes in a live ComfyUI + dev server, three fixes to make it feel native:

  • Settings URL now drives generation, not just the dropdowns. It only affected the JS catalog fetch; Python generation ignored it, so changing it "did nothing." Added a persisted server-side config (client.set/configured_url + /random_ai_prompt/config routes); precedence is now Settings URL → RANDOM_AI_PROMPT_URL → default. (Commit db94fd3.)
  • Removed the AI Rewrite node. A node whose job is to call a third-party text API mid-graph (dragging BYOK keys in) is off-paradigm for ComfyUI — the owner's earlier "power user" note was about Comfy-vs-OpenAI, not app scope. Remaining nodes: Generator + List / Block / DPL Expand. This also means the plugin now makes zero third-party calls (localhost only) — legal note simplified.
  • Removed the redundant per-node server_url widget. Settings is the one Comfy-native config point; the nodes are cleaner for it. And drew the app icon on the node title bars (web/icon.png + an onDrawForeground hook). Still feature/comfyui-target, still 2.51.0 (unreleased refinements).

Built the ComfyUI target (2.51.0)

Built targets/comfyui/ end to end: a fat natural-language RandomAIPromptGenerator + PromptList / PromptBlock / DPLExpand / PromptRewrite helpers (nodes.py), a stdlib-only HTTP client (client.py), same-origin ComfyUI proxy routes (routes.py), and a frontend extension (web/randomAiPrompt.js) for live catalog dropdowns + a server-URL setting. Backend gained POST /api/prompt + GET /api/prompt/catalog, and presets were wired in — all reusing the shared engine/promptRun.js + engine/nodeEngine.js + engine/presets.js (extracted this session; the CLI re-exports them, so nothing is re-ported). Design calls, confirmed with the owner: fat generator + a few helpers; presets included; point-at-running-app (default http://127.0.0.1:4173). Prompt-side only — re-roll is the native seed widget, variations/upscale are native ComfyUI.

Verify: tests/integration/promptApi.test.js covers generate / seed reproducibility / preset apply + unknown→400 / catalog; the Python is ast.parse-clean and the ComfyUI-runtime JS is out of the root lint scope (added to eslint.config.js ignores) — both need validating in a running ComfyUI (manual, no CI runtime). Deep-dive systems/comfyui.md; CLAUDE.md + credits updated; legal re-checked (localhost + BYOK, no new data flow). Branch feature/comfyui-target; version 2.50.1 → 2.51.0.

Dispose of chaos + extract a shared prompt-run; ComfyUI target planned

Owner asked for a new ComfyUI plugin target, and separately flagged that chaos was still "popping up" despite thinking it was gone. Chased the second first:

  • What actually happened: git shows no recent disposal — the only chaos commits are the original June additions. On 2026-06-19 the chaos knob was unmounted from Home.jsx ("removed, pending re-add"), but withChaos + the CLI --chaos flag were deliberately left in. It was never an engine setting. Owner confirmed: dispose of it fully (a pre-DPL randomization-control idea they never liked).
  • Removed withChaos from the web facade + CLI, dropped the CLI --chaos flag, and swept the current-state docs — keeping Midjourney's unrelated --chaos provider parameter and the vocab word "chaos". Default output is byte-identical (withChaos no-oped at chaos = 1); the snapshot + CLI reproducible-prompt tests confirm → 293 Node + 419 web green, lint + doc-links clean.
  • De-duplicated the seed/reroll logic into engine/promptRun.js (isomorphic; seedFor / forEngine / createPromptRun), now consumed by the web facade + CLI — deliberate groundwork so the coming ComfyUI backend /api/prompt route reuses it instead of a third re-port. Bumped 2.50.0 → 2.50.1 as its own commit on feature/cli-target.

ComfyUI target (planned, not yet built): prompt-side only (ComfyUI owns image gen / upscale / variations natively; re-roll = its native seed widget). Nodes: a flagship natural-language RandomPromptGenerator + PromptList / PromptBlock / DPLExpand / PromptRewrite; a frontend registerExtension for live catalog dropdowns + a status sidebar over the existing /api/manage/watch SSE. Backend gains /api/prompt + /api/prompt/catalog (extracting a shared engine/nodeEngine.js Node boot). Point-at-running-app. Branch plan: merge feature/cli-targetdev, then build on a fresh feature/comfyui-target; deep-dive systems/comfyui.md to be written with the build.

New targets/cli/ build target — the prompt CLI (2.50.0)

Built the long-planned CLI target from scratch as targets/cli/ (its own npm package, @random-ai-prompt/cli, bin prompt). Owner brief: a traditional command + arguments CLI (no TUI, no interactive), with a --help page, colors, and bash/zsh completion (plus "different shells" → also fish + PowerShell), covering every feature — "effectively do the same thing as the gui." Mid-build the owner reinforced: keep it in parity with the GUI and with the engine, by default, and record durable knowledge in the repo notes (not private memory).

Architecture — reuse, never fork:

  • Prompt generation goes through the shared engine (createEngine(nodeLoader) + promptFilesAndSuggestions), the exact bootstrap the smoke test uses. Every engine/settings.js field is a flag (src/lib/optionSpec.js is the single source for parsing + help + completion).
  • The SPA's provider registry (shared/index.js) uses Vite globs and can't run under Node, so I wrote a Node registry (src/lib/providers.js) that fs-discovers shared/<id>/config.js + _shared/settings/*.js and dynamic-imports them, folding shared settings in like the web registry.
  • For image/upscale/rewrite I run the real backend (apiHandler.js) in-process on an ephemeral localhost port and shim globalThis.fetch so the providers' relative /api/... calls resolve (src/lib/backend.js). So every provider's own code/generate.js runs unchanged and images land in the shared output/ folder with the same sidecar the gallery reads (src/lib/imagegen.js mirrors the SPA useImageBatches.runBatch). Reused the pure snapshot.js + rewriteSystem.js verbatim.
  • Settings/keys share the app's user/settings/ store (src/lib/store.jsvite-api-helpers.js): CLI defaults in their own cli namespace (no clobber), BYOK keys read from both stores (shared).

Landmines hit + fixed:

  • Node 24 rejects the providers' bare JSON imports (Vite normally transforms them). Added an ESM resolve hook (src/lib/jsonLoader.mjs) registered in bin/prompt.js that injects type: json.
  • First image test "hung" — it was actually a real OpenAI call: the CLI correctly picked up the owner's saved key + prompt from the shared GUI store (parity working). Stopped to avoid spending credits and added a guard: an api provider is only called with --images (so prompt -p openai "x" never bills). Copy providers (plain/novelai/midjourney) never touch the network.
  • Root ESLint ignored all of targets/**; narrowed the ignore to the web targets so the CLI (Node ESM) is linted with the engine. Added varsIgnorePattern: "^_" to match the existing _-omit convention.

Completion: src/lib/completion.js generates bash/zsh/fish/PowerShell scripts from the flag spec (never drifts) + a hidden prompt __complete <kind> dynamic resolver (provider ids, presets, samplers, block/list names) — kubectl/gh-style.

Verify: tests/cli/cli.test.js (14 tests, in the root Vitest gate) — flag coercion/overrides, settings/preset merge, provider discovery, completion generators, key masking, reproducible prompt generation. Full gate green: eslint . (0 problems), smoke, vitest run (293 tests / 31 files), prettier --check. Manually verified --help, list providers (40), text generation, midjourney copy formatting, and the missing-key guard. Live image gen against a running SD server / paid APIs is manual (not in CI).

Docs: rewrote notes/systems/cli.md (was the historical pre-revival CLI page) as the current deep-dive; added targets/cli/README.md; changelog entry; credits (commander, picocolors); legal pages re-checked (CLI adds no new data flow — same on-device storage + same providers) and dated; CLAUDE.md updated (the CLI now exists). Version bumped 2.49.6 → 2.50.0 (MINOR — new target/ milestone). Branch feature/cli-target.