comfygit 0.5.0__tar.gz → 0.7.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 (38) hide show
  1. {comfygit-0.5.0 → comfygit-0.7.0}/PKG-INFO +20 -10
  2. {comfygit-0.5.0 → comfygit-0.7.0}/README.md +15 -5
  3. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/cli.py +99 -10
  4. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/env_commands.py +454 -189
  5. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/global_commands.py +278 -235
  6. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/logging/compressed_handler.py +9 -0
  7. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/logging/environment_logger.py +21 -13
  8. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/logging/logging_config.py +6 -5
  9. comfygit-0.7.0/comfygit_cli/logging/security.py +41 -0
  10. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/utils/civitai_errors.py +1 -1
  11. comfygit-0.7.0/comfygit_cli/utils/runtime_client.py +66 -0
  12. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/utils/update_checker.py +2 -1
  13. comfygit-0.7.0/comfygit_cli/utils/workflow_result.py +40 -0
  14. {comfygit-0.5.0 → comfygit-0.7.0}/pyproject.toml +4 -4
  15. {comfygit-0.5.0 → comfygit-0.7.0}/.gitignore +0 -0
  16. {comfygit-0.5.0 → comfygit-0.7.0}/LICENSE.txt +0 -0
  17. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/__init__.py +0 -0
  18. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/__main__.py +0 -0
  19. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/cli_utils.py +0 -0
  20. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/completers.py +0 -0
  21. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/completion_commands.py +0 -0
  22. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/formatters/__init__.py +0 -0
  23. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/formatters/error_formatter.py +0 -0
  24. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/interactive/__init__.py +0 -0
  25. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/logging/log_compressor.py +0 -0
  26. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/resolution_strategies.py +0 -0
  27. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/strategies/__init__.py +0 -0
  28. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/strategies/confirmation.py +0 -0
  29. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/strategies/conflict_resolver.py +0 -0
  30. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/strategies/interactive.py +0 -0
  31. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/strategies/rollback.py +0 -0
  32. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/update_commands.py +0 -0
  33. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/utils/__init__.py +0 -0
  34. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/utils/formatting.py +0 -0
  35. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/utils/orchestrator.py +0 -0
  36. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/utils/pagination.py +0 -0
  37. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/utils/progress.py +0 -0
  38. {comfygit-0.5.0 → comfygit-0.7.0}/comfygit_cli/utils/update_notice.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: comfygit
3
- Version: 0.5.0
3
+ Version: 0.7.0
4
4
  Summary: ComfyGit - Git-based environment management for ComfyUI
5
5
  Project-URL: Documentation, https://docs.comfygit.org/
6
6
  Project-URL: Repository, https://github.com/comfygit-ai/comfygit
@@ -8,9 +8,9 @@ Project-URL: Issues, https://github.com/comfygit-ai/comfygit/issues
8
8
  License-File: LICENSE.txt
9
9
  Requires-Python: >=3.10
10
10
  Requires-Dist: argcomplete>=3.5.0
11
- Requires-Dist: comfygit-core==0.5.0
12
- Requires-Dist: comfygit-studio==0.5.0
13
- Requires-Dist: requests>=2.33.0
11
+ Requires-Dist: comfygit-core[keyring]==0.7.0
12
+ Requires-Dist: comfygit-studio==0.7.0
13
+ Requires-Dist: requests>=2.32.4
14
14
  Description-Content-Type: text/markdown
15
15
 
16
16
  # ComfyGit CLI
@@ -201,10 +201,17 @@ cg import [PATH|URL]
201
201
  cg export [PATH]
202
202
  --allow-issues Skip confirmation if models lack source URLs
203
203
 
204
- # Configuration
205
- cg config
206
- --civitai-key KEY Set CivitAI API key (empty string to clear)
207
- --show Show current configuration
204
+ # Provider authentication (secrets never go in argv)
205
+ cg auth status
206
+ cg auth set civitai
207
+ cg auth set huggingface
208
+ cg auth set github
209
+ cg auth login huggingface
210
+ cg auth migrate
211
+ cg auth clear PROVIDER
212
+
213
+ # Nonsecret configuration
214
+ cg config --show
208
215
 
209
216
  # Registry management
210
217
  cg registry status # Show registry cache status
@@ -243,6 +250,7 @@ cg create NAME
243
250
  --template PATH Template manifest
244
251
  --python VERSION Python version (default: 3.11)
245
252
  --comfyui VERSION ComfyUI version
253
+ --comfyui-repository URL ComfyUI Git repository (canonical by default)
246
254
  --torch-backend BACKEND PyTorch backend (auto/cpu/cu128/rocm6.3/xpu)
247
255
  --use Set as active environment
248
256
 
@@ -633,7 +641,9 @@ source ~/.bashrc # or ~/.zshrc
633
641
 
634
642
  - `COMFYGIT_HOME` - Override default workspace location (`~/comfygit`)
635
643
  - `COMFYGIT_DEV_COMPRESS_LOGS` - Enable compressed logging (dev feature: `true`/`1`/`yes`)
636
- - `CIVITAI_API_KEY` - CivitAI API key (or use `cg config --civitai-key`)
644
+ - `CIVITAI_API_TOKEN` / `CIVITAI_API_KEY` - CivitAI credential override
645
+ - `HF_TOKEN` / `HUGGING_FACE_HUB_TOKEN` - Hugging Face credential override
646
+ - `GITHUB_TOKEN` / `GH_TOKEN` - GitHub credential override
637
647
 
638
648
  Example:
639
649
  ```bash
@@ -186,10 +186,17 @@ cg import [PATH|URL]
186
186
  cg export [PATH]
187
187
  --allow-issues Skip confirmation if models lack source URLs
188
188
 
189
- # Configuration
190
- cg config
191
- --civitai-key KEY Set CivitAI API key (empty string to clear)
192
- --show Show current configuration
189
+ # Provider authentication (secrets never go in argv)
190
+ cg auth status
191
+ cg auth set civitai
192
+ cg auth set huggingface
193
+ cg auth set github
194
+ cg auth login huggingface
195
+ cg auth migrate
196
+ cg auth clear PROVIDER
197
+
198
+ # Nonsecret configuration
199
+ cg config --show
193
200
 
194
201
  # Registry management
195
202
  cg registry status # Show registry cache status
@@ -228,6 +235,7 @@ cg create NAME
228
235
  --template PATH Template manifest
229
236
  --python VERSION Python version (default: 3.11)
230
237
  --comfyui VERSION ComfyUI version
238
+ --comfyui-repository URL ComfyUI Git repository (canonical by default)
231
239
  --torch-backend BACKEND PyTorch backend (auto/cpu/cu128/rocm6.3/xpu)
232
240
  --use Set as active environment
233
241
 
@@ -618,7 +626,9 @@ source ~/.bashrc # or ~/.zshrc
618
626
 
619
627
  - `COMFYGIT_HOME` - Override default workspace location (`~/comfygit`)
620
628
  - `COMFYGIT_DEV_COMPRESS_LOGS` - Enable compressed logging (dev feature: `true`/`1`/`yes`)
621
- - `CIVITAI_API_KEY` - CivitAI API key (or use `cg config --civitai-key`)
629
+ - `CIVITAI_API_TOKEN` / `CIVITAI_API_KEY` - CivitAI credential override
630
+ - `HF_TOKEN` / `HUGGING_FACE_HUB_TOKEN` - Hugging Face credential override
631
+ - `GITHUB_TOKEN` / `GH_TOKEN` - GitHub credential override
622
632
 
623
633
  Example:
624
634
  ```bash
@@ -2,6 +2,7 @@
2
2
  # PYTHON_ARGCOMPLETE_OK
3
3
 
4
4
  import argparse
5
+ import os
5
6
  import sys
6
7
  from collections.abc import Callable
7
8
  from importlib.metadata import PackageNotFoundError, version
@@ -75,8 +76,25 @@ def _check_for_old_docker_installation() -> None:
75
76
  warning_flag.touch()
76
77
 
77
78
 
79
+ def _configure_stdio_encoding() -> None:
80
+ """Avoid Windows terminal encoding crashes for Unicode status output."""
81
+ if os.name != "nt":
82
+ return
83
+
84
+ for stream in (sys.stdout, sys.stderr):
85
+ reconfigure = getattr(stream, "reconfigure", None)
86
+ if reconfigure is None:
87
+ continue
88
+ try:
89
+ reconfigure(errors="replace")
90
+ except (OSError, ValueError):
91
+ continue
92
+
93
+
78
94
  def main() -> None:
79
95
  """Main entry point for ComfyGit CLI."""
96
+ _configure_stdio_encoding()
97
+
80
98
  # Enable readline for input() line editing (arrow keys, history)
81
99
  # Unix/Linux/macOS: provides full editing capability
82
100
  # Windows: gracefully falls back to native console editing
@@ -215,6 +233,14 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
215
233
  )
216
234
  analyze_parser.set_defaults(func=global_cmds.analyze)
217
235
 
236
+ inventory_parser = subparsers.add_parser(
237
+ "inventory",
238
+ help="Report typed workspace model, environment, and storage inventory",
239
+ )
240
+ inventory_parser.add_argument("--json", action="store_true", dest="json_output", help="Emit machine-readable JSON")
241
+ inventory_parser.add_argument("--storage", action="store_true", help="Measure environment, cache, input/output, and model storage")
242
+ inventory_parser.set_defaults(func=global_cmds.inventory)
243
+
218
244
  # update - Update ComfyGit CLI (self-update)
219
245
  update_parser = subparsers.add_parser("update", help="Update ComfyGit CLI")
220
246
  update_parser.add_argument("--check", action="store_true", help="Check for updates without upgrading")
@@ -315,6 +341,7 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
315
341
  # model index list
316
342
  model_index_list_parser = model_index_subparsers.add_parser("list", help="List all indexed models")
317
343
  model_index_list_parser.add_argument("--duplicates", action="store_true", help="Show only models with multiple locations")
344
+ model_index_list_parser.add_argument("--json", action="store_true", dest="json_output", help="Emit machine-readable JSON")
318
345
  model_index_list_parser.set_defaults(func=global_cmds.model_index_list)
319
346
 
320
347
  # model index show
@@ -352,7 +379,14 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
352
379
  # model delete
353
380
  model_delete_parser = model_subparsers.add_parser("delete", help="Delete model files and clean index entries")
354
381
  model_delete_parser.add_argument("identifier", help="Model hash, hash prefix, filename, or path")
355
- model_delete_parser.add_argument("-y", "--yes", action="store_true", help="Skip confirmation prompt")
382
+ deletion_target = model_delete_parser.add_mutually_exclusive_group()
383
+ deletion_target.add_argument("--location-id", type=int, help="Delete one indexed location id")
384
+ deletion_target.add_argument("--all-locations", action="store_true", help="Explicitly target every indexed location")
385
+ model_delete_parser.add_argument("--apply", action="store_true", help="Apply the deletion plan; default is dry-run")
386
+ model_delete_parser.add_argument("--allow-referenced", action="store_true", help="Allow deletion despite ComfyGit environment references")
387
+ model_delete_parser.add_argument("--allow-incomplete-recovery", action="store_true", help="Allow final-copy deletion without source/hash recovery proof")
388
+ model_delete_parser.add_argument("--json", action="store_true", dest="json_output", help="Emit machine-readable JSON")
389
+ model_delete_parser.add_argument("-y", "--yes", action="store_true", help="Compatibility alias for --apply --all-locations")
356
390
  model_delete_parser.set_defaults(func=global_cmds.model_delete)
357
391
 
358
392
  # Registry management subcommands
@@ -368,14 +402,46 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
368
402
  registry_update_parser = registry_subparsers.add_parser("update", help="Update registry data from GitHub")
369
403
  registry_update_parser.set_defaults(func=global_cmds.registry_update)
370
404
 
371
- # Config management - now with subcommands
405
+ # Provider authentication. Secret values are read from a hidden prompt or stdin,
406
+ # never from argv.
407
+ auth_parser = subparsers.add_parser("auth", help="Manage provider authentication")
408
+ auth_subparsers = auth_parser.add_subparsers(dest="auth_command", help="Authentication commands")
409
+ auth_parser.set_defaults(func=_make_help_func(auth_parser))
410
+
411
+ auth_status_parser = auth_subparsers.add_parser("status", help="Show provider authentication status")
412
+ auth_status_parser.set_defaults(func=global_cmds.auth_status)
413
+
414
+ auth_set_parser = auth_subparsers.add_parser("set", help="Save a provider credential")
415
+ auth_set_parser.add_argument("provider", choices=("civitai", "huggingface", "github"))
416
+ auth_set_parser.add_argument(
417
+ "--token-stdin",
418
+ action="store_true",
419
+ help="Read the credential from one line on standard input instead of a hidden prompt",
420
+ )
421
+ auth_set_parser.set_defaults(func=global_cmds.auth_set)
422
+
423
+ auth_clear_parser = auth_subparsers.add_parser("clear", help="Clear a saved provider credential")
424
+ auth_clear_parser.add_argument("provider", choices=("civitai", "huggingface", "github"))
425
+ auth_clear_parser.set_defaults(func=global_cmds.auth_clear)
426
+
427
+ auth_login_parser = auth_subparsers.add_parser(
428
+ "login",
429
+ help="Authenticate through a provider-native login flow",
430
+ )
431
+ auth_login_parser.add_argument("provider", choices=("huggingface",))
432
+ auth_login_parser.add_argument("--force", action="store_true", help="Force a new provider login")
433
+ auth_login_parser.set_defaults(func=global_cmds.auth_login)
434
+
435
+ auth_migrate_parser = auth_subparsers.add_parser(
436
+ "migrate",
437
+ help="Migrate verified legacy plaintext credentials into secure storage",
438
+ )
439
+ auth_migrate_parser.set_defaults(func=global_cmds.auth_migrate)
440
+
441
+ # Nonsecret workspace configuration.
372
442
  config_parser = subparsers.add_parser("config", help="Manage configuration settings")
373
443
  config_parser.add_subparsers(dest="config_command", help="Configuration commands")
374
444
 
375
- # Legacy flags - still supported at root level for backward compatibility
376
- config_parser.add_argument("--civitai-key", type=str, help="Set Civitai API key (use empty string to clear)")
377
- config_parser.add_argument("--huggingface-token", type=str, help="Set Hugging Face token for gated model downloads (use empty string to clear)")
378
- config_parser.add_argument("--github-token", type=str, help="Set GitHub token for private git repository access (use empty string to clear)")
379
445
  config_parser.add_argument("--uv-cache", type=str, help="Set external UV cache path (use empty string to clear)")
380
446
  config_parser.add_argument("--show", action="store_true", help="Show current configuration")
381
447
  config_parser.set_defaults(func=global_cmds.config)
@@ -419,22 +485,24 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
419
485
  orch_parser.set_defaults(func=_make_help_func(orch_parser))
420
486
 
421
487
  # orch status
422
- orch_status_parser = orch_subparsers.add_parser("status", help="Show orchestrator status")
488
+ orch_status_parser = orch_subparsers.add_parser("status", help="Show environment runtime status (legacy orchestrator fallback)")
423
489
  orch_status_parser.add_argument("--json", action="store_true", help="Output as JSON")
424
490
  orch_status_parser.set_defaults(func=global_cmds.orch_status)
425
491
 
426
492
  # orch restart
427
- orch_restart_parser = orch_subparsers.add_parser("restart", help="Restart ComfyUI")
493
+ orch_restart_parser = orch_subparsers.add_parser("restart", help="Restart idle ComfyUI through its cg run supervisor")
428
494
  orch_restart_parser.add_argument("--wait", action="store_true", help="Wait for restart to complete")
495
+ orch_restart_parser.add_argument("--timeout", type=float, default=180, help="Maximum readiness wait in seconds")
496
+ orch_restart_parser.add_argument("--json", action="store_true", help="Output acknowledgement or verified readiness as JSON")
429
497
  orch_restart_parser.set_defaults(func=global_cmds.orch_restart)
430
498
 
431
499
  # orch kill
432
- orch_kill_parser = orch_subparsers.add_parser("kill", help="Shutdown orchestrator")
500
+ orch_kill_parser = orch_subparsers.add_parser("kill", help="Shutdown the legacy orchestrator (not cg run)")
433
501
  orch_kill_parser.add_argument("--force", action="store_true", help="Force kill (bypass command queue)")
434
502
  orch_kill_parser.set_defaults(func=global_cmds.orch_kill)
435
503
 
436
504
  # orch clean
437
- orch_clean_parser = orch_subparsers.add_parser("clean", help="Clean orchestrator state")
505
+ orch_clean_parser = orch_subparsers.add_parser("clean", help="Clean legacy orchestrator state")
438
506
  orch_clean_parser.add_argument("--dry-run", action="store_true", help="Show what would be deleted")
439
507
  orch_clean_parser.add_argument("--force", action="store_true", help="Skip confirmation")
440
508
  orch_clean_parser.add_argument("--kill", action="store_true", help="Also kill orchestrator process")
@@ -479,6 +547,13 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
479
547
  create_parser.add_argument("--template", type=Path, help="Template manifest")
480
548
  create_parser.add_argument("--python", default="3.11", help="Python version")
481
549
  create_parser.add_argument("--comfyui", help="ComfyUI version")
550
+ create_parser.add_argument(
551
+ "--comfyui-repository",
552
+ help=(
553
+ "ComfyUI Git repository URL. Use with --comfyui to pin a fork "
554
+ "or alternate upstream; defaults to canonical ComfyUI."
555
+ ),
556
+ )
482
557
  create_parser.add_argument(
483
558
  "--torch-backend",
484
559
  default="auto",
@@ -1047,10 +1122,24 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
1047
1122
  workflow_resolve_parser = workflow_subparsers.add_parser("resolve", help="Resolve workflow dependencies (nodes & models)")
1048
1123
  workflow_resolve_parser.add_argument("name", help="Workflow name to resolve").completer = workflow_completer # type: ignore[attr-defined]
1049
1124
  workflow_resolve_parser.add_argument("--auto", action="store_true", help="Auto-resolve without interaction")
1125
+ workflow_resolve_parser.add_argument("--json", action="store_true", help="JSON result on stdout; requires --auto and --install/--no-install")
1126
+ workflow_resolve_parser.add_argument("--strict", action="store_true", help="Exit 1 when dependencies remain unresolved or uninstalled")
1050
1127
  workflow_resolve_parser.add_argument("--install", action="store_true", help="Auto-install missing nodes without prompting")
1051
1128
  workflow_resolve_parser.add_argument("--no-install", action="store_true", help="Skip node installation prompt")
1052
1129
  workflow_resolve_parser.set_defaults(func=env_cmds.workflow_resolve)
1053
1130
 
1131
+ workflow_node_parser = workflow_subparsers.add_parser("node", help="Manage explicit node ownership mappings")
1132
+ mapping_parsers = workflow_node_parser.add_subparsers(dest="mapping_command", required=True)
1133
+ for operation in ("map", "unmap", "list"):
1134
+ mapping_parser = mapping_parsers.add_parser(operation)
1135
+ mapping_parser.add_argument("name", help="Workflow name")
1136
+ if operation != "list":
1137
+ mapping_parser.add_argument("node_type", help="ComfyUI registered node class name")
1138
+ if operation == "map":
1139
+ mapping_parser.add_argument("package", help="Tracked node package identifier")
1140
+ mapping_parser.add_argument("--json", action="store_true")
1141
+ mapping_parser.set_defaults(func=env_cmds.workflow_node_mapping)
1142
+
1054
1143
  # workflow model importance
1055
1144
  workflow_importance_parser = workflow_subparsers.add_parser(
1056
1145
  "model",