comfygit 0.3.6__py3-none-any.whl → 0.3.10__py3-none-any.whl

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.
comfygit_cli/cli.py CHANGED
@@ -3,12 +3,12 @@
3
3
 
4
4
  import argparse
5
5
  import sys
6
- from importlib.metadata import version, PackageNotFoundError
6
+ from collections.abc import Callable
7
+ from importlib.metadata import PackageNotFoundError, version
7
8
  from pathlib import Path
8
9
 
9
10
  import argcomplete
10
11
 
11
- from .completion_commands import CompletionCommands
12
12
  from .completers import (
13
13
  branch_completer,
14
14
  commit_hash_completer,
@@ -17,10 +17,19 @@ from .completers import (
17
17
  ref_completer,
18
18
  workflow_completer,
19
19
  )
20
+ from .completion_commands import CompletionCommands
20
21
  from .env_commands import EnvironmentCommands
21
22
  from .global_commands import GlobalCommands
22
23
  from .logging.logging_config import setup_logging
23
24
 
25
+
26
+ def _make_help_func(parser: argparse.ArgumentParser) -> Callable[[argparse.Namespace], None]:
27
+ """Create a function that prints parser help and exits."""
28
+ def show_help(args: argparse.Namespace) -> None:
29
+ parser.print_help()
30
+ sys.exit(1)
31
+ return show_help
32
+
24
33
  try:
25
34
  __version__ = version("comfygit")
26
35
  except PackageNotFoundError:
@@ -56,7 +65,7 @@ def _check_for_old_docker_installation() -> None:
56
65
  print(" • New version: UV packages, 'comfygit' command")
57
66
  print("\nBoth versions can coexist. Your old environments are unchanged.")
58
67
  print("\nTo use old version: pip install comfydock==0.1.6")
59
- print("To use new version: comfygit init")
68
+ print("To use new version: cg init")
60
69
  print("\nMigration guide: https://github.com/comfyhub-org/comfygit/blob/main/MIGRATION.md")
61
70
  print("="*70 + "\n")
62
71
 
@@ -156,7 +165,6 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
156
165
  init_parser.add_argument("path", type=Path, nargs="?", help="Workspace directory (default: ~/comfygit)")
157
166
  init_parser.add_argument("--models-dir", type=Path, help="Path to existing models directory to index")
158
167
  init_parser.add_argument("--yes", "-y", action="store_true", help="Use all defaults, no interactive prompts")
159
- init_parser.add_argument("--bare", action="store_true", help="Create workspace without system nodes (comfygit-manager)")
160
168
  init_parser.set_defaults(func=global_cmds.init)
161
169
 
162
170
  # list - List all environments
@@ -197,16 +205,18 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
197
205
  # export - Export ComfyGit environment
198
206
  export_parser = subparsers.add_parser("export", help="Export ComfyGit environment (include relevant files from .cec)")
199
207
  export_parser.add_argument("path", type=Path, nargs="?", help="Path to output file")
200
- export_parser.add_argument("--allow-issues", action="store_true", help="Skip confirmation if models are missing source URLs")
208
+ export_parser.add_argument("--allow-issues", action="store_true", help="Export even with unresolved workflows or models without source URLs")
201
209
  export_parser.set_defaults(func=global_cmds.export_env)
202
210
 
203
211
  # Model management subcommands
204
212
  model_parser = subparsers.add_parser("model", help="Manage model index")
205
213
  model_subparsers = model_parser.add_subparsers(dest="model_command", help="Model commands")
214
+ model_parser.set_defaults(func=_make_help_func(model_parser))
206
215
 
207
216
  # model index subcommands
208
217
  model_index_parser = model_subparsers.add_parser("index", help="Model index operations")
209
218
  model_index_subparsers = model_index_parser.add_subparsers(dest="model_index_command", help="Model index commands")
219
+ model_index_parser.set_defaults(func=_make_help_func(model_index_parser))
210
220
 
211
221
  # model index find
212
222
  model_index_find_parser = model_index_subparsers.add_parser("find", help="Find models by hash or filename")
@@ -253,6 +263,7 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
253
263
  # Registry management subcommands
254
264
  registry_parser = subparsers.add_parser("registry", help="Manage node registry cache")
255
265
  registry_subparsers = registry_parser.add_subparsers(dest="registry_command", help="Registry commands")
266
+ registry_parser.set_defaults(func=_make_help_func(registry_parser))
256
267
 
257
268
  # registry status
258
269
  registry_status_parser = registry_subparsers.add_parser("status", help="Show registry cache status")
@@ -262,8 +273,11 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
262
273
  registry_update_parser = registry_subparsers.add_parser("update", help="Update registry data from GitHub")
263
274
  registry_update_parser.set_defaults(func=global_cmds.registry_update)
264
275
 
265
- # Config management
276
+ # Config management - now with subcommands
266
277
  config_parser = subparsers.add_parser("config", help="Manage configuration settings")
278
+ config_subparsers = config_parser.add_subparsers(dest="config_command", help="Configuration commands")
279
+
280
+ # Legacy flags - still supported at root level for backward compatibility
267
281
  config_parser.add_argument("--civitai-key", type=str, help="Set Civitai API key (use empty string to clear)")
268
282
  config_parser.add_argument("--show", action="store_true", help="Show current configuration")
269
283
  config_parser.set_defaults(func=global_cmds.config)
@@ -280,6 +294,7 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
280
294
  completion_cmds = CompletionCommands()
281
295
  completion_parser = subparsers.add_parser("completion", help="Manage shell tab completion")
282
296
  completion_subparsers = completion_parser.add_subparsers(dest="completion_command", help="Completion commands")
297
+ completion_parser.set_defaults(func=_make_help_func(completion_parser))
283
298
 
284
299
  # completion install
285
300
  completion_install_parser = completion_subparsers.add_parser("install", help="Install tab completion for your shell")
@@ -303,6 +318,7 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
303
318
  dest="orch_command",
304
319
  help="Orchestrator commands"
305
320
  )
321
+ orch_parser.set_defaults(func=_make_help_func(orch_parser))
306
322
 
307
323
  # orch status
308
324
  orch_status_parser = orch_subparsers.add_parser("status", help="Show orchestrator status")
@@ -332,6 +348,26 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
332
348
  orch_logs_parser.add_argument("-n", "--lines", type=int, default=50, help="Number of lines to show (default: 50)")
333
349
  orch_logs_parser.set_defaults(func=global_cmds.orch_logs)
334
350
 
351
+ # Workspace management subcommands
352
+ workspace_parser = subparsers.add_parser("workspace", help="Workspace operations")
353
+ workspace_subparsers = workspace_parser.add_subparsers(
354
+ dest="workspace_command",
355
+ help="Workspace commands"
356
+ )
357
+ workspace_parser.set_defaults(func=_make_help_func(workspace_parser))
358
+
359
+ # workspace cleanup
360
+ workspace_cleanup_parser = workspace_subparsers.add_parser(
361
+ "cleanup",
362
+ help="Remove legacy workspace artifacts"
363
+ )
364
+ workspace_cleanup_parser.add_argument(
365
+ "--force",
366
+ action="store_true",
367
+ help="Skip verification and force cleanup"
368
+ )
369
+ workspace_cleanup_parser.set_defaults(func=global_cmds.workspace_cleanup)
370
+
335
371
 
336
372
  def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
337
373
  """Add environment-specific commands."""
@@ -372,9 +408,42 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
372
408
 
373
409
  # Environment Operation Commands (operate IN environments, require -e or active)
374
410
 
411
+ # env-config - Environment-scoped configuration (requires -e or active env)
412
+ env_config_parser = subparsers.add_parser("env-config", help="Manage environment-specific configuration")
413
+ env_config_subparsers = env_config_parser.add_subparsers(dest="env_config_command", help="Environment config commands")
414
+ env_config_parser.set_defaults(func=_make_help_func(env_config_parser))
415
+
416
+ # env-config torch-backend - Manage PyTorch backend for this environment
417
+ env_config_torch_parser = env_config_subparsers.add_parser("torch-backend", help="Manage PyTorch backend settings")
418
+ env_config_torch_subparsers = env_config_torch_parser.add_subparsers(dest="torch_command", help="PyTorch backend commands")
419
+ env_config_torch_parser.set_defaults(func=_make_help_func(env_config_torch_parser))
420
+
421
+ # env-config torch-backend show
422
+ env_config_torch_show_parser = env_config_torch_subparsers.add_parser("show", help="Show current PyTorch backend")
423
+ env_config_torch_show_parser.set_defaults(func=env_cmds.env_config_torch_show)
424
+
425
+ # env-config torch-backend set <backend>
426
+ env_config_torch_set_parser = env_config_torch_subparsers.add_parser("set", help="Set PyTorch backend")
427
+ env_config_torch_set_parser.add_argument("backend", help="Backend to set (e.g., cu128, cpu, rocm6.3, xpu)")
428
+ env_config_torch_set_parser.set_defaults(func=env_cmds.env_config_torch_set)
429
+
430
+ # env-config torch-backend detect
431
+ env_config_torch_detect_parser = env_config_torch_subparsers.add_parser("detect", help="Auto-detect and show recommended backend")
432
+ env_config_torch_detect_parser.set_defaults(func=env_cmds.env_config_torch_detect)
433
+
375
434
  # run - Run ComfyUI (special handling for ComfyUI args)
376
435
  run_parser = subparsers.add_parser("run", help="Run ComfyUI")
377
436
  run_parser.add_argument("--no-sync", action="store_true", help="Skip environment sync before running")
437
+ run_parser.add_argument(
438
+ "--torch-backend",
439
+ default=None,
440
+ metavar="BACKEND",
441
+ help=(
442
+ "PyTorch backend override (one-time, not saved). Examples: cpu, "
443
+ "cu128 (CUDA 12.8), cu126, cu124, rocm6.3 (AMD), xpu (Intel). "
444
+ "Reads from .pytorch-backend file if not specified."
445
+ ),
446
+ )
378
447
  run_parser.set_defaults(func=env_cmds.run, args=[])
379
448
 
380
449
  # status - Show environment status
@@ -400,6 +469,25 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
400
469
  )
401
470
  repair_parser.set_defaults(func=env_cmds.repair)
402
471
 
472
+ # sync - Sync environment (packages, nodes, models)
473
+ sync_parser = subparsers.add_parser("sync", help="Sync environment packages and dependencies")
474
+ sync_parser.add_argument(
475
+ "--torch-backend",
476
+ default=None,
477
+ metavar="BACKEND",
478
+ help=(
479
+ "PyTorch backend override (one-time, not saved). Examples: cpu, "
480
+ "cu128 (CUDA 12.8), cu126, cu124, rocm6.3 (AMD), xpu (Intel). "
481
+ "Reads from .pytorch-backend file if not specified."
482
+ ),
483
+ )
484
+ sync_parser.add_argument(
485
+ "-v", "--verbose",
486
+ action="store_true",
487
+ help="Show full UV output during sync"
488
+ )
489
+ sync_parser.set_defaults(func=env_cmds.sync)
490
+
403
491
  # log - Show commit history
404
492
  log_parser = subparsers.add_parser("log", help="Show commit history")
405
493
  log_parser.add_argument("-n", "--limit", type=int, default=20, metavar="N", help="Number of commits to show (default: 20)")
@@ -475,6 +563,11 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
475
563
  default="origin",
476
564
  help="Git remote name (default: origin)"
477
565
  )
566
+ pull_parser.add_argument(
567
+ "-b", "--branch",
568
+ default=None,
569
+ help="Remote branch to pull (default: current local branch). Use when remote has different default branch (e.g., master vs main)"
570
+ )
478
571
  pull_parser.add_argument(
479
572
  "--models",
480
573
  choices=["all", "required", "skip"],
@@ -496,6 +589,16 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
496
589
  choices=["mine", "theirs"],
497
590
  help="Auto-resolve conflicts: 'mine' keeps local, 'theirs' takes incoming"
498
591
  )
592
+ pull_parser.add_argument(
593
+ "--torch-backend",
594
+ default=None,
595
+ metavar="BACKEND",
596
+ help=(
597
+ "PyTorch backend override (one-time, not saved). Examples: cpu, "
598
+ "cu128 (CUDA 12.8), cu126, cu124, rocm6.3 (AMD), xpu (Intel). "
599
+ "Reads from .pytorch-backend file if not specified."
600
+ ),
601
+ )
499
602
  pull_parser.set_defaults(func=env_cmds.pull)
500
603
 
501
604
  # push - Push commits to remote
@@ -522,8 +625,9 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
522
625
  )
523
626
  remote_subparsers = remote_parser.add_subparsers(
524
627
  dest="remote_command",
525
- required=True
628
+ help="Remote commands"
526
629
  )
630
+ remote_parser.set_defaults(func=_make_help_func(remote_parser))
527
631
 
528
632
  # remote add
529
633
  remote_add_parser = remote_subparsers.add_parser(
@@ -538,6 +642,7 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
538
642
  "url",
539
643
  help="Remote URL"
540
644
  )
645
+ remote_add_parser.set_defaults(func=env_cmds.remote)
541
646
 
542
647
  # remote remove
543
648
  remote_remove_parser = remote_subparsers.add_parser(
@@ -548,18 +653,19 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
548
653
  "name",
549
654
  help="Remote name to remove"
550
655
  )
656
+ remote_remove_parser.set_defaults(func=env_cmds.remote)
551
657
 
552
658
  # remote list
553
659
  remote_list_parser = remote_subparsers.add_parser(
554
660
  "list",
555
661
  help="List all git remotes"
556
662
  )
557
-
558
- remote_parser.set_defaults(func=env_cmds.remote)
663
+ remote_list_parser.set_defaults(func=env_cmds.remote)
559
664
 
560
665
  # Node management subcommands
561
666
  node_parser = subparsers.add_parser("node", help="Manage custom nodes")
562
667
  node_subparsers = node_parser.add_subparsers(dest="node_command", help="Node commands")
668
+ node_parser.set_defaults(func=_make_help_func(node_parser))
563
669
 
564
670
  # node add
565
671
  node_add_parser = node_subparsers.add_parser("add", help="Add custom node(s)")
@@ -597,6 +703,7 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
597
703
  # Workflow management subcommands
598
704
  workflow_parser = subparsers.add_parser("workflow", help="Manage workflows")
599
705
  workflow_subparsers = workflow_parser.add_subparsers(dest="workflow_command", help="Workflow commands")
706
+ workflow_parser.set_defaults(func=_make_help_func(workflow_parser))
600
707
 
601
708
  # workflow list
602
709
  workflow_list_parser = workflow_subparsers.add_parser("list", help="List all workflows with sync status")
@@ -619,6 +726,7 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
619
726
  dest="model_command",
620
727
  help="Model management commands"
621
728
  )
729
+ workflow_importance_parser.set_defaults(func=_make_help_func(workflow_importance_parser))
622
730
 
623
731
  importance_parser = workflow_model_subparsers.add_parser(
624
732
  "importance",
@@ -645,6 +753,7 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
645
753
  # Constraint management subcommands
646
754
  constraint_parser = subparsers.add_parser("constraint", help="Manage UV constraint dependencies")
647
755
  constraint_subparsers = constraint_parser.add_subparsers(dest="constraint_command", help="Constraint commands")
756
+ constraint_parser.set_defaults(func=_make_help_func(constraint_parser))
648
757
 
649
758
  # constraint add
650
759
  constraint_add_parser = constraint_subparsers.add_parser("add", help="Add constraint dependencies")
@@ -663,6 +772,7 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
663
772
  # Python dependency management subcommands
664
773
  py_parser = subparsers.add_parser("py", help="Manage Python dependencies")
665
774
  py_subparsers = py_parser.add_subparsers(dest="py_command", help="Python dependency commands")
775
+ py_parser.set_defaults(func=_make_help_func(py_parser))
666
776
 
667
777
  # py add
668
778
  py_add_parser = py_subparsers.add_parser("add", help="Add Python dependencies")
@@ -705,5 +815,21 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
705
815
  )
706
816
  py_uv_parser.set_defaults(func=env_cmds.py_uv)
707
817
 
818
+ # Manager subcommands (per-environment comfygit-manager)
819
+ manager_parser = subparsers.add_parser("manager", help="Manage comfygit-manager installation")
820
+ manager_subparsers = manager_parser.add_subparsers(dest="manager_command", help="Manager commands")
821
+ manager_parser.set_defaults(func=_make_help_func(manager_parser))
822
+
823
+ # manager status
824
+ manager_status_parser = manager_subparsers.add_parser("status", help="Show manager version and update availability")
825
+ manager_status_parser.set_defaults(func=env_cmds.manager_status)
826
+
827
+ # manager update
828
+ manager_update_parser = manager_subparsers.add_parser("update", help="Update or migrate comfygit-manager")
829
+ manager_update_parser.add_argument("--version", help="Target version (default: latest)")
830
+ manager_update_parser.add_argument("-y", "--yes", action="store_true", help="Skip confirmation prompts")
831
+ manager_update_parser.set_defaults(func=env_cmds.manager_update)
832
+
833
+
708
834
  if __name__ == "__main__":
709
835
  main()
comfygit_cli/cli_utils.py CHANGED
@@ -10,6 +10,7 @@ from .logging.environment_logger import WorkspaceLogger
10
10
  if TYPE_CHECKING:
11
11
  from comfygit_core.core.workspace import Workspace
12
12
 
13
+
13
14
  def get_workspace_or_exit() -> "Workspace":
14
15
  """Get workspace or exit with error message."""
15
16
  try:
@@ -64,9 +64,9 @@ def environment_completer(prefix: str, parsed_args: argparse.Namespace, **kwargs
64
64
  """Complete environment names from workspace.
65
65
 
66
66
  Used for:
67
- - comfygit use <TAB>
68
- - comfygit delete <TAB>
69
- - comfygit -e <TAB>
67
+ - cg use <TAB>
68
+ - cg delete <TAB>
69
+ - cg -e <TAB>
70
70
  """
71
71
  workspace = get_workspace_safe()
72
72
  if not workspace:
@@ -89,7 +89,7 @@ def workflow_completer(prefix: str, parsed_args: argparse.Namespace, **kwargs: A
89
89
  2. Synced workflows
90
90
 
91
91
  Used for:
92
- - comfygit workflow resolve <TAB>
92
+ - cg workflow resolve <TAB>
93
93
  """
94
94
  workspace = get_workspace_safe()
95
95
  if not workspace:
@@ -125,8 +125,8 @@ def installed_node_completer(prefix: str, parsed_args: argparse.Namespace, **kwa
125
125
  """Complete installed node names.
126
126
 
127
127
  Used for:
128
- - comfygit node remove <TAB>
129
- - comfygit node update <TAB>
128
+ - cg node remove <TAB>
129
+ - cg node update <TAB>
130
130
  """
131
131
  workspace = get_workspace_safe()
132
132
  if not workspace: