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.
@@ -16,15 +16,6 @@ from .utils import create_progress_callback, paginate, show_civitai_auth_help, s
16
16
 
17
17
  logger = get_logger(__name__)
18
18
 
19
- # Default system nodes to install with new workspaces.
20
- # These are infrastructure custom nodes that provide management capabilities.
21
- # Use `cg init --bare` to skip installation.
22
- DEFAULT_SYSTEM_NODES = {
23
- "comfygit-manager": {
24
- "url": "https://github.com/comfyhub-org/comfygit-manager.git",
25
- "description": "ComfyGit management panel for ComfyUI",
26
- },
27
- }
28
19
 
29
20
 
30
21
  class GlobalCommands:
@@ -94,7 +85,6 @@ class GlobalCommands:
94
85
  - uv_cache/ for package management
95
86
  - environments/ for ComfyUI environments
96
87
  """
97
- from pathlib import Path
98
88
 
99
89
  # Validate models directory if provided (before creating workspace)
100
90
  explicit_models_dir = getattr(args, 'models_dir', None)
@@ -142,12 +132,6 @@ class GlobalCommands:
142
132
 
143
133
  print(f"✓ Workspace initialized at {workspace.path}")
144
134
 
145
- # Install default system nodes (unless --bare)
146
- if not getattr(args, 'bare', False):
147
- self._install_system_nodes(workspace)
148
- else:
149
- print("📦 Skipping system node installation (--bare flag)")
150
-
151
135
  # Handle models directory setup
152
136
  self._setup_models_directory(workspace, args)
153
137
 
@@ -163,39 +147,6 @@ class GlobalCommands:
163
147
  print(f"✗ Failed to initialize workspace: {e}", file=sys.stderr)
164
148
  sys.exit(1)
165
149
 
166
- def _install_system_nodes(self, workspace: Workspace) -> None:
167
- """Install default system nodes (comfygit-manager) into workspace.
168
-
169
- System nodes are infrastructure custom nodes that:
170
- - Live at workspace level (.metadata/system_nodes/)
171
- - Are symlinked into every environment
172
- - Are never tracked in pyproject.toml
173
- """
174
- from comfygit_core.utils.git import git_clone
175
-
176
- system_nodes_path = workspace.paths.system_nodes
177
-
178
- for node_name, node_config in DEFAULT_SYSTEM_NODES.items():
179
- target_path = system_nodes_path / node_name
180
-
181
- if target_path.exists():
182
- logger.debug(f"System node '{node_name}' already exists, skipping")
183
- continue
184
-
185
- print(f"📦 Installing system node: {node_name}")
186
- try:
187
- git_clone(
188
- url=node_config["url"],
189
- target_path=target_path,
190
- depth=1 # Shallow clone for speed
191
- )
192
- print(f" ✓ Installed {node_name}")
193
- logger.info(f"Installed system node: {node_name}")
194
- except Exception as e:
195
- print(f" ⚠️ Failed to install {node_name}: {e}")
196
- print(f" You can install it manually later")
197
- logger.warning(f"Failed to install system node {node_name}: {e}")
198
-
199
150
  def _show_workspace_env_setup(self, workspace_path: Path) -> None:
200
151
  """Show instructions for setting COMFYGIT_HOME for custom workspace location."""
201
152
  import os
@@ -231,8 +182,7 @@ class GlobalCommands:
231
182
  args: CLI arguments containing models_dir and yes flags
232
183
  """
233
184
  from pathlib import Path
234
- from comfygit_cli.utils.progress import create_model_sync_progress
235
- from comfygit_core.utils.common import format_size
185
+
236
186
 
237
187
  # Check for explicit flags
238
188
  use_interactive = not getattr(args, 'yes', False)
@@ -256,7 +206,7 @@ class GlobalCommands:
256
206
  print("\nOptions:")
257
207
  print(" 1. Point to an existing ComfyUI models directory (recommended)")
258
208
  print(" → Access all your existing models immediately")
259
- print(f" → Example: ~/ComfyUI/models")
209
+ print(" → Example: ~/ComfyUI/models")
260
210
  print("\n 2. Use the default empty directory")
261
211
  print(f" → ComfyGit created: {workspace.paths.models}")
262
212
  print(" → Download models as needed later")
@@ -296,7 +246,7 @@ class GlobalCommands:
296
246
  # Auto-detect if they entered ComfyUI root instead of models subdir
297
247
  if (models_path / "models").exists() and models_path.name != "models":
298
248
  print(f"\n⚠️ Detected ComfyUI installation at: {models_path}")
299
- use_subdir = input(f"Use models/ subdirectory instead? (Y/n): ").strip().lower()
249
+ use_subdir = input("Use models/ subdirectory instead? (Y/n): ").strip().lower()
300
250
  if use_subdir != 'n':
301
251
  models_path = models_path / "models"
302
252
  print(f"Using: {models_path}")
@@ -322,9 +272,10 @@ class GlobalCommands:
322
272
  workspace: The workspace instance
323
273
  models_path: Path to the models directory to scan
324
274
  """
325
- from comfygit_cli.utils.progress import create_model_sync_progress
326
275
  from comfygit_core.utils.common import format_size
327
276
 
277
+ from comfygit_cli.utils.progress import create_model_sync_progress
278
+
328
279
  try:
329
280
  progress = create_model_sync_progress()
330
281
  workspace.set_models_directory(models_path, progress=progress)
@@ -404,7 +355,7 @@ class GlobalCommands:
404
355
 
405
356
  # Read log lines
406
357
  try:
407
- with open(log_file, 'r', encoding='utf-8') as f:
358
+ with open(log_file, encoding='utf-8') as f:
408
359
  lines = f.readlines()
409
360
  except Exception as e:
410
361
  print(f"✗ Failed to read log file: {e}", file=sys.stderr)
@@ -453,9 +404,9 @@ class GlobalCommands:
453
404
  for line in record:
454
405
  print(line.rstrip())
455
406
 
456
- print(f"\n=== End of logs ===")
407
+ print("\n=== End of logs ===")
457
408
  if not args.full and len(records) == args.lines:
458
- print(f"Tip: Use --full to see all logs, or increase --lines to see more")
409
+ print("Tip: Use --full to see all logs, or increase --lines to see more")
459
410
 
460
411
  @with_workspace_logging("migrate")
461
412
  def migrate(self, args: argparse.Namespace) -> None:
@@ -749,7 +700,7 @@ class GlobalCommands:
749
700
  callbacks = CLIExportCallbacks()
750
701
 
751
702
  try:
752
- tarball_path = env.export_environment(output_path, callbacks=callbacks)
703
+ tarball_path = env.export_environment(output_path, callbacks=callbacks, allow_issues=args.allow_issues)
753
704
 
754
705
  # Check if we need user confirmation
755
706
  if callbacks.models_without_sources and not args.allow_issues:
@@ -1519,10 +1470,10 @@ class GlobalCommands:
1519
1470
  def orch_status(self, args: argparse.Namespace) -> None:
1520
1471
  """Show orchestrator status."""
1521
1472
  from .utils.orchestrator import (
1473
+ format_uptime,
1474
+ get_orchestrator_uptime,
1522
1475
  is_orchestrator_running,
1523
1476
  read_switch_status,
1524
- get_orchestrator_uptime,
1525
- format_uptime
1526
1477
  )
1527
1478
 
1528
1479
  metadata_dir = self.workspace.path / ".metadata"
@@ -1578,7 +1529,7 @@ class GlobalCommands:
1578
1529
  try:
1579
1530
  port = control_port_file.read_text().strip()
1580
1531
  print(f"Control Port: {port}")
1581
- except IOError:
1532
+ except OSError:
1582
1533
  pass
1583
1534
 
1584
1535
  # Check switch status
@@ -1605,6 +1556,7 @@ class GlobalCommands:
1605
1556
  def orch_restart(self, args: argparse.Namespace) -> None:
1606
1557
  """Request orchestrator to restart ComfyUI."""
1607
1558
  import time
1559
+
1608
1560
  from .utils.orchestrator import is_orchestrator_running, safe_write_command
1609
1561
 
1610
1562
  metadata_dir = self.workspace.path / ".metadata"
@@ -1643,11 +1595,12 @@ class GlobalCommands:
1643
1595
  def orch_kill(self, args: argparse.Namespace) -> None:
1644
1596
  """Shutdown orchestrator."""
1645
1597
  import time
1598
+
1646
1599
  from .utils.orchestrator import (
1647
1600
  is_orchestrator_running,
1648
- safe_write_command,
1649
1601
  kill_orchestrator_process,
1650
- read_switch_status
1602
+ read_switch_status,
1603
+ safe_write_command,
1651
1604
  )
1652
1605
 
1653
1606
  metadata_dir = self.workspace.path / ".metadata"
@@ -1701,9 +1654,9 @@ class GlobalCommands:
1701
1654
  def orch_clean(self, args: argparse.Namespace) -> None:
1702
1655
  """Clean orchestrator state files."""
1703
1656
  from .utils.orchestrator import (
1657
+ cleanup_orchestrator_state,
1704
1658
  is_orchestrator_running,
1705
1659
  kill_orchestrator_process,
1706
- cleanup_orchestrator_state
1707
1660
  )
1708
1661
 
1709
1662
  metadata_dir = self.workspace.path / ".metadata"
@@ -1742,7 +1695,7 @@ class GlobalCommands:
1742
1695
  print("\nNote: workspace_config.json will be preserved")
1743
1696
 
1744
1697
  if args.kill:
1745
- print(f"\n⚠️ --kill flag: Will also terminate orchestrator process")
1698
+ print("\n⚠️ --kill flag: Will also terminate orchestrator process")
1746
1699
 
1747
1700
  response = input("\nContinue? [y/N]: ").strip().lower()
1748
1701
  if response not in ['y', 'yes']:
@@ -1784,6 +1737,7 @@ class GlobalCommands:
1784
1737
  def orch_logs(self, args: argparse.Namespace) -> None:
1785
1738
  """Show orchestrator logs."""
1786
1739
  import subprocess
1740
+
1787
1741
  from .utils.orchestrator import tail_log_file
1788
1742
 
1789
1743
  metadata_dir = self.workspace.path / ".metadata"
@@ -1808,3 +1762,27 @@ class GlobalCommands:
1808
1762
  print("".join(lines))
1809
1763
  else:
1810
1764
  print("(empty log file)")
1765
+
1766
+ # === Workspace Management ===
1767
+
1768
+ @with_workspace_logging("workspace cleanup")
1769
+ def workspace_cleanup(self, args: argparse.Namespace) -> None:
1770
+ """Clean up legacy workspace artifacts.
1771
+
1772
+ Removes .metadata/system_nodes/ directory if no environments
1773
+ still use legacy symlinked manager.
1774
+ """
1775
+ force = getattr(args, 'force', False)
1776
+
1777
+ result = self.workspace.cleanup_legacy_system_nodes(force=force)
1778
+
1779
+ if result.success:
1780
+ print(f"Removed {result.removed_path}")
1781
+ else:
1782
+ if result.legacy_environments:
1783
+ print("Cannot cleanup: Some environments still use legacy manager")
1784
+ for env in result.legacy_environments:
1785
+ print(f" {env}")
1786
+ print("\nRun 'cg -e <ENV> manager update' to migrate, then retry.")
1787
+ else:
1788
+ print(f"{result.message}")
@@ -408,21 +408,21 @@ def with_env_logging(command_name: str, get_env_name: Callable | None = None, lo
408
408
  """Decorator for environment commands that automatically sets up logging.
409
409
 
410
410
  Args:
411
- command_name: Name of the command for logging (e.g., "env create")
411
+ command_name: Name of the command for logging (e.g., "create", "node add")
412
412
  get_env_name: Optional function to extract env name from args.
413
- If None, tries args.name, then args.env_name,
413
+ If None, tries args.name, then args.env_name,
414
414
  then calls self._get_env_name(args) if available.
415
415
  log_args: If True, automatically logs all args attributes (default: True)
416
416
  **log_context: Additional static context to log
417
-
417
+
418
418
  Example:
419
- @with_env_logging("env create") # Automatically logs all args
419
+ @with_env_logging("create") # Automatically logs all args
420
420
  def create(self, args):
421
421
  # All logging automatically goes to environment log
422
422
  result = self.env_mgr.create_environment(...)
423
-
424
- @with_env_logging("env apply", log_args=False, custom_field="value")
425
- def apply(self, args):
423
+
424
+ @with_env_logging("repair", log_args=False, custom_field="value")
425
+ def repair(self, args):
426
426
  # Only logs custom_field, not args
427
427
  """
428
428
  def decorator(func: Callable) -> Callable:
@@ -5,5 +5,5 @@ def show_civitai_auth_help() -> None:
5
5
  """Display helpful message for Civitai authentication errors."""
6
6
  print("\n💡 Civitai API key required")
7
7
  print(" 1. Get your API key from: https://civitai.com/user/account")
8
- print(" 2. Add it to ComfyGit: comfygit config --civitai-key <your-key>")
8
+ print(" 2. Add it to ComfyGit: cg config --civitai-key <your-key>")
9
9
  print(" 3. Try downloading again")