Skip to content

feat: add read-only comfy outdated verb (core + node pack versions vs latest) (BE-3396)#561

Open
mattmillerai wants to merge 2 commits into
mainfrom
matt/be-3396-outdated-verb
Open

feat: add read-only comfy outdated verb (core + node pack versions vs latest) (BE-3396)#561
mattmillerai wants to merge 2 commits into
mainfrom
matt/be-3396-outdated-verb

Conversation

@mattmillerai

Copy link
Copy Markdown
Collaborator

ELI-5

Your ComfyUI install can quietly fall behind — an old core or an old node pack
can silently degrade agents (BE-3352). This adds a new read-only command,
comfy outdated, that tells you, at a glance, whether your ComfyUI core and
each custom node pack is up to date with the latest release. It never
changes anything — it just reads git metadata / pyproject.toml and asks the
GitHub + Comfy registry APIs what "latest" is.

$ comfy outdated
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┓
┃ component      ┃ installed ┃ latest  ┃ status   ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━┩
│ ComfyUI (core) │ v0.3.40   │ v0.3.41 │ outdated │
│ my-cool-pack   │ 1.0.0     │ 1.2.0   │ outdated │
└────────────────┴───────────┴─────────┴──────────┘

comfy outdated --json emits the standard envelope for agents. Latest-version
lookups are cached for 1h under ~/.cache/comfy-cli/outdated.json; --refresh
bypasses the cache.

What & how

  • New top-level comfy outdated (comfy_cli/cmdline.py, beside update) —
    read-only, resolves the workspace via workspace_manager.workspace_path (same
    as update), renders via the existing get_renderer().emit (pretty table /
    JSON envelope).
  • Core: git describe --tags --always + short HEAD for a git checkout,
    falling back to comfyui_version.py's __version__ then pyproject.toml.
    Latest = GitHub releases/latest, reusing install.get_latest_release
    (rate-limit-aware, honors GITHUB_TOKEN).
  • Packs: walk <workspace>/custom_nodes/*; a pack whose pyproject.toml
    carries a registry id+version is a registry pack (latest via the
    comfy_cli.registry client); a bare git clone is a git pack (git ls-remote HEAD vs local HEAD).
  • Output: {core:{installed,commit,latest,outdated}, packs:[{name,source,installed,latest,outdated}], checked_at}.
    Registered a JSON schema (comfy_cli/schemas/outdated.json) and wired it into
    discovery.COMMAND_SCHEMAS (the schema-registration ratchet test enforces this).
  • Cache 1h; --refresh bypasses. Any network failure degrades to
    latest: null + a warning and exit 0
    — a report that can't reach the
    network is still useful.

Tests

tests/comfy_cli/command/test_outdated.py builds a real fixture workspace
(git-checkout core + one registry pack + one git pack, the git pack cloned from
a local bare remote so it's fully offline) with mocked GitHub/registry HTTP.
Covers: stale-install verdicts, up-to-date, network-failure → latest: null +
exit 0, the 1h warm cache (serves latest even when the network is down),
--refresh bypass, the JSON envelope contract (single clean line on stdout),
and schema validation. Ran ruff check + ruff format (clean on new files)
and the full tests/comfy_cli/command + tests/comfy_cli/output suites green.

Judgment calls / deviations from the ticket

  • Reused install.get_latest_release for core latest instead of hand-rolling
    a GitHub call. Its timeout is 5s (ticket suggested 10s) — reusing the
    rate-limit-aware fetcher is worth the smaller budget, and warm-cache calls are
    ~0.8s regardless. Acceptance (<5s warm cache) is met.
  • Registry latest via RegistryAPI.install_node(id) (the client's
    latest-version accessor, hits /nodes/{id}/install) rather than a raw
    /nodes/{id} call — honors "reuse the registry client rather than hand-rolling."
  • Added two fields beyond the ticket's shape (additive, non-breaking): core
    commit (short HEAD) and each pack's source (registry/git/unknown).
  • Self-review fix: a shallow / no-tag core checkout resolves via git describe --always to a bare SHA. Comparing a SHA to a version tag is
    incomparable, so _is_outdated returns False there (rather than a false
    "outdated") while still treating SHA-vs-SHA differences (git packs) as behind.
    Regression-tested.
  • Parser side-warnings from the shared extract_node_configuration (e.g. a pack
    with no license) are routed to stderr so they never corrupt the single JSON
    envelope on stdout.

Not a capability-denial change (no dead-end / "not supported" path) — it's a
purely additive read-only report, so the negative-claim falsification gate
doesn't apply.

@mattmillerai mattmillerai added agent-coded PR authored by the agent-work loop cursor-review Request Cursor bot review labels Jul 18, 2026
@mattmillerai
mattmillerai marked this pull request as ready for review July 18, 2026 00:41
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 18, 2026
@coderabbitai

coderabbitai Bot commented Jul 18, 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: 44 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: fd7d6a86-7eff-4d28-9170-e98177f68a6f

📥 Commits

Reviewing files that changed from the base of the PR and between a732f5c and fa69a6a.

📒 Files selected for processing (6)
  • comfy_cli/cmdline.py
  • comfy_cli/command/outdated.py
  • comfy_cli/discovery.py
  • comfy_cli/registry/api.py
  • comfy_cli/schemas/outdated.json
  • tests/comfy_cli/command/test_outdated.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch matt/be-3396-outdated-verb
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch matt/be-3396-outdated-verb

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

@dosubot dosubot Bot added the enhancement New feature or request label Jul 18, 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 10 finding(s).

Severity Count
🔴 Critical 1
🟠 High 3
🟡 Medium 3
🟢 Low 3

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/command/outdated.py Outdated
Comment thread comfy_cli/command/outdated.py Outdated
Comment thread comfy_cli/command/outdated.py Outdated
Comment thread comfy_cli/command/outdated.py
Comment thread comfy_cli/command/outdated.py Outdated
Comment thread comfy_cli/command/outdated.py
Comment thread comfy_cli/command/outdated.py
Comment thread comfy_cli/command/outdated.py
Comment thread comfy_cli/command/outdated.py Outdated
Comment thread comfy_cli/command/outdated.py Outdated
Root-cause the CI build failure and address the cursor-review panel on
comfy_cli/command/outdated.py:

- test fixture: pin the git-pack bare repo to `-b main` so `ls-remote HEAD`
  resolves on runners whose `init.defaultBranch` is `master` (the 2
  test_outdated failures).
- git-pack RCE hardening: restrict transports (drop ext::/git://), pin
  GIT_SSH_COMMAND, clear credential.helper/core.fsmonitor, and add `--`
  before the origin URL in ls-remote (option-injection). Applied to every
  git call since cwd sits in an untrusted pack.
- redirect get_latest_release stdout to stderr so a network error can't
  corrupt the single-line JSON envelope.
- RegistryAPI.install_node: add a request timeout so a stalled registry
  can't hang `comfy outdated`.
- escape pack names/versions/warnings through rich markup (MarkupError).
- fall back to the git HEAD comparison when a pyproject pack isn't in the
  registry, instead of reporting it permanently unknown.
- warn on a missing origin remote; catch UnicodeDecodeError on a corrupt
  cache.

Adds tests for the fallback, missing-origin warning, and ext:: rejection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jul 18, 2026
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:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant