test: lint comfy hint-strings + snapshot the command inventory - #516
test: lint comfy hint-strings + snapshot the command inventory#516mattmillerai wants to merge 8 commits into
Conversation
…comfy auth login` The `auth` command group manages third-party model-host API tokens (Civitai, Hugging Face) and has no `login` subcommand. Comfy Cloud sign-in is `comfy cloud login`. Seven help/hint/error strings (plus a stale comment) pointed users and agents at the dead `comfy auth login`, including the agent-facing `jobs --where` option help. Correct them all and tighten the signed-out banner tests to guard the hint.
The interactive demo's sign-in step invoked `comfy auth whoami`, which was deliberately removed (test_legacy_auth_whoami_is_gone) — the command now lives at `comfy cloud whoami`. Update the step title, both invocations, and the capabilities summary so the walkthrough runs a command that actually exists. Adjust the step-coverage test needle from "auth" to "whoami" to match. Addresses cursor-review (gemini-3.1-pro edge-case) thread on PR #512. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Four cloud error paths (job cancel, workflow HTTP errors, cloud model list/search) still pointed users at `comfy auth whoami`, which does not exist — the `auth` group only has list/set/remove, and sign-in status lives under `comfy cloud whoami`. Same class of bug this PR set out to fix for `auth login`. Also strengthen the run_cli demo test per CodeRabbit: assert the whoami step's argv/labels target `cloud whoami` and never `auth whoami`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add two anti-rot CLI-surface guards, mirroring the MCP server's EXPECTED_TOOLS + description-budget snapshot pattern: - Hint-string lint: extract every backtick/shell-hint `comfy …` invocation from help text, docstrings, hint/error strings, examples, and bundled skill docs, then validate each against the registered command set by walking the Typer app tree. Fails naming the offending string + file. A regression fixture pins that it flags the historical `comfy auth login` rot (and the sibling `auth whoami`). - Command-inventory snapshot: snapshot the full command tree so surface additions/removals/hides are explicit diffs in review. Regenerate with UPDATE_CLI_SNAPSHOT=1 pytest tests/comfy_cli/test_cli_surface.py. The lint immediately surfaced live rot: five hint strings pointed at the nonexistent `comfy auth whoami` (deliberately removed — see test_legacy_auth_whoami_is_gone). Route them to the real `comfy cloud whoami`. The remaining `comfy query` rot (CQL surface documented but no command registered) is baselined for a separate fix.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
🔍 Cursor Review — Consolidated panel
Triggered by @mattmillerai.
Judge call failed (status=parse_error): Could not parse JSON findings from output. First 500 chars:
I have enough to adjudicate. The shell/web tools are blocked in this environment, so I verified everything by reading the actual file and reasoning from Python internals.
Key adjudication decisions:
- **Dropped the gemini "high" AttributeError claim (line 172).** The claim that `ast.Constant` nodes inside f-strings lack `.lineno` in Python 3.10/3.11 is false — parsed f-string literal parts carry valid (if historically imprecise) position info; `.lineno` never raises `AttributeError` on parsed
Re-trigger by removing and re-adding the cursor-review label.
This PR is scoped to routing user-facing `comfy auth login`/`auth whoami` hints at the real `comfy cloud login`/`cloud whoami` commands. It had also picked up a 287-line `uv.lock` re-sync that locks `anthropic`, `pydantic`, and `pydantic-core` — unrelated to the hint strings and not load-bearing for any test here. main's lockfile is genuinely stale (`uv lock --check` fails on main: the `bench` extra declares `anthropic>=0.40` but was never locked), so the re-sync is real work — just not this PR's. No CI job consumes `uv.lock` (ci-cursor-review explicitly excludes it), so reverting restores main's status quo with no regression. Tracked as a follow-up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Both conflicts were cosmetic overlaps from main's own auth-copy cleanup (BE-2996, #616) landing alongside this branch's identical intent: - test_run_cli.py: keep main's "cloud whoami" needle (matches the actual step title produced by run_cli.py) - test_branding.py: keep both assertions — main's tightened "comfy cloud login" check plus this branch's "comfy auth login" not in out guard
…' into matt/be-2979-hint-lint-discover-snapshot # Conflicts: # tests/comfy_cli/command/test_run_cli.py
Merging in the base branch pulled in a wave of new commands from main (model downloads, node deps, run-template, system-stats, workflow notes, etc.) that weren't in this PR's committed inventory snapshot. Separately, the base's run-cli rewrite already replaced the invalid `comfy query` reference with `comfy nodes ls`, so that BASELINE_INVALID_REFS entry is now stale per test_baseline_is_not_stale's own contract.
skishore23
left a comment
There was a problem hiding this comment.
The command-inventory snapshot here is genuinely valuable and I'd like to see it land — main has no equivalent. But the lint half is now a duplicate of a stronger guard that already shipped, and I think it should come out before merge. Details below; it's a small, surgical cut.
The overlap
This PR was opened 2026-07-14. Since then #616 ("fix: point CLI copy at commands that exist + lint it", BE-2996) landed on main on 2026-07-28, adding comfy_cli/command_mentions.py + tests/comfy_cli/test_command_mentions.py — the same hint-string lint, same ticket family. After merging origin/main into this head, the branch carries both.
That alone would just be redundancy. The problem is which one is weaker.
The lint in this PR has a blind spot main's has already closed
_leading_command_tokens stops at the first token that isn't [a-z][a-z0-9-]*, so a leading global option swallows the whole reference. main's resolver deliberately skips root-callback options and keeps scanning. Ran both against the same strings on the merged tree:
| reference | this PR flags | main flags |
|---|---|---|
comfy --json auth login |
False | True |
comfy auth login |
True | True |
comfy --where cloud auth whoami |
False | True |
comfy --json cloud singin |
False | True |
main has an explicit regression test for exactly this (test_invalid_mentions_are_flagged[comfy --json auth login-login]) with a comment noting that otherwise "prefixing the bad command with --json would hide it from the lint entirely."
Two further gaps: this lint scans comfy_cli/**/*.py + comfy_cli/**/*.md but not README.md (main scans it, and has test_scan_reaches_the_readmes_fenced_examples), and _WHOLE_LINE's [a-z0-9 _-]*$ can't match a bare line carrying a path, so comfy run --workflow ./workflow.json isn't extracted.
To be clear: merging this does not weaken anything — main's lint still catches all of the above, so combined coverage is unchanged. The cost is maintenance, and it's real: ~200 lines of parallel extraction logic, and two separate allowlists (ALLOWED_NONINVOKABLE_REFS / BASELINE_INVALID_REFS here vs PROSE_SCAN_EXCLUDED there). A contributor who adds a command and gets flagged has to know both exist and update the right one. The weaker implementation is also the one with the more inviting name (test_cli_surface.py), so it's the one people will reach for.
What I'd suggest
Keep test_command_inventory_snapshot + _command_inventory() + the fixture; drop test_no_invalid_command_references, test_baseline_is_not_stale, test_lint_catches_auth_login_and_friends, and the extraction helpers (_refs_in_text, _leading_command_tokens, _ref_is_valid, _command_tree, _iter_source_strings, _scan_invalid_references, both allowlists, the three regexes). The snapshot test only needs build_help_json, so it's cleanly separable — no dependency on any of the lint machinery.
If any of the three lint tests cover a case main's doesn't, the better move is to port that case into tests/comfy_cli/test_command_mentions.py rather than keep a second scanner alive.
What I verified (all green)
- Merged
origin/maininto the head — clean merge, no conflicts. test_cli_surface.py+test_command_mentions.py— 35 passed together.- The snapshot is not stale: regenerated it with
UPDATE_CLI_SNAPSHOT=1against currentmainand diffed — zero drift, 152 entries. Nice job reconciling that in21a890f. BASELINE_INVALID_REFSis now empty, so thecomfy queryrot mentioned in the description is already resolved — the description's "baselined for a separate fix" paragraph is stale and should come out of the squash message.
Happy to flip to approve on a push that drops the duplicate lint — or, if you'd rather keep both and reconcile later, say so and I'll approve as-is; the coverage argument above is about maintenance cost, not correctness.
ELI-5
Some of the CLI's help messages and error hints told you to run commands that
don't exist — like
comfy auth login(the real one iscomfy cloud login).Nobody noticed for a long time. This adds two tests that act like a spell-checker
for command names:
comfy …command mentioned in help text, hints,and error messages and checks each one is a real registered command. If a
string points at a command that doesn't exist, the test fails and names the
exact string + file.
up as an obvious diff in review (mirrors the MCP server's
EXPECTED_TOOLSpattern).
Turning the lint on immediately caught live rot — five hints pointed at the
removed
comfy auth whoami— so those are corrected tocomfy cloud whoamitoo.What & why
The MCP server prevents help/hint rot with
EXPECTED_TOOLS+ description-budgetsnapshot tests; the CLI had no equivalent, which is how seven strings referenced
the nonexistent
comfy auth loginfor who knows how long.1. Hint-string lint (
tests/comfy_cli/test_cli_surface.py)comfy …invocation — backtick-quoted,run:/$-prefixed shell hints, and whole-string command lines — from allPython string literals (docstrings,
help=/hint=/message=kwargs,examples) and bundled skill docs, scanned via AST so comments and code
identifiers are never mistaken for references.
tree (
build_help_json). Correctly accepts groups, leaves-plus-args(
comfy generate list), and hidden commands (comfy agent-review); flags the"valid group + nonexistent subcommand" rot class (
comfy auth login/whoami).like "the comfy skills into Claude Code" is not mistaken for a command
(verified: zero false positives across the whole package).
2. Command-inventory snapshot — snapshots every command path (groups +
leaves, with a
[hidden]marker) totests/comfy_cli/fixtures/cli_command_inventory.txt.Regenerate after an intentional surface change with one command:
Both run under the normal
pytestinvocation, so they gate every PR in CI.Rot the lint surfaced (and what this PR does about it)
comfy auth whoami(5 hints) →comfy cloud whoami.auth whoamiwasdeliberately removed (there is an existing
test_legacy_auth_whoami_is_gone);the hints were stale. All five are cloud-auth contexts, so they route to the
real
comfy cloud whoami. Fixed here.comfy query(2 refs — an example + acomfy run-clidemo step). The CQLquery surface is documented but no
querycommand is registered on the app.Whether to wire one up or rewrite the examples is a product call, so it is
baselined (
BASELINE_INVALID_REFS) for a separate fix rather than bundledinto this guard.
test_baseline_is_not_stalefails the moment it's fixed,forcing the baseline entry to be removed so the allowlist can't outlive the bug.
comfy versionis allowlisted — it's the--versionflag's output-envelopecommand name (in
discovery.COMMAND_SCHEMAS), not an invokable subcommand.Acceptance
auth loginrefs — pinned by the regressionfixture in
test_lint_catches_auth_login_and_friends(backtick,run:, andwhole-string forms), per the ticket's "add one as a regression fixture" note.
pytest, picked up by the existing pytestworkflow.
Notes for the reviewer
auth loginhints tocomfy cloud login; the live lint depends on those being fixed to stay green.GitHub will retarget this to
mainwhen that PR merges.auth whoami → cloud whoamicorrections the lint immediately surfaced.tests/comfy_clisuite green (2475 passed, 13 skipped);ruff check+ruff formatclean.Judgment calls
auth whoamirot inline (clean, unambiguous, test-backed) butbaselined
comfy query(needs a product decision) — kept this PR focused onthe guard plus the rot that's mechanically safe to fix.
*.mdskill docs too (agent-facing help); all currentrefs there are valid.