comfy-cli 1.7.3__tar.gz → 1.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/PKG-INFO +80 -27
  2. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/README.md +79 -26
  3. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/cmdline.py +19 -1
  4. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/code_search.py +46 -14
  5. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/custom_nodes/command.py +11 -0
  6. comfy_cli-1.9.0/comfy_cli/command/generate/__init__.py +3 -0
  7. comfy_cli-1.9.0/comfy_cli/command/generate/app.py +464 -0
  8. comfy_cli-1.9.0/comfy_cli/command/generate/client.py +152 -0
  9. comfy_cli-1.9.0/comfy_cli/command/generate/output.py +105 -0
  10. comfy_cli-1.9.0/comfy_cli/command/generate/poll.py +381 -0
  11. comfy_cli-1.9.0/comfy_cli/command/generate/schema.py +273 -0
  12. comfy_cli-1.9.0/comfy_cli/command/generate/spec.py +403 -0
  13. comfy_cli-1.9.0/comfy_cli/command/generate/upload.py +128 -0
  14. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/install.py +138 -9
  15. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/run.py +103 -23
  16. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/git_utils.py +20 -3
  17. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/registry/config_parser.py +203 -5
  18. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/tracking.py +9 -1
  19. comfy_cli-1.9.0/comfy_cli/workflow_to_api.py +1369 -0
  20. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli.egg-info/PKG-INFO +80 -27
  21. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli.egg-info/SOURCES.txt +9 -0
  22. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/pyproject.toml +1 -1
  23. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/LICENSE +0 -0
  24. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/__init__.py +0 -0
  25. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/__main__.py +0 -0
  26. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/__init__.py +0 -0
  27. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/custom_nodes/__init__.py +0 -0
  28. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/custom_nodes/bisect_custom_nodes.py +0 -0
  29. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/custom_nodes/cm_cli_util.py +0 -0
  30. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/github/pr_info.py +0 -0
  31. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/launch.py +0 -0
  32. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/models/models.py +0 -0
  33. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/command/pr_command.py +0 -0
  34. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/config_manager.py +0 -0
  35. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/constants.py +0 -0
  36. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/cuda_detect.py +0 -0
  37. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/env_checker.py +0 -0
  38. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/file_utils.py +0 -0
  39. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/logging.py +0 -0
  40. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/pr_cache.py +0 -0
  41. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/registry/__init__.py +0 -0
  42. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/registry/api.py +0 -0
  43. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/registry/types.py +0 -0
  44. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/resolve_python.py +0 -0
  45. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/standalone.py +0 -0
  46. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/typing.py +0 -0
  47. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/ui.py +0 -0
  48. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/update.py +0 -0
  49. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/utils.py +0 -0
  50. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/uv.py +0 -0
  51. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli/workspace_manager.py +0 -0
  52. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli.egg-info/dependency_links.txt +0 -0
  53. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli.egg-info/entry_points.txt +0 -0
  54. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli.egg-info/requires.txt +0 -0
  55. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/comfy_cli.egg-info/top_level.txt +0 -0
  56. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/setup.cfg +0 -0
  57. {comfy_cli-1.7.3 → comfy_cli-1.9.0}/tests/test_file_utils_network.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comfy-cli
3
- Version: 1.7.3
3
+ Version: 1.9.0
4
4
  Summary: A CLI tool for installing and using ComfyUI.
5
5
  Maintainer-email: Yoland Yan <yoland@drip.art>, James Kwon <hongilkwon316@gmail.com>, Robin Huang <robin@drip.art>, "Dr.Lt.Data" <dr.lt.data@gmail.com>
6
6
  License: GPL-3.0-only
@@ -52,11 +52,10 @@ Dynamic: license-file
52
52
  [![Python](https://img.shields.io/pypi/pyversions/comfy-cli)](https://pypi.org/project/comfy-cli/)
53
53
  [![License](https://img.shields.io/pypi/l/comfy-cli)](https://github.com/Comfy-Org/comfy-cli/blob/main/LICENSE)
54
54
 
55
- comfy-cli is a command line tool that helps users easily install and manage
56
- [ComfyUI](https://github.com/comfyanonymous/ComfyUI), a powerful open-source
57
- machine learning framework. With comfy-cli, you can quickly set up ComfyUI,
58
- install packages, and manage custom nodes, all from the convenience of your
59
- terminal.
55
+ comfy-cli is a command-line tool for installing, running, and extending
56
+ [ComfyUI](https://github.com/comfyanonymous/ComfyUI) the open-source
57
+ generative-media engine. Set up ComfyUI, install custom nodes and models, run
58
+ workflows, and call hosted partner image models, all from your terminal.
60
59
 
61
60
  ## Demo
62
61
 
@@ -64,29 +63,32 @@ terminal.
64
63
 
65
64
  ## Features
66
65
 
67
- - 🚀 Easy installation of ComfyUI with a single command
68
- - 📦 Seamless package management for ComfyUI extensions and dependencies
69
- - 🔧 Custom node management for extending ComfyUI's functionality
70
- - 🗄️ Download checkpoints and save model hash
71
- - 💻 Cross-platform compatibility (Windows, macOS, Linux)
72
- - 📖 Comprehensive documentation and examples
73
- - 🎉 install pull request to ComfyUI automatically
66
+ - 🚀 One-command ComfyUI install and launch
67
+ - 🎨 Direct calls to partner image and video nodes (Flux, Ideogram, DALL·E, Recraft, Stability, Kling, Luma, Runway, Pika, Vidu, Hailuo, …) via `comfy generate`, no workflow JSON required
68
+ - 🔧 Custom node management install, update, snapshot, bisect
69
+ - 📦 Fast dependency resolution with `uv` (`--fast-deps`, `--uv-compile`)
70
+ - 🗄️ Model downloads from CivitAI, Hugging Face, and direct URLs
71
+ - 🎬 Run workflows against a local ComfyUI server, including auto-conversion of UI-format JSON
72
+ - 🧪 Test ComfyUI and frontend pull requests with one flag
73
+ - 💻 Cross-platform: Windows, macOS, Linux
74
74
 
75
75
  ## Installation
76
76
 
77
- 1. (Recommended, but not necessary) Enable virtual environment ([venv](https://docs.python.org/3/library/venv.html)/[conda](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html))
77
+ 1. (Recommended) Activate a virtual environment ([venv](https://docs.python.org/3/library/venv.html) or [conda](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html)).
78
78
 
79
- 2. To install comfy-cli, make sure you have Python 3.9 or higher installed on your system. Then, run the following command:
79
+ 2. Install with `pip` (requires Python 3.10+):
80
80
 
81
- `pip install comfy-cli`
81
+ ```bash
82
+ pip install comfy-cli
83
+ ```
82
84
 
83
85
  ### Shell Autocomplete
84
86
 
85
- To install autocompletion hints in your shell run:
87
+ Install shell completion so `comfy <TAB>` expands commands and options:
86
88
 
87
- `comfy --install-completion`
88
-
89
- This enables you to type `comfy [TAP]` to autocomplete commands and options
89
+ ```bash
90
+ comfy --install-completion
91
+ ```
90
92
 
91
93
  ## Usage
92
94
 
@@ -329,6 +331,57 @@ the bisect tool can help you pinpoint the custom node that causes the issue.
329
331
 
330
332
  `comfy model list ?[--relative-path <PATH>]`
331
333
 
334
+ ### Calling partner nodes (`comfy generate`)
335
+
336
+ `comfy generate` calls Comfy's partner nodes directly from the terminal — no
337
+ local ComfyUI or workflow JSON required. It hits the same hosted partner nodes
338
+ you'd otherwise wire into a ComfyUI workflow, but as one-shot CLI calls. Image
339
+ models (Flux, Ideogram, DALL·E, Recraft, Stability, Runway, Reve, xAI Grok, …)
340
+ and video models (Kling, Luma, Runway Gen-3, Pika, Vidu, Moonvalley, Hailuo,
341
+ Grok video) are all covered; video jobs run async and the CLI polls until the
342
+ result is ready.
343
+
344
+ Prerequisites — a Comfy API key and a credit balance:
345
+
346
+ - [Create an API key](https://docs.comfy.org/development/comfyui-server/api-key-integration)
347
+ - [Browse partner nodes and per-call credit costs](https://docs.comfy.org/tutorials/partner-nodes/overview) · [pricing table](https://docs.comfy.org/tutorials/partner-nodes/pricing)
348
+ - [Add credits](https://docs.comfy.org/interface/credits)
349
+
350
+ Set the key once, then go:
351
+
352
+ ```bash
353
+ export COMFY_API_KEY=comfyui-... # or pass --api-key on each call
354
+
355
+ comfy generate list # browse available models
356
+ comfy generate schema flux-pro # see params for one model
357
+ comfy generate flux-pro --prompt "a cat on the moon" \
358
+ --width 1024 --height 1024 --download cat.png
359
+ ```
360
+
361
+ Reference images can be passed as local paths — the CLI uploads them through
362
+ the cloud's storage endpoint (or base64-encodes inline, as each partner
363
+ requires):
364
+
365
+ ```bash
366
+ comfy generate flux-kontext --prompt "add a top hat" \
367
+ --input_image ./photo.jpg --download out.png
368
+
369
+ comfy generate upload ./photo.jpg # explicit upload
370
+ ```
371
+
372
+ Async models (every video model plus the Flux family) block until ready by
373
+ default. Pass `--async` to return immediately with a job id, then resume later
374
+ with `comfy generate resume <model> <job_id>`. Examples:
375
+
376
+ ```bash
377
+ comfy generate kling --prompt "a paper boat drifting on a river at dusk" \
378
+ --duration 5 --download boat.mp4
379
+
380
+ comfy generate luma --prompt "..." --aspect_ratio 16:9 --async
381
+ # → prints job id; resume with:
382
+ comfy generate resume luma <job_id> --download out.mp4
383
+ ```
384
+
332
385
  ### Managing ComfyUI-Manager
333
386
 
334
387
  - Disable ComfyUI-Manager completely (no manager flags passed to ComfyUI):
@@ -414,19 +467,19 @@ Check out the usage here: [Mixpanel Board](https://mixpanel.com/p/13hGfPfEPdRkjP
414
467
 
415
468
  ## Contributing
416
469
 
417
- We welcome contributions to comfy-cli! If you have any ideas, suggestions, or
418
- bug reports, please open an issue on our [GitHub
419
- repository](https://github.com/yoland68/comfy-cli/issues). If you'd like to contribute code,
420
- please fork the repository and submit a pull request.
470
+ We welcome contributions to comfy-cli! For ideas, suggestions, or bug reports,
471
+ open an issue at [Comfy-Org/comfy-cli](https://github.com/Comfy-Org/comfy-cli/issues).
472
+ For code changes, fork the repo and open a pull request.
421
473
 
422
- Check out the [Dev Guide](/DEV_README.md) for more details.
474
+ See the [Dev Guide](/DEV_README.md) for setup details.
423
475
 
424
476
  ## License
425
477
 
426
- comfy is released under the [GNU General Public License v3.0](https://github.com/yoland68/comfy-cli/blob/master/LICENSE).
478
+ Released under the [GNU General Public License v3.0](https://github.com/Comfy-Org/comfy-cli/blob/main/LICENSE).
427
479
 
428
480
  ## Support
429
481
 
430
- If you encounter any issues or have questions about comfy-cli, please [open an issue](https://github.com/comfy-cli/issues) on our GitHub repository or contact us on [Discord](https://discord.com/invite/comfyorg). We'll be happy to assist you!
482
+ Questions or issues? [Open an issue](https://github.com/Comfy-Org/comfy-cli/issues)
483
+ or reach us on [Discord](https://discord.com/invite/comfyorg).
431
484
 
432
485
  Happy diffusing with ComfyUI and comfy-cli! 🎉
@@ -7,11 +7,10 @@
7
7
  [![Python](https://img.shields.io/pypi/pyversions/comfy-cli)](https://pypi.org/project/comfy-cli/)
8
8
  [![License](https://img.shields.io/pypi/l/comfy-cli)](https://github.com/Comfy-Org/comfy-cli/blob/main/LICENSE)
9
9
 
10
- comfy-cli is a command line tool that helps users easily install and manage
11
- [ComfyUI](https://github.com/comfyanonymous/ComfyUI), a powerful open-source
12
- machine learning framework. With comfy-cli, you can quickly set up ComfyUI,
13
- install packages, and manage custom nodes, all from the convenience of your
14
- terminal.
10
+ comfy-cli is a command-line tool for installing, running, and extending
11
+ [ComfyUI](https://github.com/comfyanonymous/ComfyUI) the open-source
12
+ generative-media engine. Set up ComfyUI, install custom nodes and models, run
13
+ workflows, and call hosted partner image models, all from your terminal.
15
14
 
16
15
  ## Demo
17
16
 
@@ -19,29 +18,32 @@ terminal.
19
18
 
20
19
  ## Features
21
20
 
22
- - 🚀 Easy installation of ComfyUI with a single command
23
- - 📦 Seamless package management for ComfyUI extensions and dependencies
24
- - 🔧 Custom node management for extending ComfyUI's functionality
25
- - 🗄️ Download checkpoints and save model hash
26
- - 💻 Cross-platform compatibility (Windows, macOS, Linux)
27
- - 📖 Comprehensive documentation and examples
28
- - 🎉 install pull request to ComfyUI automatically
21
+ - 🚀 One-command ComfyUI install and launch
22
+ - 🎨 Direct calls to partner image and video nodes (Flux, Ideogram, DALL·E, Recraft, Stability, Kling, Luma, Runway, Pika, Vidu, Hailuo, …) via `comfy generate`, no workflow JSON required
23
+ - 🔧 Custom node management install, update, snapshot, bisect
24
+ - 📦 Fast dependency resolution with `uv` (`--fast-deps`, `--uv-compile`)
25
+ - 🗄️ Model downloads from CivitAI, Hugging Face, and direct URLs
26
+ - 🎬 Run workflows against a local ComfyUI server, including auto-conversion of UI-format JSON
27
+ - 🧪 Test ComfyUI and frontend pull requests with one flag
28
+ - 💻 Cross-platform: Windows, macOS, Linux
29
29
 
30
30
  ## Installation
31
31
 
32
- 1. (Recommended, but not necessary) Enable virtual environment ([venv](https://docs.python.org/3/library/venv.html)/[conda](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html))
32
+ 1. (Recommended) Activate a virtual environment ([venv](https://docs.python.org/3/library/venv.html) or [conda](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html)).
33
33
 
34
- 2. To install comfy-cli, make sure you have Python 3.9 or higher installed on your system. Then, run the following command:
34
+ 2. Install with `pip` (requires Python 3.10+):
35
35
 
36
- `pip install comfy-cli`
36
+ ```bash
37
+ pip install comfy-cli
38
+ ```
37
39
 
38
40
  ### Shell Autocomplete
39
41
 
40
- To install autocompletion hints in your shell run:
42
+ Install shell completion so `comfy <TAB>` expands commands and options:
41
43
 
42
- `comfy --install-completion`
43
-
44
- This enables you to type `comfy [TAP]` to autocomplete commands and options
44
+ ```bash
45
+ comfy --install-completion
46
+ ```
45
47
 
46
48
  ## Usage
47
49
 
@@ -284,6 +286,57 @@ the bisect tool can help you pinpoint the custom node that causes the issue.
284
286
 
285
287
  `comfy model list ?[--relative-path <PATH>]`
286
288
 
289
+ ### Calling partner nodes (`comfy generate`)
290
+
291
+ `comfy generate` calls Comfy's partner nodes directly from the terminal — no
292
+ local ComfyUI or workflow JSON required. It hits the same hosted partner nodes
293
+ you'd otherwise wire into a ComfyUI workflow, but as one-shot CLI calls. Image
294
+ models (Flux, Ideogram, DALL·E, Recraft, Stability, Runway, Reve, xAI Grok, …)
295
+ and video models (Kling, Luma, Runway Gen-3, Pika, Vidu, Moonvalley, Hailuo,
296
+ Grok video) are all covered; video jobs run async and the CLI polls until the
297
+ result is ready.
298
+
299
+ Prerequisites — a Comfy API key and a credit balance:
300
+
301
+ - [Create an API key](https://docs.comfy.org/development/comfyui-server/api-key-integration)
302
+ - [Browse partner nodes and per-call credit costs](https://docs.comfy.org/tutorials/partner-nodes/overview) · [pricing table](https://docs.comfy.org/tutorials/partner-nodes/pricing)
303
+ - [Add credits](https://docs.comfy.org/interface/credits)
304
+
305
+ Set the key once, then go:
306
+
307
+ ```bash
308
+ export COMFY_API_KEY=comfyui-... # or pass --api-key on each call
309
+
310
+ comfy generate list # browse available models
311
+ comfy generate schema flux-pro # see params for one model
312
+ comfy generate flux-pro --prompt "a cat on the moon" \
313
+ --width 1024 --height 1024 --download cat.png
314
+ ```
315
+
316
+ Reference images can be passed as local paths — the CLI uploads them through
317
+ the cloud's storage endpoint (or base64-encodes inline, as each partner
318
+ requires):
319
+
320
+ ```bash
321
+ comfy generate flux-kontext --prompt "add a top hat" \
322
+ --input_image ./photo.jpg --download out.png
323
+
324
+ comfy generate upload ./photo.jpg # explicit upload
325
+ ```
326
+
327
+ Async models (every video model plus the Flux family) block until ready by
328
+ default. Pass `--async` to return immediately with a job id, then resume later
329
+ with `comfy generate resume <model> <job_id>`. Examples:
330
+
331
+ ```bash
332
+ comfy generate kling --prompt "a paper boat drifting on a river at dusk" \
333
+ --duration 5 --download boat.mp4
334
+
335
+ comfy generate luma --prompt "..." --aspect_ratio 16:9 --async
336
+ # → prints job id; resume with:
337
+ comfy generate resume luma <job_id> --download out.mp4
338
+ ```
339
+
287
340
  ### Managing ComfyUI-Manager
288
341
 
289
342
  - Disable ComfyUI-Manager completely (no manager flags passed to ComfyUI):
@@ -369,19 +422,19 @@ Check out the usage here: [Mixpanel Board](https://mixpanel.com/p/13hGfPfEPdRkjP
369
422
 
370
423
  ## Contributing
371
424
 
372
- We welcome contributions to comfy-cli! If you have any ideas, suggestions, or
373
- bug reports, please open an issue on our [GitHub
374
- repository](https://github.com/yoland68/comfy-cli/issues). If you'd like to contribute code,
375
- please fork the repository and submit a pull request.
425
+ We welcome contributions to comfy-cli! For ideas, suggestions, or bug reports,
426
+ open an issue at [Comfy-Org/comfy-cli](https://github.com/Comfy-Org/comfy-cli/issues).
427
+ For code changes, fork the repo and open a pull request.
376
428
 
377
- Check out the [Dev Guide](/DEV_README.md) for more details.
429
+ See the [Dev Guide](/DEV_README.md) for setup details.
378
430
 
379
431
  ## License
380
432
 
381
- comfy is released under the [GNU General Public License v3.0](https://github.com/yoland68/comfy-cli/blob/master/LICENSE).
433
+ Released under the [GNU General Public License v3.0](https://github.com/Comfy-Org/comfy-cli/blob/main/LICENSE).
382
434
 
383
435
  ## Support
384
436
 
385
- If you encounter any issues or have questions about comfy-cli, please [open an issue](https://github.com/comfy-cli/issues) on our GitHub repository or contact us on [Discord](https://discord.com/invite/comfyorg). We'll be happy to assist you!
437
+ Questions or issues? [Open an issue](https://github.com/Comfy-Org/comfy-cli/issues)
438
+ or reach us on [Discord](https://discord.com/invite/comfyorg).
386
439
 
387
440
  Happy diffusing with ComfyUI and comfy-cli! 🎉
@@ -11,6 +11,7 @@ from rich.console import Console
11
11
 
12
12
  from comfy_cli import constants, env_checker, logging, tracking, ui, utils
13
13
  from comfy_cli.command import code_search, custom_nodes, pr_command
14
+ from comfy_cli.command import generate as generate_command
14
15
  from comfy_cli.command import install as install_inner
15
16
  from comfy_cli.command import run as run_inner
16
17
  from comfy_cli.command.install import validate_version
@@ -446,7 +447,23 @@ def run(
446
447
  int | None,
447
448
  typer.Option(help="The timeout in seconds for the workflow execution."),
448
449
  ] = 30,
450
+ api_key: Annotated[
451
+ str | None,
452
+ typer.Option(
453
+ "--api-key",
454
+ envvar="COMFY_API_KEY",
455
+ help=(
456
+ "Comfy API key for API Nodes (Partner Nodes). "
457
+ "Embedded in the prompt body as extra_data.api_key_comfy_org on POST /prompt. "
458
+ "For scripting, prefer the COMFY_API_KEY environment variable so the secret "
459
+ "stays out of shell history."
460
+ ),
461
+ ),
462
+ ] = None,
449
463
  ):
464
+ if api_key:
465
+ api_key = api_key.strip() or None
466
+
450
467
  config = ConfigManager()
451
468
 
452
469
  if host:
@@ -470,7 +487,7 @@ def run(
470
487
  if not port:
471
488
  port = 8188
472
489
 
473
- run_inner.execute(workflow, host, port, wait, verbose, local_paths, timeout)
490
+ run_inner.execute(workflow, host, port, wait, verbose, local_paths, timeout, api_key=api_key)
474
491
 
475
492
 
476
493
  def validate_comfyui(_env_checker):
@@ -682,6 +699,7 @@ def standalone(
682
699
  sty.to_tarball()
683
700
 
684
701
 
702
+ generate_command.register_with(app)
685
703
  app.add_typer(models_command.app, name="model", help="Manage models.")
686
704
  app.add_typer(custom_nodes.app, name="node", help="Manage custom nodes.")
687
705
  app.add_typer(custom_nodes.manager_app, name="manager", help="Manage ComfyUI-Manager.")
@@ -2,6 +2,7 @@
2
2
 
3
3
  import json
4
4
  import re
5
+ import sys
5
6
  from typing import Annotated
6
7
  from urllib.parse import quote
7
8
 
@@ -20,12 +21,19 @@ DEFAULT_COUNT = 20
20
21
  REQUEST_TIMEOUT = 30
21
22
 
22
23
 
24
+ _TYPE_FILTER_RE = re.compile(r"(^|\s)type:")
25
+
26
+
23
27
  def _build_query(query: str, repo: str | None, count: int) -> str:
24
28
  parts = []
25
29
  if repo:
26
30
  if "/" not in repo:
27
31
  repo = f"Comfy-Org/{repo}"
28
32
  parts.append(f"repo:^{re.escape(repo)}$")
33
+ # Only default to file matches when the user hasn't specified their own
34
+ # type: filter — otherwise respect whatever they passed (e.g. type:commit).
35
+ if not _TYPE_FILTER_RE.search(query):
36
+ parts.append("type:file")
29
37
  parts.append(f"count:{count}")
30
38
  parts.append(query)
31
39
  return " ".join(parts)
@@ -56,20 +64,21 @@ def _format_results(search: dict) -> list[dict]:
56
64
  commit_hash = (default_branch.get("target") or {}).get("commit", {}).get("oid", "")
57
65
  ref = commit_hash or branch_name
58
66
 
67
+ encoded_path = quote(file_path, safe="/")
68
+ file_url = f"https://github.com/{clean_name}/blob/{ref}/{encoded_path}"
69
+
59
70
  line_matches = result.get("lineMatches") or []
60
71
  matches = []
61
- if line_matches:
62
- encoded_path = quote(file_path, safe="/")
63
- base_url = f"https://github.com/{clean_name}/blob/{ref}/{encoded_path}"
64
- for m in line_matches:
65
- line = m.get("lineNumber", 0) + 1
66
- preview = m.get("preview", "").rstrip()
67
- matches.append({"line": line, "preview": preview, "url": f"{base_url}#L{line}"})
72
+ for m in line_matches:
73
+ line = m.get("lineNumber", 0) + 1
74
+ preview = m.get("preview", "").rstrip()
75
+ matches.append({"line": line, "preview": preview, "url": f"{file_url}#L{line}"})
68
76
 
69
77
  formatted.append(
70
78
  {
71
79
  "repository": clean_name,
72
80
  "file": file_path,
81
+ "file_url": file_url,
73
82
  "branch": branch_name,
74
83
  "commit": commit_hash,
75
84
  "matches": matches,
@@ -96,19 +105,34 @@ def _print_results(results: list[dict], stats: dict, json_output: bool) -> None:
96
105
  console.print("[yellow]No results found.[/yellow]")
97
106
  return
98
107
 
108
+ # Use raw isatty() rather than Rich's console.is_terminal: Rich treats
109
+ # FORCE_COLOR=1 / TTY_COMPATIBLE=1 as terminal-capable even when stdout
110
+ # is redirected, but OSC 8 escapes in a piped stream defeat the whole
111
+ # point of this branch (hiding URLs from humans, exposing them to AI).
112
+ is_tty = sys.stdout.isatty()
113
+
99
114
  for file_result in results:
115
+ repo = file_result["repository"]
116
+ path = file_result["file"]
117
+ file_url = file_result["file_url"]
118
+
100
119
  header = Text()
101
- header.append(file_result["repository"], style="bold cyan")
102
- header.append(" / ", style="dim")
103
- header.append(file_result["file"], style="bold")
120
+ if is_tty:
121
+ # Humans: clickable OSC 8 hyperlink, URL hidden from visible output.
122
+ header.append(f"{repo} / {path}", style=f"bold cyan link {file_url}")
123
+ else:
124
+ # Non-TTY (pipes, AI agents): print the raw URL once per file so
125
+ # agents can synthesize #L<line> anchors themselves.
126
+ header.append(f"{repo} / {path}\n")
127
+ header.append(f" {file_url}", style="dim")
104
128
  console.print(header)
105
129
 
106
130
  for match in file_result["matches"]:
107
- line_text = Text()
108
- line_text.append(f" L{match['line']:>5}", style="green")
131
+ line_text = Text(" ")
132
+ line_style = f"green link {match['url']}" if is_tty else "green"
133
+ line_text.append(f"L{match['line']:>5}", style=line_style)
109
134
  line_text.append(f" {match['preview']}")
110
135
  console.print(line_text)
111
- console.print(f" [dim]{match['url']}[/dim]")
112
136
 
113
137
  console.print()
114
138
 
@@ -121,7 +145,15 @@ def _print_results(results: list[dict], stats: dict, json_output: bool) -> None:
121
145
  @app.callback(invoke_without_command=True)
122
146
  @tracking.track_command()
123
147
  def code_search(
124
- query: Annotated[str, typer.Argument(help="Search query (supports Sourcegraph syntax)")],
148
+ query: Annotated[
149
+ str,
150
+ typer.Argument(
151
+ help=(
152
+ "Search query (supports Sourcegraph syntax). Defaults to file matches; "
153
+ "pass your own `type:` filter (e.g. `type:commit`) to override."
154
+ ),
155
+ ),
156
+ ],
125
157
  repo: Annotated[
126
158
  str | None,
127
159
  typer.Option("--repo", "-r", help="Filter by repository (e.g. ComfyUI, Comfy-Org/ComfyUI)"),
@@ -975,6 +975,17 @@ def validate_node_for_publishing():
975
975
  # Perform some validation logic here
976
976
  typer.echo("Validating node configuration...")
977
977
  config = extract_node_configuration()
978
+ if config is None:
979
+ raise typer.Exit(code=1)
980
+
981
+ if not config.project.version:
982
+ # Escape `[` chars so rich doesn't parse `[tool.comfy.version]` and
983
+ # `["version"]` as markup tags; `]` doesn't need escaping.
984
+ print(
985
+ "[red]Error: project version is empty. Set `project.version` in pyproject.toml, "
986
+ r'or configure `\[tool.comfy.version].path` if using `dynamic = \["version"]`.[/red]'
987
+ )
988
+ raise typer.Exit(code=1)
978
989
 
979
990
  # Run security checks first
980
991
  typer.echo("Running security checks...")
@@ -0,0 +1,3 @@
1
+ from comfy_cli.command.generate.app import register_with
2
+
3
+ __all__ = ["register_with"]