Releases: Comfy-Org/comfy-cli
Release list
v1.17.0 — comfy build replaces comfy distribution
What's Changed
- fix(output): populate
whereon error envelopes for every routed command (BE-6275) by @mattmillerai in #700 - fix(models): refuse downloads whose destination is claimed by a live background download (BE-6469) by @mattmillerai in #678
- fix(jobs): speak cloud's actual /api/jobs status vocabulary (BE-6644) by @mattmillerai in #685
- fix(models): claim destinations from foreground downloads too, with a deterministic tie-break (BE-6652) by @mattmillerai in #688
- fix(cql): expand dynamic-combo sub-inputs in slot extraction and set-slot/vary write path (BE-3371) by @mattmillerai in #574
- feat(templates): serve stale gallery cache immediately, revalidate in background (BE-3427) by @mattmillerai in #566
- refactor(workflow): re-home API-workflow validate under
comfy workflow validate(BE-3000) by @mattmillerai in #522 - ci: bump cursor-review to github-workflows@0096e1a by @cloud-code-bot[bot] in #701
- fix: add HTTP timeouts to eight bare requests.* calls (BE-3272) by @mattmillerai in #527
- fix(cql): answer same-type
nodes pathqueries instead of declining them by @mattmillerai in #698 - refactor(cql): remove vestigial load_graph fetch stack from loader.py (BE-4364) by @mattmillerai in #598
- fix(registry): emit pyproject hints as standalone comments for tomlkit 0.15 by @mattmillerai in #536
- ci: bump cursor-review to github-workflows@9e8352a by @cloud-code-bot[bot] in #712
- ci: bump groom to github-workflows@eb4b26c by @cloud-code-bot[bot] in #702
- ci: bump agents-md-integrity to github-workflows@c6b3eff by @cloud-code-bot[bot] in #703
- ci: bump cursor-review to github-workflows@732100b by @cloud-code-bot[bot] in #716
- feat(nodes): include is_api_node in
nodes lsandnodes searchrows by @mattmillerai in #719 - fix(logs): sanitize replayed log output and the launch-failure panel by @mattmillerai in #717
- fix(run): conform the cloud NDJSON stream to the documented event contract by @mattmillerai in #656
- fix(launch): escape ComfyUI output before the markup-parsing relay by @mattmillerai in #713
- feat(distribution): serverless distribution commands (limited beta) by @sundar-svg in #731
- feat(distribution): remaining builder commands (update, references, manifest, artifact, blob) by @sundar-svg in #732
- ci: bump groom to github-workflows@f8eec04 by @cloud-code-bot[bot] in #736
- ci: bump cursor-review to github-workflows@f8eec04 by @cloud-code-bot[bot] in #720
- ci: bump cursor-review to github-workflows@00b0eef by @cloud-code-bot[bot] in #742
- feat(workflow): agent-first workflow editing — CRDT edit primitives, recipes, offline catalog, cloud run association by @skishore23 in #511
- ci: bump groom to github-workflows@eaee6df by @cloud-code-bot[bot] in #745
- docs: add CONTRIBUTING.md and CHANGELOG.md by @christian-byrne in #733
- feat(cloud): add
comfy cloud statusfor balance, tier and concurrency by @mattmillerai in #744 - feat(skills): fetch the comfy-build skill from comfy-skills at install time by @james00012 in #737
- fix: fail CLA allowlist step on API errors by @alexisrolland in #752
- fix(distribution): make a scanned definition buildable by @james00012 in #738
- feat(build): comfy build replaces comfy distribution behind a deprecated alias (BE-8393) by @james00012 in #754
New Contributors
- @sundar-svg made their first contribution in #731
Full Changelog: v1.16.0...v1.17.0
v1.16.0 — cloud failure causes restored, live jobs watch, tokenized model search
16 commits since v1.15.0 (2 features, 13 fixes). No breaking changes.
The headline is that a failed cloud job tells you why again. Since the CLI moved
to the newer jobs endpoint, every failed cloud job came back with an empty error
and a shrug — the real cause, the OOM in your KSampler, is back.
Fixes worth calling out
- Failed cloud jobs report their cause again.
jobs status/jobs watch
were asking/api/jobs/<id>for field names it does not serve, so every
failure surfaced as an empty error andended in status 'error'. The
structured execution error is now read and flattened to a human line, and
carried verbatim for--jsonconsumers. The blank timestamps came back with
it. (#683) jobs watchstreams live progress instead of sitting silent. A local
ComfyUI addresses execution events to the socket that submitted the prompt,
andwatchconnected under a fresh client id, so it could never receive one.
It now attaches as the submitting client, understands the per-step
progress_statemessage current ComfyUI actually sends, and reconciles
completed nodes against the server — so the final line is right no matter when
you started watching. (#693)- Local
models search --textmatches the way model files are named. The
query was matched as one unbroken string, so--text "sdxl base"returned
nothing in a folder plainly containingsd_xl_base_1.0.safetensors. Each
token now has to appear somewhere in the name, in any order, with_-.
separators no longer in the way. (#684) nodes pathfollows the wires and stops overclaiming. The walk ignored
the source type —AUDIO -> IMAGEreturned the same rows asMODEL -> IMAGE
— and stamped every answer"exact": true. Each hop must now go through an
input whose declared type matches the previous hop's output, andexactis
claimed only when the search actually finished. An agent planning a graph off
the old output was being confidently misled, which is worse than an error.
(#695)comfy outdatedno longer trusts a mis-set GitHubreleases/latestflag
for ComfyUI core. It prefers the highest stable semver tag known to the local
checkout, falling back to the API only when the checkout has no usable tags —
the same guardinstall/update --version latestalready had. (#694)nvidia-smiis resolved by absolute path in the CUDA probe, so running
comfyfrom a prepared directory on Windows cannot execute a planted
nvidia-smi.exe. An unresolvable match degrades to "unknown CUDA version",
exactly as a failed probe already did. (#641)- Registry failures are typed and carry a machine-readable code.
node publish/node registry-installraised a bareExceptionon a bad
token, a missing node, or a server error; they now emit the standard error
envelope with the HTTP status and body indetails. (#528) node install --exit-on-failreturns an exit code that cannot lie. A
signal death reported a mangled-9as247, and non-zero multiples of 256
wrapped to0— a failed install reporting success to the CI script the flag
exists for. Codes are now normalized (137for an OOM kill, never0), with
the raw status indetails.cm_cli_returncode. (#681)--host/--portusage errors emit a terminating envelope in JSON and
NDJSON modes, instead of exiting 2 with zero bytes on stdout. This also hit
auto-selected JSON mode, socomfy jobs ls --port 0 | catwas silent too.
(#687)whereis populated on run-path JSON error envelopes, which had always
shippednulldespite the documented"local"/"cloud"values. (#665)- Externally-killed
comfy run --waitruns get reaped.--waitnever
recorded which process was watching, so a CItimeoutSIGKILL left the record
runningforever. It now stamps its own pid at submit time; a--waitthat
hits its own--timeoutdeliberately clears the stamp, since the job may
genuinely still be running on the server. (#682) jobs.jsonrequireshost/portonly for non-cloud payloads. Cloud
jobs report abase_urland have neither, so every cloudstatus/watch
payload was breaking the CLI's own published schema. (#696)- Stranded atomic-write
.tmpfiles are swept in the state reap pass. The
scratch name is randomized per attempt, so every unclean death left a
different orphan that nothing ever deleted. (#689)
New
.comfy-downloads/growth is bounded. Background-download bookkeeping
files were never thrown away, so the directory grew forever and
comfy model downloadsparsed all of it to show a mostly-ancient list. A
prune pass now keeps anything still downloading plus the recent records, and
preserves any failed or cancelled record whose partial bytes are still on
disk — that record is your only handle for reclaiming them. (#697)- Partner-node usage is attributed to the caller that drove it. The usage
label was hardcoded, so a run you typed and a run an agent kicked off through
comfy-mcp looked identical. Humans keep the exactcomfy-clistring; agentic
callers becomecomfy-cli/comfy-mcp,comfy-cli/claude-code,
comfy-cli/agent, orcomfy-cli/pipe. (#690)
Internal
- The cursor-review workflow was bumped to the current shared revision. (#699)
v1.15.0 — fresh-install model detection, verified stop by port, non-zero update failures
12 commits since v1.14.0 (5 features, 4 fixes). No breaking changes.
The headline is a validation fix: on a fresh install, comfy validate now reports
the models you are missing instead of staying silent about the loaders that have
none.
Fixes worth calling out
- Empty COMBO enums no longer skip validation. A loader whose option list is
empty —UNETLoaderandCLIPLoaderon an install with no models — was
treated as "unconstrained", so its missing model was never reported at all.
Detection got worse the emptier the install, which is backwards for the
fresh-install case it exists to serve, and the two silently-skipped loaders are
the large downloads a user most needs to be told about before starting a run.
(#680) - An explicit
--port 0is no longer swallowed by a--host host:port
value. (#679) validateenforces promoted hard checks only on output-reachable nodes, so
a node that cannot affect the output no longer fails an otherwise runnable
graph. (#565)- Apple Silicon is detected under Rosetta 2 in the GPU probe, rather than
being reported as an x86 machine. (#568)
New
comfy stop --port <p>— verified stop of a local ComfyUI this CLI did not
launch, so an untracked server can be recycled instead of merely reported.
(#675)comfy update --exit-on-fail— a failed pack update exits non-zero, so a
script or an agent can tell a partial update from a clean one. (#676)error_codeonjobs lsrows — a job's failure cause travels with the row
instead of requiring a second call per job. (#677)text_outputsin localjobs status— text/STRING node outputs are
surfaced, not just file outputs. (#550)partner_nodes_detectedtelemetry, andcaller_kindstamped on every
event — usage driven by an agent is distinguishable from usage driven by a
human. (#647)
Internal
v1.14.0 — agent-drivable diagnostics, background downloads, version rollback
89 commits since v1.13.0 (17 features, 38 fixes). No breaking changes.
This release is what the Comfy MCP servers have been waiting on: every verb the
local MCP's tool surface calls but could not reach on 1.13.0 now ships.
New commands
comfy system-stats/comfy free— ComfyUI/system_statsand/free
passthrough, so device/VRAM data is available from the CLI instead of grepping
a log. (#626)comfy workflow notes <path>— readNote/MarkdownNotetext out of a
frontend workflow, offline. This is where LoRA trigger-word guidance lives.
(#611)comfy node deps— read-only per-pack Python dependency report: each
requirement marked satisfied / mismatch / missing against the workspace venv.
--registry <node-id>pre-checks a not-yet-installed pack, so a conflict
can be assessed before installing. (#610, #625)comfy model download --background— persistent download state plus
comfy model download-status,comfy model downloads, and
comfy model download-cancel. A multi-GB transfer no longer has to be held
open by its caller. (#607)comfy update comfy --version <X>— headless ComfyUI version
switch/rollback with tag validation, stashing by default. (#606)comfy templates check— a per-template runnable / missing /
api-required verdict, so a gallery template can be assessed against this
install before it is fetched. (#557)comfy upload --host/--port— local target routing for uploads. (#648)
Fixes worth calling out
models search --textwalks every model folder, not justcheckpoints—
it previously returned zero for files plainly on disk. (#603)comfy envdetects legacy ComfyUI-Manager clones and reconciles a stale
manager_gui_mode, so Manager present on disk is no longer reported
not-installed. (#609)comfy logsresolves the right file — candidate-based resolution with a
user/comfyui.logfallback, a crash-surviving pointer, and staleness
metadata. (#608)- A dead local server is now attributable to the job that killed it. This is
the headline fix for anyone who has watched an oversized workflow take ComfyUI
down and been told onlyserver_not_running.jobs statusfalls back to the
on-disk state file when the server is down (#602),run --waitwrites that
state at submit and names theprompt_idon disconnect (#605), the watcher
records a terminalserver_died(#604), and — the part that makes it usable —
jobs statusalso consults that record when the server is back UP but has no
history of the prompt (#674). Without that last piece the documented recovery
("relaunch, then check") threw the attribution away, which is exactly what a
user does first. The read is scoped to the queried target and to matching
loopback host spellings, so a cloud run — or a job from a second local
instance on another port — is never reported as an answer about this one. comfy nodesrefreshes its annotation data live from comfy-complete, and
templates fetchemits a correct envelope. (#474)nodes searchis tokenized and order-independent, with a category
haystack and close-match fallback. (#646)- Model downloads are atomic — streamed to a
.partsibling and renamed on
completion, so a killed transfer never leaves a truncated file sitting at the
final model path. (#666) validate/nodesread the same serverrunsubmits to — they now
honor the persisted background server instead of always consulting
127.0.0.1:8188, andvalidatenames the server its verdict came from. (#667)
Agent-facing contract
envelope/1now emitted bycomfy launch/comfy stop(#588) and by
generate list/generate schema(#621);model downloadandgenerate
emit envelope errors on every failure path (#581, #601).comfy rungates on paid partner nodes via--allow-spend, andvalidate
reportspartner_nodes/spends_credits(#591, #590).- Server-supplied text is stripped of ANSI/control sequences and escaped before
reaching Rich markup sinks (#614, #627, #655). jobs lsstate-file rows are scoped to the resolved--wheretarget, with
--allto opt out (#582), andjobs cancelemitsprompt_not_foundfor an
unknown local id rather than failing opaquely (#580).
Hardening
Absolute-path resolution for probe binaries to block Windows CWD planting
(#567), a shared read cap on three unbounded HTTP body reads (#654), authed
urllib routed through a no-redirect opener (#530), and PostHog key
shape-validation with the logger quieted (#620).
v1.13.0 — agent-drivable cloud login, run-template, spend gates
First release since v1.12.0 (2026-07-07) — 41 commits.
Features
comfy cloud loginis now agent-drivable. In--jsonmode it emits a machine-readablelogin_urlevent as soon as the authorize URL exists, instead of printing it only in pretty mode. This is what lets an MCP server or agent drive sign-in and hand the URL to a user.comfy run-template— fetch a template, fill its params, spend-gate, and run to completion in one verb.comfy outdated— read-only version check for ComfyUI core and installed node packs against latest.comfy run --prompt/--set— local text2img straight from the bundled default workflow, no graph authoring required.comfy generatespend gate — explicit consent before spending credits.comfy generatenow derives partner model enums from the active OpenAPI spec rather than a pinned list.comfy validateauto-converts UI-format workflows, matchingcomfy run.COMFY_LOCAL_URLis honored for the local ComfyUI address — the:8188hardcode is gone.
Fixes
Transfers / downloads
- Verify
Content-Lengthand download atomically via.partrename. - Sanitize the download extension taken from an untrusted
?filename=param. - Structured envelope on connection errors.
Workflows
- Detect oversize responses in
_http_requestinstead of silently truncating. - Widget-aware dynamic-combo expansion and name-aligned control-marker filtering in
workflow_to_api. validatepresence-checks required inputs, adds a no-outputs check, and hard-errors range violations.
Run / jobs
- Refresh the OAuth session during local partner-credential injection.
- Close the run WebSocket on every exit path of local
--wait. get_job_statusmigrated off the deprecated/api/job/<id>/statusendpoint.
Telemetry / install
- Bound telemetry network I/O so it can't outlive the run envelope.
- Build telemetry providers lazily so
comfy installcan upgradepydantic_core. - Pin
mixpanel<5socomfy installcan't wedgepydantic-coreon Windows.
Misc
comfy generate refreshfalls back to/openapi.yml.- Escape square brackets in Typer help strings so choice lists render.
- Surface GitHub rate limits from
find_pr_by_branch. - Registry pyproject hints emitted as single-line tomlkit comments.
Internal
Nine refactors (dead-code removal, shared helpers for banners/tarballs/download loops, CQL validate extraction, jobs WS dispatch table), CI now installs test deps from uv.lock so upstream releases can't break every PR, and an AGENTS.md contributor onboarding guide.
Full changelog: v1.12.0...v1.13.0
v1.12.0 — comfy logs + local saved-workflow
Highlights
comfy logs— background ComfyUI logs are now persisted to<workspace>/user/comfyui_<port>.logand readable viacomfy logs --tail N. A failedcomfy launch --backgroundis debuggable instead of a black box (#491).- Local saved-workflow support — the saved-workflow verbs now work with
--where localvia ComfyUI's/userdata(#486). comfy downloadcopies on-disk local outputs instead of refusing them (#485).- Python 3.14 —
comfy launch --backgroundno longer crashes on the removed implicit event loop (#481). - ROCm 7.2 support added and set as the default (#476).
Hardening & internals
- Shared IPv6-aware
host:portresolver forcomfy run(#488) - Consolidated redirect-refusal and SSRF loopback guards into
comfy_cli/http.py(#487, #482) - Centralized the
wheredefault config read viawhere.resolve_default()(#477) - Module-local
_emit_http_errorhelper in models/search (#484)
CI & repo
- CLA Assistant workflow + author-only allowlist (#473, #489)
- Label-triggered Cursor review workflow (#483)
- Bump
actions/checkout6 → 7 (#475)
Full changelog: v1.11.1...v1.12.0
v1.11.1 — agent-first CLI
The first PyPI-published cut of the agent-first comfy-cli. (v1.11.0 was tagged but did not publish to PyPI due to a release-trigger mismatch — v1.11.1 is the first published release of this line; identical code.)
An agent (or a human) can build, validate, run, and review image/video/audio workflows on a local server or Comfy Cloud, entirely from the terminal — with a stable machine contract underneath. Fully additive and backward-compatible for interactive use.
✨ Highlights
- One machine contract. Every command emits the same versioned JSON envelope; every error carries a registered code + an actionable hint. Agents never parse prose. (
--json, auto on non-TTY.) - A compile model for workflows. Author typed fragments, wire them with YAML blueprints into one graph (
comfy workflow compose);comfy workflow decomposeis the inverse. Folders are source; the compiled JSON is a build artifact. - Pre-flight validation (CQL).
comfy validatechecks a graph against the live server'sobject_infobefore you spend. - Async-by-default execution with
comfy jobs— incl.comfy jobs wait <id…>to block on a whole batch at once. - Projects (
project/1layout, content-addressedassets push, run journal,--whererouting). comfy preview— image → thumbnail, video → contact sheet, audio → waveform.- Bundled skills (
comfy skills) that teach agents to operate · build · debug · present. - One-step onboarding —
comfy setupwizard, surfaced from the welcome screen and a first-run nudge. - Install robustness —
install/updateno longer assume the workspace interpreter ships pip.
⚠️ One compatibility note
Interactive (terminal) use is unchanged. The one behavior change: piped/redirected output now defaults to JSON (this is what makes agents work out-of-the-box). For the old text output, pass --no-json or set COMFY_OUTPUT=pretty.
📦 Upgrade
pip install -U comfy-cli
comfy setupv1.11.0 — agent-first CLI
This release turns comfy-cli into an agent-first tool: an agent (or a human) can build, validate, run, and review image/video/audio workflows on a local server or Comfy Cloud, entirely from the terminal — with a stable machine contract underneath. Everything is additive and backward-compatible for interactive use; your existing commands and scripts keep working (see the one compatibility note below).
✨ Highlights
- One machine contract. Every command emits the same versioned JSON envelope, and every error carries a registered code + an actionable hint — an error is a navigation signal toward the fix, not just a failure. Agents never parse prose. (
--json, auto on non-TTY.) - A compile model for workflows. Author small typed fragments and wire them with YAML blueprints into one graph (
comfy workflow compose);comfy workflow decomposeis the inverse — it projects any workflow back into editable fragment source. Folders are source; the compiled JSON is a build artifact. - Pre-flight validation (CQL).
comfy validatechecks a graph against the live server'sobject_infobefore you spend — combo types preserved, enum rejections carry the full untruncated options list. - Async-by-default execution. Submit returns immediately, a detached watcher tracks the job, and later processes resume from a state file. New:
comfy jobs wait <id…>blocks on a whole batch at once (summary envelope, per-jobsettledevents,--all/--timeout). - Projects. A
project/1layout with content-addressedassets push, a run journal, and--whererouting (OAuth-first credentials). comfy preview— render any media to something viewable: image → thumbnail, video → contact sheet, audio → waveform.- Bundled skills (
comfy skills) that teach agents to operate · build · debug · present the CLI. - One-step onboarding.
comfy setup— a guided wizard (routing → sign-in → skills → verify). New users are now pointed at it from the welcome screen and a first-run nudge. - Install robustness.
comfy install/comfy updateno longer assume the workspace interpreter ships pip (a pip-less uv-managed venv is bootstrapped automatically).
⚠️ One compatibility note
Fully backward-compatible for interactive (terminal) use — same commands, same pretty output. The single behavior change: when output is piped or redirected (non-TTY), commands with structured output now default to JSON instead of text (this is what makes agents work out-of-the-box). If a script parses the old piped text, pass --no-json or set COMFY_OUTPUT=pretty.
📦 Upgrade
pip install -U comfy-cli
comfy setup # new here? this gets you from zero to runningv1.10.5
What's Changed
- Add Comfy-Usage-Source header to ComfyUI and cloud API requests by @robinjhuang in #468
- feat(node): add changelog support to comfy node publish by @bigcat88 in #469
- fix: broaden telemetry kwarg redaction and
_ctxfilter atomically by @mattmillerai in #459
New Contributors
- @mattmillerai made their first contribution in #459
Full Changelog: v1.10.4...v1.10.5
v1.10.4
What's Changed
- Add unreviewed-merge detector (SOC 2 compliance) by @luke-mino-altherr in #464
- feat(tracking): namespace PostHog events with cli: prefix by @robinjhuang in #465
New Contributors
- @luke-mino-altherr made their first contribution in #464
Full Changelog: v1.10.3...v1.10.4