Skip to content

feat: emit envelope/1 for comfy launch / comfy stop under --json - #588

Open
mattmillerai wants to merge 2 commits into
mainfrom
matt/be-4273-launch-stop-json-envelope
Open

feat: emit envelope/1 for comfy launch / comfy stop under --json#588
mattmillerai wants to merge 2 commits into
mainfrom
matt/be-4273-launch-stop-json-envelope

Conversation

@mattmillerai

Copy link
Copy Markdown
Collaborator

ELI-5

Every comfy command run with --json prints one machine-readable
envelope/1 object on stdout so tools can parse the result. Two commands —
comfy launch and comfy stop — forgot to do that, so a program calling
them got nothing back and had to guess whether it worked. This teaches those
two commands to print the same envelope everyone else does. Humans running
the commands normally see exactly the same output as before.

Closes #509.

What & why

comfy launch and comfy stop ignored the global --json flag: unlike
every other subcommand they emitted no envelope/1 on stdout. Programmatic
callers (e.g. comfy-local-mcp's launch_comfyui / stop_comfyui, which parse
the versioned envelope) got nothing machine-readable and had to special-case
these two commands. This completes the existing --json contract for them —
no new user-visible UI.

What changed

  • comfy stop emits an envelope on every path: success
    (data.stopped/host/port/pid), no background server recorded
    (error.code = no_background_server), and kill failure
    (error.code = stop_failed).
  • comfy launch emits an envelope on every reachable path:
    • background success (data.background=true, url, pid) — emitted from
      the monitor right before it os._exit(0)s, via a small extracted
      _emit_launch_success helper so it is unit-testable;
    • background errors: server_already_running, port_invalid,
      port_in_use, and launch_failed (log-open failure or no success line);
    • workspace-not-available: not_in_workspace;
    • foreground exit: success envelope on clean exit, launch_failed on a
      non-zero return code.
  • Registered launch/stop output schemas in comfy discover and the new
    lifecycle error codes in the error_codes registry (both are enforced by
    existing contract tests).

Human output is unchanged

Every emission is guarded by if renderer.is_json():, so pretty mode prints
only the existing Rich lines and keeps the same process exit codes. A test
asserts stdout carries no JSON in pretty mode.

Tests

tests/comfy_cli/command/test_launch_stop_envelope.py asserts the envelope
(schema, ok, command, data/error) on the launch and stop success and
error paths, plus the pretty-mode purity check. Full suite green
(2678 passed, 13 skipped); ruff check + ruff format clean on changed
files.

Notes / judgment calls

  • Foreground comfy launch is a blocking, interactive server — its
    "success" envelope is only emitted when the server process exits. Streaming
    progress (--json-stream) is explicitly out of scope; an agent uses
    --background, which is the fully-covered path.
  • _emit_launch_success was extracted specifically because the success path
    os._exit(0)s immediately, which is otherwise untestable without killing
    the test process.
  • No behavior/exit-code changes on any existing path; this is purely additive
    machine output. No capability is denied — the error envelopes mirror
    pre-existing human error messages that already raised/exited.

comfy launch and comfy stop previously ignored the global --json flag,
emitting no envelope/1 object on stdout unlike every other subcommand.
Programmatic callers (e.g. comfy-local-mcp's launch_comfyui / stop_comfyui
tools, which parse envelope/1) had to special-case these two commands.

Add envelope emission on every reachable success and error path for both
commands, guarded by renderer.is_json() so human (pretty) output and exit
codes are unchanged. Register launch/stop schemas in discovery and the new
lifecycle error codes in the registry.
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 4 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6734183e-b4ac-4beb-819b-d3c2896283bb

📥 Commits

Reviewing files that changed from the base of the PR and between 85b62da and 9077571.

📒 Files selected for processing (7)
  • comfy_cli/cmdline.py
  • comfy_cli/command/launch.py
  • comfy_cli/discovery.py
  • comfy_cli/error_codes.py
  • comfy_cli/schemas/launch.json
  • comfy_cli/schemas/stop.json
  • tests/comfy_cli/command/test_launch_stop_envelope.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch matt/be-4273-launch-stop-json-envelope
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch matt/be-4273-launch-stop-json-envelope

Comment @coderabbitai help to get the list of available commands.

@mattmillerai mattmillerai added agent-coded PR authored by the agent-work loop cursor-review Request Cursor bot review labels Jul 24, 2026
@mattmillerai
mattmillerai marked this pull request as ready for review July 24, 2026 05:24
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Jul 24, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Cursor Review — Consolidated panel

Triggered by @mattmillerai.

Found 7 finding(s).

Severity Count
🟠 High 1
🟡 Medium 2
🟢 Low 3
⚪ Nit 1

Panel: 6/8 reviewers contributed findings.

Reviewers that did not contribute: kimi-k2.5:adversarial (empty), kimi-k2.5:edge-case (empty)

Comment thread comfy_cli/cmdline.py Outdated
Comment thread comfy_cli/cmdline.py Outdated
Comment thread comfy_cli/command/launch.py
Comment thread comfy_cli/command/launch.py Outdated
Comment thread comfy_cli/command/launch.py Outdated
Comment thread comfy_cli/command/launch.py
Comment thread comfy_cli/command/launch.py Outdated
- stop: keep the background record when kill_all fails (was unconditionally
  removed, orphaning a live server that a retried `comfy stop` could no
  longer target); raise typer.Exit(1) on the failure path so pretty mode
  exits non-zero too, not just --json.
- launch: parse the `--port=`/`--listen=` single-token form (was ignored,
  leaving port at the 8188 default that disagreed with the bound port).
- launch: range-check --port to 1-65535 for a precise port_invalid verdict.
- launch: cap the launch_failed `details.log` payload via the existing
  LOGS_MAX_LINES/LOGS_MAX_BYTES bounds (was unbounded, could leak secrets).
- launch: bracket IPv6 hosts in emitted/printed URLs via shared _bracket_host.
- launch: redirect the foreground child's stdout to stderr under --json so
  the single-envelope-on-stdout contract holds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-coded PR authored by the agent-work loop cursor-review Request Cursor bot review enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

launch/stop ignore --json: no envelope output for lifecycle commands

1 participant