comfygit-core 0.5.0__tar.gz → 0.6.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 (439) hide show
  1. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/PKG-INFO +2 -2
  2. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/pyproject.toml +2 -2
  3. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/node_classifier.py +1 -2
  4. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/node_git_analyzer.py +1 -1
  5. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/status_scanner.py +51 -14
  6. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/caching/workflow_cache.py +1 -1
  7. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/configs/package_config.py +1 -0
  8. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/constants.py +6 -0
  9. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/core/environment.py +116 -20
  10. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/core/workspace.py +17 -1
  11. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/integrations/uv_command.py +1 -1
  12. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/lifecycle/switch_observer.py +16 -3
  13. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/environment_git_orchestrator.py +32 -59
  14. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/export_import_manager.py +53 -3
  15. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/git_manager.py +3 -0
  16. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/model_symlink_manager.py +2 -2
  17. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/node_manager.py +61 -9
  18. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/overlay_manager.py +1 -1
  19. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/pytorch_backend_manager.py +1 -1
  20. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/user_content_symlink_manager.py +2 -2
  21. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/uv_project_manager.py +71 -7
  22. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/workflow_manager.py +51 -2
  23. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/disposable_project.py +15 -2
  24. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/pyproject_manifest.py +26 -0
  25. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/store.py +0 -1
  26. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/uv_config.py +3 -1
  27. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/merging/atomic_executor.py +1 -1
  28. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/__init__.py +11 -0
  29. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/environment.py +28 -7
  30. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/exceptions.py +2 -2
  31. comfygit_core-0.6.0/src/comfygit_core/models/lifecycle.py +346 -0
  32. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/overlay.py +14 -6
  33. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/shared.py +3 -0
  34. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/workflow.py +21 -14
  35. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/runtime.py +4 -0
  36. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/build_readiness.py +1 -1
  37. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/dependency_resolution_preview.py +1 -0
  38. comfygit_core-0.6.0/src/comfygit_core/services/environment_lifecycle.py +1037 -0
  39. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/node_lookup_service.py +90 -5
  40. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_execution.py +26 -3
  41. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_file_store.py +35 -0
  42. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_manifest_reconciler.py +171 -31
  43. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_resolution_fixer.py +1 -1
  44. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/common.py +15 -1
  45. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/conflict_analyzer.py +2 -2
  46. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/dependency_probe.py +82 -3
  47. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/download.py +57 -25
  48. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/environment_cleanup.py +50 -0
  49. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/environment_lock.py +6 -0
  50. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/filesystem.py +19 -3
  51. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/git.py +12 -2
  52. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/pytorch_prober.py +54 -5
  53. comfygit_core-0.6.0/src/comfygit_core/utils/toml_compat.py +10 -0
  54. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/validation/resolution_tester.py +3 -3
  55. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_branch_workflow_preservation.py +63 -32
  56. comfygit_core-0.6.0/tests/integration/test_lifecycle_status.py +158 -0
  57. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_optional_dependency_groups.py +7 -3
  58. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_overlay_git_integration.py +29 -0
  59. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_runtime_restart_workflow_preservation.py +37 -0
  60. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_caching_integration.py +13 -13
  61. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_subgraph_resolution.py +187 -0
  62. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/test_public_api.py +13 -0
  63. comfygit_core-0.6.0/tests/unit/analyzers/test_node_git_analyzer.py +37 -0
  64. comfygit_core-0.6.0/tests/unit/analyzers/test_status_scanner.py +21 -0
  65. comfygit_core-0.6.0/tests/unit/analyzers/test_status_scanner_package_sync.py +25 -0
  66. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_environment_facades.py +81 -2
  67. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_environment_operation_locking.py +11 -0
  68. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_environment_run.py +16 -0
  69. comfygit_core-0.6.0/tests/unit/core/test_environment_sync.py +27 -0
  70. comfygit_core-0.6.0/tests/unit/core/test_workflow_contract_access.py +12 -0
  71. comfygit_core-0.6.0/tests/unit/core/test_workspace_environment_creation.py +62 -0
  72. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_export_import_overlays.py +39 -0
  73. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_git_manager_gitignore.py +2 -0
  74. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_node_manager.py +33 -1
  75. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_pyproject_manager.py +29 -2
  76. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_pytorch_overlay_materialization.py +136 -0
  77. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_uv_no_build_isolation.py +39 -0
  78. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_workflow_manager.py +59 -0
  79. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_workflow_node_cleanup.py +27 -0
  80. comfygit_core-0.6.0/tests/unit/models/test_lifecycle.py +161 -0
  81. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/models/test_overlay.py +18 -0
  82. comfygit_core-0.6.0/tests/unit/services/test_environment_lifecycle.py +644 -0
  83. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_node_lookup_api_first.py +20 -0
  84. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_node_lookup_version_fallback.py +57 -1
  85. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_scan_requirements_substitution.py +42 -0
  86. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_execution.py +35 -0
  87. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_file_store.py +46 -0
  88. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_user_content_symlink_manager.py +22 -0
  89. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_dependency_probe.py +167 -4
  90. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_environment_cleanup.py +43 -0
  91. comfygit_core-0.6.0/tests/unit/utils/test_filesystem.py +74 -0
  92. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_pytorch_prober.py +122 -20
  93. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/.gitignore +0 -0
  94. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/.python-version +0 -0
  95. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/AGENTS.md +0 -0
  96. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/CLAUDE.md +0 -0
  97. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/LICENSE.txt +0 -0
  98. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/README.md +0 -0
  99. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/docs/architecture-deep-dive.md +0 -0
  100. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/docs/architecture.md +0 -0
  101. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/docs/knowledge/comfyui-node-loader-base-directories.md +0 -0
  102. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/docs/knowledge/model-tracking-system.md +0 -0
  103. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/docs/knowledge/node-resolution-behavior.md +0 -0
  104. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/docs/layer-hierarchy.md +0 -0
  105. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/docs/plans/uv-overlay-system.md +0 -0
  106. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/__init__.py +0 -0
  107. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/__init__.py +0 -0
  108. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/config_comparison.py +0 -0
  109. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/custom_node_scanner.py +0 -0
  110. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/git_change_parser.py +0 -0
  111. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/model_scanner.py +0 -0
  112. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/ref_diff_analyzer.py +0 -0
  113. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/unmanaged_comfyui_analyzer.py +0 -0
  114. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/analyzers/workflow_dependency_parser.py +0 -0
  115. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/assets.py +0 -0
  116. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/build_readiness.py +0 -0
  117. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/caching/__init__.py +0 -0
  118. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/caching/api_cache.py +0 -0
  119. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/caching/base.py +0 -0
  120. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/caching/comfyui_cache.py +0 -0
  121. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/caching/custom_node_cache.py +0 -0
  122. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/clients/__init__.py +0 -0
  123. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/clients/civitai_client.py +0 -0
  124. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/clients/github_client.py +0 -0
  125. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/clients/registry_client.py +0 -0
  126. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/configs/__init__.py +0 -0
  127. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/configs/comfyui_builtin_nodes.py +0 -0
  128. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/configs/comfyui_models.py +0 -0
  129. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/configs/model_config.py +0 -0
  130. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/confirmation.py +0 -0
  131. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/core/__init__.py +0 -0
  132. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/data/overlays/stock/sageattention.toml +0 -0
  133. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/data/overlays/stock/triton.toml +0 -0
  134. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/data/overlays/stock/xformers.toml +0 -0
  135. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/factories/__init__.py +0 -0
  136. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/factories/environment_factory.py +0 -0
  137. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/factories/uv_factory.py +0 -0
  138. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/factories/workspace_factory.py +0 -0
  139. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/git.py +0 -0
  140. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/imports.py +0 -0
  141. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/infrastructure/__init__.py +0 -0
  142. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/infrastructure/sqlite_manager.py +0 -0
  143. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/integrations/__init__.py +0 -0
  144. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/lifecycle/__init__.py +0 -0
  145. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/lifecycle/comfyui_readiness.py +0 -0
  146. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/logging/__init__.py +0 -0
  147. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/logging/logging_config.py +0 -0
  148. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/__init__.py +0 -0
  149. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/environment_model_manager.py +0 -0
  150. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/pyproject_manager.py +0 -0
  151. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/managers/system_node_symlink_manager.py +0 -0
  152. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/__init__.py +0 -0
  153. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/base.py +0 -0
  154. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/dependencies.py +0 -0
  155. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/migrations.py +0 -0
  156. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/models.py +0 -0
  157. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/nodes.py +0 -0
  158. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/overlays.py +0 -0
  159. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/sync_config.py +0 -0
  160. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/manifest/workflows.py +0 -0
  161. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/merging/__init__.py +0 -0
  162. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/merging/merge_validator.py +0 -0
  163. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/merging/semantic_merger.py +0 -0
  164. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/build_readiness.py +0 -0
  165. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/civitai.py +0 -0
  166. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/comfyui_builtin_versions.py +0 -0
  167. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/commit.py +0 -0
  168. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/dependency_resolution.py +0 -0
  169. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/git.py +0 -0
  170. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/manifest.py +0 -0
  171. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/materialization.py +0 -0
  172. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/merge_plan.py +0 -0
  173. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/model_scan.py +0 -0
  174. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/node_mapping.py +0 -0
  175. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/protocols.py +0 -0
  176. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/readiness.py +0 -0
  177. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/ref_diff.py +0 -0
  178. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/registry.py +0 -0
  179. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/runtime_config.py +0 -0
  180. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/sync.py +0 -0
  181. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/system.py +0 -0
  182. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/unmanaged_import.py +0 -0
  183. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/workflow_contract.py +0 -0
  184. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/workflow_execution.py +0 -0
  185. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/models/workspace_config.py +0 -0
  186. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/py.typed +0 -0
  187. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/readiness.py +0 -0
  188. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/repositories/__init__.py +0 -0
  189. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/repositories/comfyui_builtin_versions_repository.py +0 -0
  190. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/repositories/migrate_paths.py +0 -0
  191. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/repositories/model_repository.py +0 -0
  192. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/repositories/node_mappings_repository.py +0 -0
  193. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/repositories/workflow_repository.py +0 -0
  194. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/repositories/workspace_config_repository.py +0 -0
  195. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/resolvers/__init__.py +0 -0
  196. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/resolvers/global_node_resolver.py +0 -0
  197. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/resolvers/model_resolver.py +0 -0
  198. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/__init__.py +0 -0
  199. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/environment_readiness.py +0 -0
  200. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/environment_sync_coordinator.py +0 -0
  201. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/huggingface_url.py +0 -0
  202. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/import_analyzer.py +0 -0
  203. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/model_downloader.py +0 -0
  204. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/model_source_lookup.py +0 -0
  205. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/registry_data_manager.py +0 -0
  206. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/unmanaged_environment_import.py +0 -0
  207. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_analysis_cache.py +0 -0
  208. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_analysis_service.py +0 -0
  209. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_input.py +0 -0
  210. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_manual_model_policy.py +0 -0
  211. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_model_dependency_service.py +0 -0
  212. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_model_download_coordinator.py +0 -0
  213. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_model_path_policy.py +0 -0
  214. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_node_package_policy.py +0 -0
  215. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_resolution_context_builder.py +0 -0
  216. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_resolution_service.py +0 -0
  217. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/services/workflow_state_cleanup.py +0 -0
  218. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/strategies/__init__.py +0 -0
  219. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/strategies/auto.py +0 -0
  220. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/strategies/confirmation.py +0 -0
  221. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/__init__.py +0 -0
  222. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/builtin_extractor.py +0 -0
  223. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/comfyui_ops.py +0 -0
  224. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/conflict_parser.py +0 -0
  225. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/dependency_parser.py +0 -0
  226. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/folder_paths_extractor.py +0 -0
  227. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/input_signature.py +0 -0
  228. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/model_categories.py +0 -0
  229. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/model_loader_extractor.py +0 -0
  230. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/node_identity.py +0 -0
  231. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/provider_urls.py +0 -0
  232. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/pytorch.py +0 -0
  233. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/redaction.py +0 -0
  234. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/requirements.py +0 -0
  235. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/retry.py +0 -0
  236. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/symlink_utils.py +0 -0
  237. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/system_detector.py +0 -0
  238. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/uuid.py +0 -0
  239. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/uv_error_handler.py +0 -0
  240. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/version.py +0 -0
  241. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/utils/workflow_hash.py +0 -0
  242. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/validation/__init__.py +0 -0
  243. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/src/comfygit_core/workflow.py +0 -0
  244. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/README.md +0 -0
  245. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/caching/TEST_REDUCTION_SUMMARY.md +0 -0
  246. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/caching/__init__.py +0 -0
  247. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/caching/test_workflow_cache.py +0 -0
  248. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/caching/test_workflow_cache_context_hash.py +0 -0
  249. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/conftest.py +0 -0
  250. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/models/test_models.json +0 -0
  251. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/workflows/checkpoint_loader_with_missing_model.json +0 -0
  252. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/workflows/kjnodes_workflow.json +0 -0
  253. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/workflows/simple_txt2img.json +0 -0
  254. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/workflows/with_custom_node.json +0 -0
  255. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/workflows/with_missing_model.json +0 -0
  256. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/workflows/workflow_with_duplicates.json +0 -0
  257. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/workflows/workflow_with_properties.json +0 -0
  258. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/fixtures/workflows/workflow_without_properties.json +0 -0
  259. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/helpers/__init__.py +0 -0
  260. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/helpers/model_index_builder.py +0 -0
  261. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/helpers/pyproject_assertions.py +0 -0
  262. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/helpers/workflow_builder.py +0 -0
  263. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_atomic_semantic_merge.py +0 -0
  264. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_auto_model_index_sync.py +0 -0
  265. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_cache_invalidation_on_model_deletion.py +0 -0
  266. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_cache_node_version_invalidation.py +0 -0
  267. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_checkout_b_with_modified_workflow.py +0 -0
  268. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_commit_git_changes.py +0 -0
  269. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_commit_git_changes_SUMMARY.md +0 -0
  270. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_commit_history.py +0 -0
  271. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_context_aware_node_resolution.py +0 -0
  272. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_create_with_version_spec.py +0 -0
  273. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_custom_node_path_preservation.py +0 -0
  274. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_deferred_model_downloads.py +0 -0
  275. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_deleted_model_download_intent.py +0 -0
  276. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_dependency_group_removal.py +0 -0
  277. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_dev_node_git_references.py +0 -0
  278. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_dev_node_improvements.py +0 -0
  279. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_download_cleanup.py +0 -0
  280. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_download_intent_cache_invalidation.py +0 -0
  281. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_environment_basic.py +0 -0
  282. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_environment_branching.py +0 -0
  283. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_environment_create_progress.py +0 -0
  284. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_export_import.py +0 -0
  285. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_git_branching.py +0 -0
  286. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_git_import.py +0 -0
  287. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_git_pull_push.py +0 -0
  288. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_git_remote.py +0 -0
  289. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_git_subdirectory_import.py +0 -0
  290. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_import_auto_remote.py +0 -0
  291. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_import_comfyui_version_bug.py +0 -0
  292. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_import_preview.py +0 -0
  293. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_category_mismatch_detection.py +0 -0
  294. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_directory_switch.py +0 -0
  295. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_download_integration.py +0 -0
  296. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_index_mismatch_bug_SUMMARY.md +0 -0
  297. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_path_sync_detection.py +0 -0
  298. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_resolution_stale_directory.py +0 -0
  299. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_show_command.py +0 -0
  300. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_source_management.py +0 -0
  301. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_source_preservation.py +0 -0
  302. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_source_preservation_SUMMARY.md +0 -0
  303. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_model_source_removal.py +0 -0
  304. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_multiple_optional_group_failures.py +0 -0
  305. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_node_prune.py +0 -0
  306. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_node_version_replacement.py +0 -0
  307. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_opencv_conflict_resolution.py +0 -0
  308. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_overlay_e2e.py +0 -0
  309. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_overlay_system_integration.py +0 -0
  310. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_package_config.py +0 -0
  311. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_per_environment_manager.py +0 -0
  312. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_pyproject_batch_writes.py +0 -0
  313. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_pytorch_reconfiguration.py +0 -0
  314. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_registry_git_fallback.py +0 -0
  315. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_registry_node_update_empty_download_url.py +0 -0
  316. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_repair_completion_marker.py +0 -0
  317. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_repair_model_download.py +0 -0
  318. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_repair_node_removal.py +0 -0
  319. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_repair_workflow.py +0 -0
  320. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_requirements_inline_comments_bug.py +0 -0
  321. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_status_abstraction.py +0 -0
  322. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_status_uninstalled_nodes.py +0 -0
  323. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_cache_metadata_invalidation.py +0 -0
  324. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_commit_flow.py +0 -0
  325. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_deletion_cleanup.py +0 -0
  326. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_model_criticality_update.py +0 -0
  327. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_path_update_after_interactive_resolution.py +0 -0
  328. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_resolution_cleanup.py +0 -0
  329. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_resolution_pipeline.py +0 -0
  330. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/integration/test_workflow_resolve_install.py +0 -0
  331. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/test_architecture_boundaries.py +0 -0
  332. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/analyzers/test_config_comparison.py +0 -0
  333. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/analyzers/test_custom_node_scanner.py +0 -0
  334. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/analyzers/test_ref_diff_analyzer.py +0 -0
  335. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/analyzers/test_status_scanner_disabled_nodes.py +0 -0
  336. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/analyzers/test_workflow_dependency_parser.py +0 -0
  337. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/caching/test_cache_base.py +0 -0
  338. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/caching/test_comfyui_cache.py +0 -0
  339. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/caching/test_custom_node_cache_refactor.py +0 -0
  340. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/caching/test_workspace_relative_caching.py +0 -0
  341. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/clients/test_civitai_client.py +0 -0
  342. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/clients/test_civitai_parsing.py +0 -0
  343. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/clients/test_github_releases.py +0 -0
  344. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/configs/__init__.py +0 -0
  345. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/configs/test_package_config.py +0 -0
  346. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_environment_uninstalled_nodes.py +0 -0
  347. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_import_download_failures.py +0 -0
  348. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_import_no_manager.py +0 -0
  349. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_reserved_environment_names.py +0 -0
  350. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_sync_node_dependency_provisioning.py +0 -0
  351. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/core/test_workspace_model_delete.py +0 -0
  352. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/factories/test_environment_factory_manager_install.py +0 -0
  353. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/lifecycle/test_comfyui_readiness.py +0 -0
  354. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_environment_model_manager.py +0 -0
  355. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_git_manager_log_refs.py +0 -0
  356. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_model_index_manager.py +0 -0
  357. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_model_short_hash.py +0 -0
  358. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_node_conflict_detection.py +0 -0
  359. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_overlay_fuzz.py +0 -0
  360. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_overlay_manager.py +0 -0
  361. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_overlay_materialization.py +0 -0
  362. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_pyproject_schema_version.py +0 -0
  363. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_pytorch_backend_manager.py +0 -0
  364. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_pytorch_stripping.py +0 -0
  365. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_sqlite_manager.py +0 -0
  366. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/managers/test_workflow_status.py +0 -0
  367. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/merging/__init__.py +0 -0
  368. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/merging/test_atomic_executor.py +0 -0
  369. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/merging/test_merge_validator.py +0 -0
  370. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/merging/test_semantic_merger.py +0 -0
  371. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/models/test_comfyui_builtin_versions.py +0 -0
  372. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/models/test_ref_diff.py +0 -0
  373. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/models/test_workflow_contract.py +0 -0
  374. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/models/test_workflow_dependencies.py +0 -0
  375. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/models/test_workflow_roundtrip.py +0 -0
  376. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/models/test_workflow_subgraph.py +0 -0
  377. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/resolvers/test_global_node_resolver_v2.py +0 -0
  378. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/resolvers/test_model_resolver.py +0 -0
  379. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_build_readiness.py +0 -0
  380. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_dependency_resolution_preview.py +0 -0
  381. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_environment_readiness.py +0 -0
  382. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_global_node_resolver.py +0 -0
  383. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_huggingface_url.py +0 -0
  384. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_import_analyzer.py +0 -0
  385. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_model_downloader.py +0 -0
  386. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_model_source_lookup.py +0 -0
  387. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_registry_data_manager.py +0 -0
  388. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_unmanaged_environment_import.py +0 -0
  389. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_analysis_cache.py +0 -0
  390. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_analysis_service.py +0 -0
  391. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_input.py +0 -0
  392. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_model_dependency_service.py +0 -0
  393. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_model_download_coordinator.py +0 -0
  394. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_model_path_policy.py +0 -0
  395. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_resolution_context_builder.py +0 -0
  396. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_resolution_fixer.py +0 -0
  397. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_resolution_service.py +0 -0
  398. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/services/test_workflow_state_cleanup.py +0 -0
  399. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_add_dependencies_substitution.py +0 -0
  400. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_auto_strategies.py +0 -0
  401. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_builtin_extractor.py +0 -0
  402. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_dev_node_rename_detection.py +0 -0
  403. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_environment_py_dependencies.py +0 -0
  404. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_external_uv_cache.py +0 -0
  405. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_folder_paths_extractor.py +0 -0
  406. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_github_auth_config.py +0 -0
  407. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_github_url_installation.py +0 -0
  408. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_headless_import.py +0 -0
  409. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_materialization.py +0 -0
  410. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_minimal_schema_compatibility.py +0 -0
  411. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_model_config_dynamic_loading.py +0 -0
  412. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_model_downloader_errors.py +0 -0
  413. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_model_loader_extractor.py +0 -0
  414. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_model_repository_cleanup.py +0 -0
  415. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_model_symlink_manager.py +0 -0
  416. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_node_callbacks.py +0 -0
  417. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_node_conflict_context.py +0 -0
  418. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_node_mappings_repository.py +0 -0
  419. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_node_resolution_context.py +0 -0
  420. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_unified_node_search.py +0 -0
  421. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_uv_error_handling.py +0 -0
  422. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_uv_error_parser.py +0 -0
  423. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_workflow_manager_deduplication.py +0 -0
  424. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_workspace_config_facade.py +0 -0
  425. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/test_workspace_config_resilience.py +0 -0
  426. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_conflict_analyzer.py +0 -0
  427. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_conflict_parser.py +0 -0
  428. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_dependency_parser.py +0 -0
  429. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_git.py +0 -0
  430. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_input_signature.py +0 -0
  431. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_node_identity.py +0 -0
  432. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_provider_auth_hardening.py +0 -0
  433. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_pytorch.py +0 -0
  434. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_requirements.py +0 -0
  435. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_symlink_utils.py +0 -0
  436. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_uuid.py +0 -0
  437. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/unit/utils/test_version.py +0 -0
  438. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/utils/__init__.py +0 -0
  439. {comfygit_core-0.5.0 → comfygit_core-0.6.0}/tests/utils/test_workflow_hash.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comfygit-core
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: ComfyGit Core - Git-based ComfyUI environment manager
5
5
  Project-URL: Documentation, https://docs.comfygit.org/
6
6
  Project-URL: Repository, https://github.com/comfygit-ai/comfygit
@@ -10,7 +10,7 @@ Requires-Python: >=3.10
10
10
  Requires-Dist: blake3>=0.3.3
11
11
  Requires-Dist: huggingface-hub>=0.11.0
12
12
  Requires-Dist: packaging>=16.2
13
- Requires-Dist: requests>=2.33.0
13
+ Requires-Dist: requests>=2.32.4
14
14
  Requires-Dist: requirements-parser>=0.11.0
15
15
  Requires-Dist: tomlkit>=0.11.0
16
16
  Requires-Dist: uv>=0.11.8
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "comfygit-core"
3
- version = "0.5.0"
3
+ version = "0.6.0"
4
4
  description = "ComfyGit Core - Git-based ComfyUI environment manager"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -8,7 +8,7 @@ dependencies = [
8
8
  "blake3>=0.3.3",
9
9
  "huggingface_hub>=0.11.0",
10
10
  "packaging>=16.2",
11
- "requests>=2.33.0",
11
+ "requests>=2.32.4",
12
12
  "requirements-parser>=0.11.0",
13
13
  "tomlkit>=0.11.0",
14
14
  "uv>=0.11.8",
@@ -6,11 +6,10 @@ from dataclasses import dataclass, field
6
6
  from pathlib import Path
7
7
  from typing import TYPE_CHECKING
8
8
 
9
- import tomllib
10
-
11
9
  from ..configs.comfyui_builtin_nodes import COMFYUI_BUILTIN_NODES
12
10
  from ..logging.logging_config import get_logger
13
11
  from ..models.comfyui_builtin_versions import BuiltinVersionGateInfo
12
+ from ..utils.toml_compat import tomllib
14
13
 
15
14
  if TYPE_CHECKING:
16
15
  from ..configs.model_config import ModelConfig
@@ -67,7 +67,7 @@ def get_node_git_info(node_path: Path) -> GitInfo | None:
67
67
  git_info.github_repo = github_match.group(2).replace(".git", "")
68
68
 
69
69
  # Check if there are uncommitted changes
70
- status_entries = git_status_porcelain(node_path)
70
+ status_entries = git_status_porcelain(node_path, check=False)
71
71
  git_info.is_dirty = bool(status_entries)
72
72
 
73
73
  return git_info
@@ -41,6 +41,25 @@ def _versions_match(actual: str | None, expected: str | None) -> bool:
41
41
  return False
42
42
 
43
43
 
44
+ _UV_DRY_RUN_CHANGE_PREFIXES = (
45
+ "Would update lockfile",
46
+ "Would download ",
47
+ "Would install ",
48
+ "Would uninstall ",
49
+ "Would upgrade ",
50
+ "Would downgrade ",
51
+ "Would remove ",
52
+ )
53
+
54
+
55
+ def _uv_dry_run_reports_changes(output: str) -> bool:
56
+ """Return True when uv dry-run output says sync would mutate the env."""
57
+ return any(
58
+ line.strip().startswith(_UV_DRY_RUN_CHANGE_PREFIXES)
59
+ for line in output.splitlines()
60
+ )
61
+
62
+
44
63
  class StatusScanner:
45
64
  """Scans environment to get current state."""
46
65
 
@@ -58,7 +77,12 @@ class StatusScanner:
58
77
  self._comfyui_path = comfyui_path
59
78
  self._pytorch_manager = pytorch_manager
60
79
 
61
- def get_full_comparison(self) -> EnvironmentComparison:
80
+ def get_full_comparison(
81
+ self,
82
+ *,
83
+ check_package_sync: bool = False,
84
+ backend_override: str | None = None,
85
+ ) -> EnvironmentComparison:
62
86
  """Get complete environment comparison with all details.
63
87
 
64
88
  Args:
@@ -77,17 +101,19 @@ class StatusScanner:
77
101
  # Get basic comparison
78
102
  comparison = self.compare_states(current, expected)
79
103
 
80
- # Skip package sync check for performance (100-500ms saved)
81
- # Rationale:
82
- # - Users rarely manually modify .venv/
83
- # - Operations like 'run', 'repair', 'node add' auto-sync before executing
84
- # - Status is high-frequency with workflow caching - needs to be fast
85
- # - Package drift self-corrects on next sync operation
86
- # If thorough check needed, use 'cg repair --dry-run' (future)
87
- # TODO: Add package sync status
88
- # package_status = self.check_packages_sync()
89
- comparison.packages_in_sync = True #package_status.in_sync
90
- comparison.package_sync_message = "" #package_status.message
104
+ if check_package_sync:
105
+ package_status = self.check_packages_sync(
106
+ backend_override=backend_override
107
+ )
108
+ comparison.packages_in_sync = package_status.in_sync
109
+ comparison.package_sync_message = package_status.message
110
+ else:
111
+ # Keep high-frequency status fast unless the manifest diff says uv
112
+ # materialization may be needed. Package drift self-corrects on the
113
+ # next explicit sync/run path, but dependency edits should guide the
114
+ # user to sync before committing.
115
+ comparison.packages_in_sync = True
116
+ comparison.package_sync_message = ""
91
117
 
92
118
  return comparison
93
119
 
@@ -400,7 +426,11 @@ class StatusScanner:
400
426
 
401
427
  return comparison
402
428
 
403
- def check_packages_sync(self) -> PackageSyncStatus:
429
+ def check_packages_sync(
430
+ self,
431
+ *,
432
+ backend_override: str | None = None,
433
+ ) -> PackageSyncStatus:
404
434
  """Check if packages are in sync with pyproject.toml.
405
435
 
406
436
  Returns:
@@ -410,13 +440,20 @@ class StatusScanner:
410
440
  # Use UV's dry-run to check if sync would change anything
411
441
  # Disposable PyTorch overlay materialization ensures the check uses the correct backend.
412
442
  extras, all_extras = self._pyproject.resolve_sync_extras(None, False)
413
- self._uv.sync_project(
443
+ dry_run_output = self._uv.sync_project(
414
444
  dry_run=True,
415
445
  all_groups=True,
416
446
  pytorch_manager=self._pytorch_manager,
447
+ backend_override=backend_override,
417
448
  extras=extras,
418
449
  all_extras=all_extras,
419
450
  )
451
+ if _uv_dry_run_reports_changes(dry_run_output):
452
+ return PackageSyncStatus(
453
+ in_sync=False,
454
+ message="Packages out of sync (run 'cg sync' to update)",
455
+ details=dry_run_output,
456
+ )
420
457
  return PackageSyncStatus(
421
458
  in_sync=True, message="Packages match pyproject.toml"
422
459
  )
@@ -246,7 +246,7 @@ class WorkflowCacheRepository:
246
246
  if from_version == to_version:
247
247
  return
248
248
 
249
- logger.info(f"Migrating workflow cache schema v{from_version} → v{to_version}")
249
+ logger.info(f"Migrating workflow cache schema v{from_version} -> v{to_version}")
250
250
 
251
251
  # Drop and recreate (cache is ephemeral)
252
252
  self.sqlite.execute_write("DROP TABLE IF EXISTS workflow_cache")
@@ -31,6 +31,7 @@ DEFAULT_PROBE_PROTECTED = [
31
31
  "torchvision",
32
32
  "torchaudio",
33
33
  "torchsde",
34
+ "uv",
34
35
  ]
35
36
 
36
37
  class PackageConfigManager:
@@ -77,6 +77,12 @@ LEGACY_SYSTEM_NODES = {
77
77
  MANAGER_NODE_ID = 'comfygit-manager'
78
78
  MANAGER_GITHUB_URL = 'https://github.com/comfygit-ai/comfygit-manager'
79
79
 
80
+ # Runtime-only PyTorch backend override used by `cg run --torch-backend`.
81
+ # This is intentionally non-persistent: it tells child Manager/UI processes
82
+ # which backend policy launched the current ComfyUI process without writing to
83
+ # `.pytorch-backend`.
84
+ ACTIVE_TORCH_BACKEND_OVERRIDE_ENV = "COMFYGIT_TORCH_BACKEND_OVERRIDE"
85
+
80
86
  # Schema version for environment pyproject.toml format.
81
87
  # Increment when making breaking changes to the pyproject.toml structure.
82
88
  # v1: Original format with inline PyTorch config (indexes, sources, constraints)
@@ -7,13 +7,14 @@ import re
7
7
  import shutil
8
8
  import subprocess
9
9
  from collections.abc import Mapping, Sequence
10
- from datetime import UTC, datetime
10
+ from datetime import datetime, timezone
11
11
  from functools import cached_property, wraps
12
12
  from pathlib import Path
13
13
  from typing import TYPE_CHECKING, cast
14
14
 
15
15
  from ..analyzers.ref_diff_analyzer import RefDiffAnalyzer
16
16
  from ..analyzers.status_scanner import StatusScanner
17
+ from ..constants import ACTIVE_TORCH_BACKEND_OVERRIDE_ENV
17
18
  from ..factories.uv_factory import create_uv_for_environment
18
19
  from ..logging.logging_config import get_logger
19
20
  from ..managers.environment_git_orchestrator import EnvironmentGitOrchestrator
@@ -82,6 +83,11 @@ if TYPE_CHECKING:
82
83
  DependencyResolutionApplyResult,
83
84
  DependencyResolutionPreview,
84
85
  )
86
+ from ..models.lifecycle import (
87
+ EnvironmentLifecycleStatus,
88
+ LifecycleOperationState,
89
+ LifecycleRuntimeState,
90
+ )
85
91
  from ..models.manifest import (
86
92
  EnvironmentManifestSnapshot,
87
93
  ManifestWorkflowEntry,
@@ -107,6 +113,7 @@ if TYPE_CHECKING:
107
113
  from ..services.node_lookup_service import NodeLookupService
108
114
 
109
115
  logger = get_logger(__name__)
116
+ UTC = timezone.utc
110
117
 
111
118
 
112
119
  def _workflow_api_prompt_relpath(workflow_name: str) -> Path:
@@ -582,8 +589,27 @@ class Environment:
582
589
  # Environment Management
583
590
  # =====================================================
584
591
 
592
+ def _get_active_torch_backend_override(self) -> str | None:
593
+ """Return the non-persistent backend override active for this process."""
594
+ backend = os.environ.get(ACTIVE_TORCH_BACKEND_OVERRIDE_ENV)
595
+ if not backend:
596
+ return None
597
+
598
+ if self.is_valid_torch_backend(backend):
599
+ return backend
600
+
601
+ logger.warning(
602
+ "Ignoring invalid %s=%r",
603
+ ACTIVE_TORCH_BACKEND_OVERRIDE_ENV,
604
+ backend,
605
+ )
606
+ return None
607
+
585
608
  def status(self) -> EnvironmentStatus:
586
609
  """Get environment sync and git status."""
610
+ git_status = self.git_manager.get_status(self.pyproject)
611
+ active_backend_override = self._get_active_torch_backend_override()
612
+
587
613
  # Each subsystem provides its complete status
588
614
  scanner = StatusScanner(
589
615
  comfyui_path=self.comfyui_path,
@@ -592,9 +618,10 @@ class Environment:
592
618
  pyproject=self.pyproject,
593
619
  pytorch_manager=self.pytorch_manager,
594
620
  )
595
- comparison = scanner.get_full_comparison()
596
-
597
- git_status = self.git_manager.get_status(self.pyproject)
621
+ comparison = scanner.get_full_comparison(
622
+ check_package_sync=git_status.has_dependency_changes,
623
+ backend_override=active_backend_override,
624
+ )
598
625
 
599
626
  workflow_status = self.workflow_manager.get_workflow_status()
600
627
 
@@ -609,6 +636,37 @@ class Environment:
609
636
  missing_models=missing_models
610
637
  )
611
638
 
639
+ def get_lifecycle_status(
640
+ self,
641
+ *,
642
+ status: EnvironmentStatus | None = None,
643
+ include_readiness: bool = False,
644
+ runtime_state: LifecycleRuntimeState | None = None,
645
+ operation_state: LifecycleOperationState | None = None,
646
+ ) -> EnvironmentLifecycleStatus:
647
+ """Return composed lifecycle health and recommended actions.
648
+
649
+ This facade keeps adapters on the public Environment API. Core computes
650
+ manifest/filesystem/snapshot/workspace-index signals from existing
651
+ status/readiness paths; Manager or CLI may pass runtime/operation state
652
+ that only the adapter can observe.
653
+ """
654
+ from ..services.environment_lifecycle import (
655
+ build_lifecycle_status_from_environment_status,
656
+ )
657
+ from ..utils.git import git_rev_parse
658
+
659
+ readiness = self.get_readiness() if include_readiness else None
660
+ return build_lifecycle_status_from_environment_status(
661
+ status or self.status(),
662
+ environment_name=self.name,
663
+ workspace_path=str(self.workspace_paths.root),
664
+ current_commit=git_rev_parse(self.cec_path, "HEAD"),
665
+ readiness=readiness,
666
+ runtime_state=runtime_state,
667
+ operation_state=operation_state,
668
+ )
669
+
612
670
  def get_manager_status(self) -> ManagerStatus:
613
671
  """Check current comfygit-manager installation status.
614
672
 
@@ -652,7 +710,7 @@ class Environment:
652
710
  is_legacy = True
653
711
  # Try to read version from symlink target
654
712
  try:
655
- import tomllib
713
+ from ..utils.toml_compat import tomllib
656
714
  target_pyproject = legacy_path / "pyproject.toml"
657
715
  if target_pyproject.exists():
658
716
  with open(target_pyproject, "rb") as f:
@@ -844,9 +902,8 @@ class Environment:
844
902
 
845
903
  def _register_existing_manager(self, manager_path: Path) -> None:
846
904
  """Register existing manager directory in pyproject.toml."""
847
- import tomllib
848
-
849
905
  from ..constants import MANAGER_NODE_ID
906
+ from ..utils.toml_compat import tomllib
850
907
 
851
908
  # Detect version from manager's pyproject.toml
852
909
  version = None
@@ -961,6 +1018,10 @@ class Environment:
961
1018
  """
962
1019
  from ..services.environment_sync_coordinator import EnvironmentSyncCoordinator
963
1020
 
1021
+ effective_backend_override = (
1022
+ backend_override or self._get_active_torch_backend_override()
1023
+ )
1024
+
964
1025
  return EnvironmentSyncCoordinator(self).sync(
965
1026
  dry_run=dry_run,
966
1027
  model_strategy=model_strategy,
@@ -970,7 +1031,7 @@ class Environment:
970
1031
  sync_callbacks=sync_callbacks,
971
1032
  verbose=verbose,
972
1033
  preserve_workflows=preserve_workflows,
973
- backend_override=backend_override,
1034
+ backend_override=effective_backend_override,
974
1035
  overlay_names=overlay_names,
975
1036
  extras=extras,
976
1037
  all_extras=all_extras,
@@ -1469,10 +1530,9 @@ class Environment:
1469
1530
  Returns:
1470
1531
  MergeValidation with is_compatible flag and any conflicts
1471
1532
  """
1472
- import tomllib
1473
-
1474
1533
  from ..merging.merge_validator import MergeValidator
1475
1534
  from ..utils.git import git_show
1535
+ from ..utils.toml_compat import tomllib
1476
1536
 
1477
1537
  # Load configs from both branches
1478
1538
  pyproject_path = Path("pyproject.toml")
@@ -1509,12 +1569,11 @@ class Environment:
1509
1569
  Returns:
1510
1570
  MergeResult with success status and details
1511
1571
  """
1512
- import tomllib
1513
-
1514
1572
  from ..merging.atomic_executor import AtomicMergeExecutor
1515
1573
  from ..merging.merge_validator import MergeValidator
1516
1574
  from ..models.merge_plan import MergePlan
1517
1575
  from ..utils.git import git_show
1576
+ from ..utils.toml_compat import tomllib
1518
1577
 
1519
1578
  # Load configs to compute final workflow set
1520
1579
  pyproject_path = Path("pyproject.toml")
@@ -1599,11 +1658,18 @@ class Environment:
1599
1658
  raise
1600
1659
 
1601
1660
  # TODO wrap subprocess completed process instance
1602
- def run(self, args: list[str] | None = None) -> subprocess.CompletedProcess:
1661
+ def run(
1662
+ self,
1663
+ args: list[str] | None = None,
1664
+ *,
1665
+ backend_override: str | None = None,
1666
+ ) -> subprocess.CompletedProcess:
1603
1667
  """Run ComfyUI in this environment.
1604
1668
 
1605
1669
  Args:
1606
1670
  args: Arguments to pass to ComfyUI
1671
+ backend_override: Non-persistent PyTorch backend override used for
1672
+ this launched process.
1607
1673
 
1608
1674
  Returns:
1609
1675
  CompletedProcess
@@ -1618,6 +1684,8 @@ class Environment:
1618
1684
  child_env = os.environ.copy()
1619
1685
  child_env["COMFYGIT_ENV_NAME"] = self.name
1620
1686
  child_env["COMFYGIT_CG_RUN_SUPERVISOR"] = "1"
1687
+ if backend_override:
1688
+ child_env[ACTIVE_TORCH_BACKEND_OVERRIDE_ENV] = backend_override
1621
1689
 
1622
1690
  logger.info(f"Starting ComfyUI with: {' '.join(cmd)}")
1623
1691
  return run_command(
@@ -1779,12 +1847,19 @@ class Environment:
1779
1847
  return success_count, failed
1780
1848
 
1781
1849
  @_requires_env_lock
1782
- def remove_node(self, identifier: str, untrack_only: bool = False) -> NodeRemovalResult:
1850
+ def remove_node(
1851
+ self,
1852
+ identifier: str,
1853
+ untrack_only: bool = False,
1854
+ resolve_with_overlays: bool = False,
1855
+ ) -> NodeRemovalResult:
1783
1856
  """Remove a custom node.
1784
1857
 
1785
1858
  Args:
1786
1859
  identifier: Node identifier or name
1787
1860
  untrack_only: If True, only remove from pyproject.toml without touching filesystem
1861
+ resolve_with_overlays: If True, resolve post-removal sync with all active/extra
1862
+ overlays. If False, node sync defaults to pytorch-only overlays.
1788
1863
 
1789
1864
  Returns:
1790
1865
  NodeRemovalResult: Details about the removal
@@ -1792,19 +1867,25 @@ class Environment:
1792
1867
  Raises:
1793
1868
  CDNodeNotFoundError: If node not found
1794
1869
  """
1795
- return self.node_manager.remove_node(identifier, untrack_only=untrack_only)
1870
+ return self.node_manager.remove_node(
1871
+ identifier,
1872
+ untrack_only=untrack_only,
1873
+ skip_optional_overlays=not resolve_with_overlays,
1874
+ )
1796
1875
 
1797
1876
  @_requires_env_lock
1798
1877
  def remove_nodes_with_progress(
1799
1878
  self,
1800
1879
  node_ids: list[str],
1801
- callbacks: NodeInstallCallbacks | None = None
1880
+ callbacks: NodeInstallCallbacks | None = None,
1881
+ resolve_with_overlays: bool = False,
1802
1882
  ) -> tuple[int, list[tuple[str, str]]]:
1803
1883
  """Remove multiple nodes with callback support for progress tracking.
1804
1884
 
1805
1885
  Args:
1806
1886
  node_ids: List of node identifiers to remove
1807
1887
  callbacks: Optional callbacks for progress feedback
1888
+ resolve_with_overlays: If True, resolve node removals with all overlays.
1808
1889
 
1809
1890
  Returns:
1810
1891
  Tuple of (success_count, failed_nodes)
@@ -1824,7 +1905,7 @@ class Environment:
1824
1905
  callbacks.on_node_start(node_id, idx + 1, len(node_ids))
1825
1906
 
1826
1907
  try:
1827
- self.remove_node(node_id)
1908
+ self.remove_node(node_id, resolve_with_overlays=resolve_with_overlays)
1828
1909
  success_count += 1
1829
1910
  if callbacks and callbacks.on_node_complete:
1830
1911
  callbacks.on_node_complete(node_id, True, None)
@@ -1898,6 +1979,16 @@ class Environment:
1898
1979
  """Copy saved ComfyUI workflow files into tracked `.cec` workflow storage."""
1899
1980
  return self.workflow_manager.copy_all_workflows()
1900
1981
 
1982
+ @_requires_env_lock
1983
+ def capture_workflow(self, workflow_name: str) -> Path:
1984
+ """Capture one saved workflow into the tracked working environment.
1985
+
1986
+ The workflow is copied from ComfyUI's saved workflow directory into
1987
+ `.cec/workflows`, and best-effort dependency metadata is reconciled into
1988
+ the manifest. This does not commit the snapshot or install dependencies.
1989
+ """
1990
+ return self.workflow_manager.capture_workflow(workflow_name)
1991
+
1901
1992
  def get_workflow_status(self) -> DetailedWorkflowStatus:
1902
1993
  """Return analyzed workflow status without exposing the workflow manager."""
1903
1994
  return self.workflow_manager.get_workflow_status()
@@ -2379,7 +2470,13 @@ class Environment:
2379
2470
  config = edit.config
2380
2471
 
2381
2472
  for wf_analysis in workflow_status.analyzed_workflows:
2382
- if wf_analysis.sync_state in ("new", "modified"):
2473
+ if (
2474
+ wf_analysis.sync_state in ("new", "modified")
2475
+ or self.workflow_manager.resolution_changes_manifest(
2476
+ wf_analysis.resolution,
2477
+ config=config,
2478
+ )
2479
+ ):
2383
2480
  # Apply resolution results to pyproject (in-memory mutations)
2384
2481
  self.workflow_manager.apply_resolution(wf_analysis.resolution, config=config)
2385
2482
  edit.mark_changed()
@@ -2486,7 +2583,6 @@ class Environment:
2486
2583
  # Workflow Contract Management
2487
2584
  # =====================================================
2488
2585
 
2489
- @_requires_env_lock
2490
2586
  def get_workflow_execution_contract(self, workflow_name: str) -> WorkflowExecutionContract | None:
2491
2587
  """Get the saved execution contract for a workflow."""
2492
2588
  return self.pyproject.workflows.get_execution_contract(workflow_name)
@@ -2644,7 +2740,7 @@ class Environment:
2644
2740
  substituted = self.package_config.apply_substitution(pkg)
2645
2741
  if substituted != pkg:
2646
2742
  substitutions[pkg] = substituted
2647
- logger.info(f"Package substitution: {pkg} → {substituted}")
2743
+ logger.info(f"Package substitution: {pkg} -> {substituted}")
2648
2744
  transformed_packages.append(substituted)
2649
2745
  final_packages = transformed_packages
2650
2746
 
@@ -40,6 +40,7 @@ from ..repositories.model_repository import ModelRepository
40
40
  from ..services.model_downloader import ModelDownloader
41
41
  from ..services.registry_data_manager import RegistryDataManager
42
42
  from ..utils.environment_cleanup import (
43
+ DELETED_ENVIRONMENT_PREFIX,
43
44
  cleanup_partial_environment,
44
45
  is_environment_complete,
45
46
  remove_environment_directory,
@@ -524,6 +525,8 @@ class Workspace:
524
525
  return environments
525
526
 
526
527
  for env_dir in self.paths.environments.iterdir():
528
+ if env_dir.name.startswith(DELETED_ENVIRONMENT_PREFIX):
529
+ continue
527
530
  cec_path = env_dir / ".cec"
528
531
  if env_dir.is_dir() and cec_path.exists() and is_environment_complete(cec_path):
529
532
  try:
@@ -612,7 +615,20 @@ class Workspace:
612
615
  env_path = self.paths.environments / name
613
616
 
614
617
  if env_path.exists():
615
- raise CDEnvironmentExistsError(f"Environment '{name}' already exists")
618
+ cec_path = env_path / ".cec"
619
+ if is_environment_complete(cec_path):
620
+ raise CDEnvironmentExistsError(f"Environment '{name}' already exists")
621
+
622
+ logger.warning(
623
+ "Removing incomplete environment directory before recreating '%s': %s",
624
+ name,
625
+ env_path,
626
+ )
627
+ if not cleanup_partial_environment(env_path) or env_path.exists():
628
+ raise CDEnvironmentExistsError(
629
+ f"Environment '{name}' has an incomplete leftover directory at {env_path}. "
630
+ "Delete it manually or close processes using it before trying again."
631
+ )
616
632
 
617
633
  try:
618
634
  # Create the environment
@@ -36,7 +36,7 @@ class CommandResult:
36
36
  class UVCommand:
37
37
  """Pure wrapper around UV CLI commands. No business logic or pyproject.toml manipulation."""
38
38
 
39
- DEFAULT_TIMEOUT = None # no timeout
39
+ DEFAULT_TIMEOUT: int | None = None # no timeout
40
40
 
41
41
  def __init__(
42
42
  self,
@@ -5,7 +5,7 @@ import json
5
5
  import threading
6
6
  import time
7
7
  from collections.abc import Callable
8
- from datetime import UTC, datetime
8
+ from datetime import datetime, timezone
9
9
  from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
10
10
  from pathlib import Path
11
11
  from typing import Any
@@ -17,6 +17,7 @@ SUPERVISOR_INFO_FILE = ".supervisor_control.json"
17
17
  SWITCH_STATUS_ROUTE = "/v2/comfygit/switch_status"
18
18
  SWITCH_LOGS_ROUTE = "/v2/comfygit/switch_logs"
19
19
  SUPERVISOR_HEALTH_ROUTE = "/v2/comfygit/supervisor/health"
20
+ UTC = timezone.utc
20
21
 
21
22
 
22
23
  def metadata_dir_for(workspace_path: Path) -> Path:
@@ -100,11 +101,15 @@ def write_supervisor_advertisement(
100
101
  port: int,
101
102
  *,
102
103
  kind: str = "cg_run_supervisor",
104
+ public_origin: str | None = None,
103
105
  ) -> None:
104
106
  metadata_dir = metadata_dir_for(workspace_path)
105
107
  metadata_dir.mkdir(parents=True, exist_ok=True)
108
+ payload: dict[str, Any] = {"host": host, "port": port, "kind": kind}
109
+ if public_origin:
110
+ payload["public_origin"] = public_origin.rstrip("/")
106
111
  (metadata_dir / SUPERVISOR_INFO_FILE).write_text(
107
- json.dumps({"host": host, "port": port, "kind": kind}, indent=2),
112
+ json.dumps(payload, indent=2),
108
113
  encoding="utf-8",
109
114
  )
110
115
 
@@ -146,6 +151,7 @@ class SwitchObserverServer:
146
151
  port: int,
147
152
  *,
148
153
  kind: str = "cg_run_supervisor",
154
+ public_origin: str | None = None,
149
155
  post_handlers: dict[str, Callable[[], dict[str, Any]]] | None = None,
150
156
  ) -> None:
151
157
  self.workspace_path = workspace_path
@@ -153,6 +159,7 @@ class SwitchObserverServer:
153
159
  self.host = host
154
160
  self.port = port
155
161
  self.kind = kind
162
+ self.public_origin = public_origin.rstrip("/") if public_origin else None
156
163
  self.post_handlers = post_handlers or {}
157
164
  self._server: ThreadingHTTPServer | None = None
158
165
  self._thread: threading.Thread | None = None
@@ -170,7 +177,13 @@ class SwitchObserverServer:
170
177
  daemon=True,
171
178
  )
172
179
  self._thread.start()
173
- write_supervisor_advertisement(self.workspace_path, self.host, self.port, kind=self.kind)
180
+ write_supervisor_advertisement(
181
+ self.workspace_path,
182
+ self.host,
183
+ self.port,
184
+ kind=self.kind,
185
+ public_origin=self.public_origin,
186
+ )
174
187
  self.append_log(f"Supervisor control server listening on {self.host}:{self.port}")
175
188
 
176
189
  def stop(self) -> None: