comfygit-core 0.3.22__tar.gz → 0.4.1__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 (372) hide show
  1. comfygit_core-0.4.1/AGENTS.md +122 -0
  2. comfygit_core-0.4.1/CLAUDE.md +122 -0
  3. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/PKG-INFO +3 -3
  4. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/pyproject.toml +4 -4
  5. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/node_classifier.py +19 -1
  6. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/status_scanner.py +22 -2
  7. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/workflow_dependency_parser.py +114 -39
  8. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/workflow_cache.py +78 -28
  9. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/clients/civitai_client.py +182 -6
  10. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/clients/github_client.py +35 -16
  11. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/configs/__init__.py +2 -2
  12. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/configs/comfyui_models.py +10 -0
  13. comfygit_core-0.4.1/src/comfygit_core/configs/model_config.py +416 -0
  14. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/constants.py +2 -0
  15. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/core/environment.py +362 -91
  16. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/core/workspace.py +194 -3
  17. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/factories/environment_factory.py +82 -6
  18. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/factories/uv_factory.py +11 -3
  19. comfygit_core-0.4.1/src/comfygit_core/lifecycle/__init__.py +51 -0
  20. comfygit_core-0.4.1/src/comfygit_core/lifecycle/comfyui_readiness.py +163 -0
  21. comfygit_core-0.4.1/src/comfygit_core/lifecycle/switch_observer.py +249 -0
  22. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/environment_model_manager.py +31 -2
  23. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/export_import_manager.py +11 -2
  24. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/git_manager.py +8 -0
  25. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/node_manager.py +421 -15
  26. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/pyproject_manager.py +259 -30
  27. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/uv_project_manager.py +8 -5
  28. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/workflow_manager.py +428 -202
  29. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/__init__.py +27 -0
  30. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/civitai.py +18 -4
  31. comfygit_core-0.4.1/src/comfygit_core/models/dependency_resolution.py +73 -0
  32. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/exceptions.py +18 -3
  33. comfygit_core-0.4.1/src/comfygit_core/models/manifest.py +348 -0
  34. comfygit_core-0.4.1/src/comfygit_core/models/materialization.py +41 -0
  35. comfygit_core-0.4.1/src/comfygit_core/models/readiness.py +90 -0
  36. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/shared.py +50 -2
  37. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/workflow.py +77 -10
  38. comfygit_core-0.4.1/src/comfygit_core/models/workflow_contract.py +448 -0
  39. comfygit_core-0.4.1/src/comfygit_core/models/workflow_execution.py +78 -0
  40. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/workspace_config.py +6 -0
  41. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/__init__.py +2 -0
  42. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/model_repository.py +88 -30
  43. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/workspace_config_repository.py +32 -0
  44. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/resolvers/global_node_resolver.py +40 -12
  45. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/__init__.py +18 -1
  46. comfygit_core-0.4.1/src/comfygit_core/services/dependency_resolution_preview.py +368 -0
  47. comfygit_core-0.4.1/src/comfygit_core/services/environment_readiness.py +361 -0
  48. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/import_analyzer.py +20 -2
  49. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/model_downloader.py +70 -47
  50. comfygit_core-0.4.1/src/comfygit_core/services/model_source_lookup.py +158 -0
  51. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/node_lookup_service.py +43 -24
  52. comfygit_core-0.4.1/src/comfygit_core/services/workflow_analysis_service.py +611 -0
  53. comfygit_core-0.4.1/src/comfygit_core/services/workflow_execution.py +409 -0
  54. comfygit_core-0.4.1/src/comfygit_core/services/workflow_input.py +79 -0
  55. comfygit_core-0.4.1/src/comfygit_core/services/workflow_resolution_service.py +228 -0
  56. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/comfyui_ops.py +1 -1
  57. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/git.py +131 -14
  58. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/model_categories.py +12 -2
  59. comfygit_core-0.4.1/src/comfygit_core/utils/model_loader_extractor.py +349 -0
  60. comfygit_core-0.4.1/src/comfygit_core/utils/node_identity.py +60 -0
  61. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/caching/test_workflow_cache_context_hash.py +73 -0
  62. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_dev_node_git_references.py +31 -5
  63. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_export_import.py +13 -0
  64. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_optional_dependency_groups.py +13 -4
  65. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_pyproject_batch_writes.py +123 -2
  66. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_registry_git_fallback.py +15 -28
  67. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_deletion_cleanup.py +129 -0
  68. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_workflow_dependency_parser.py +110 -0
  69. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/clients/test_civitai_client.py +56 -1
  70. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/clients/test_civitai_parsing.py +17 -0
  71. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/clients/test_github_releases.py +28 -1
  72. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/core/test_environment_uninstalled_nodes.py +29 -0
  73. comfygit_core-0.4.1/tests/unit/core/test_import_download_failures.py +112 -0
  74. comfygit_core-0.4.1/tests/unit/core/test_sync_node_dependency_provisioning.py +121 -0
  75. comfygit_core-0.4.1/tests/unit/core/test_workspace_model_delete.py +89 -0
  76. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/factories/test_environment_factory_manager_install.py +2 -1
  77. comfygit_core-0.4.1/tests/unit/lifecycle/test_comfyui_readiness.py +41 -0
  78. comfygit_core-0.4.1/tests/unit/managers/test_environment_model_manager.py +92 -0
  79. comfygit_core-0.4.1/tests/unit/managers/test_git_manager_gitignore.py +61 -0
  80. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_model_short_hash.py +10 -1
  81. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_node_manager.py +262 -13
  82. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pyproject_manager.py +396 -4
  83. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pytorch_injection.py +43 -0
  84. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_workflow_manager.py +179 -0
  85. comfygit_core-0.4.1/tests/unit/models/test_workflow_dependencies.py +30 -0
  86. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_workflow_roundtrip.py +48 -0
  87. comfygit_core-0.4.1/tests/unit/services/test_dependency_resolution_preview.py +336 -0
  88. comfygit_core-0.4.1/tests/unit/services/test_environment_readiness.py +322 -0
  89. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_import_analyzer.py +15 -2
  90. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_model_downloader.py +141 -0
  91. comfygit_core-0.4.1/tests/unit/services/test_model_source_lookup.py +84 -0
  92. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_node_lookup_api_first.py +76 -0
  93. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_node_lookup_version_fallback.py +9 -16
  94. comfygit_core-0.4.1/tests/unit/services/test_workflow_analysis_service.py +135 -0
  95. comfygit_core-0.4.1/tests/unit/services/test_workflow_execution.py +362 -0
  96. comfygit_core-0.4.1/tests/unit/services/test_workflow_input.py +123 -0
  97. comfygit_core-0.4.1/tests/unit/services/test_workflow_resolution_service.py +92 -0
  98. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_dev_node_rename_detection.py +97 -0
  99. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_external_uv_cache.py +1 -2
  100. comfygit_core-0.4.1/tests/unit/test_github_auth_config.py +69 -0
  101. comfygit_core-0.4.1/tests/unit/test_headless_import.py +34 -0
  102. comfygit_core-0.4.1/tests/unit/test_materialization.py +141 -0
  103. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_model_config_dynamic_loading.py +48 -0
  104. comfygit_core-0.4.1/tests/unit/test_model_loader_extractor.py +80 -0
  105. comfygit_core-0.4.1/tests/unit/test_model_repository_cleanup.py +45 -0
  106. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_node_resolution_context.py +61 -0
  107. comfygit_core-0.4.1/tests/unit/utils/test_git.py +220 -0
  108. comfygit_core-0.4.1/tests/unit/utils/test_node_identity.py +48 -0
  109. comfygit_core-0.3.22/AGENTS.md +0 -61
  110. comfygit_core-0.3.22/CLAUDE.md +0 -86
  111. comfygit_core-0.3.22/src/comfygit_core/configs/model_config.py +0 -224
  112. comfygit_core-0.3.22/src/comfygit_core/models/manifest.py +0 -131
  113. comfygit_core-0.3.22/tests/unit/utils/test_git.py +0 -62
  114. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/.gitignore +0 -0
  115. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/.python-version +0 -0
  116. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/LICENSE.txt +0 -0
  117. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/README.md +0 -0
  118. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/architecture-deep-dive.md +0 -0
  119. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/architecture.md +0 -0
  120. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/knowledge/comfyui-node-loader-base-directories.md +0 -0
  121. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/knowledge/model-tracking-system.md +0 -0
  122. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/knowledge/node-resolution-behavior.md +0 -0
  123. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/layer-hierarchy.md +0 -0
  124. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/plans/uv-overlay-system.md +0 -0
  125. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/__init__.py +0 -0
  126. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/__init__.py +0 -0
  127. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/config_comparison.py +0 -0
  128. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/custom_node_scanner.py +0 -0
  129. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/git_change_parser.py +0 -0
  130. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/model_scanner.py +0 -0
  131. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/node_git_analyzer.py +0 -0
  132. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/ref_diff_analyzer.py +0 -0
  133. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/__init__.py +0 -0
  134. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/api_cache.py +0 -0
  135. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/base.py +0 -0
  136. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/comfyui_cache.py +0 -0
  137. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/custom_node_cache.py +0 -0
  138. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/clients/__init__.py +0 -0
  139. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/clients/registry_client.py +0 -0
  140. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/configs/comfyui_builtin_nodes.py +0 -0
  141. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/configs/package_config.py +0 -0
  142. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/core/__init__.py +0 -0
  143. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/data/overlays/stock/sageattention.toml +0 -0
  144. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/data/overlays/stock/triton.toml +0 -0
  145. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/data/overlays/stock/xformers.toml +0 -0
  146. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/factories/__init__.py +0 -0
  147. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/factories/workspace_factory.py +0 -0
  148. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/infrastructure/__init__.py +0 -0
  149. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/infrastructure/sqlite_manager.py +0 -0
  150. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/integrations/__init__.py +0 -0
  151. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/integrations/uv_command.py +0 -0
  152. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/logging/__init__.py +0 -0
  153. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/logging/logging_config.py +0 -0
  154. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/__init__.py +0 -0
  155. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/environment_git_orchestrator.py +0 -0
  156. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/model_download_manager.py +0 -0
  157. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/model_symlink_manager.py +0 -0
  158. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/overlay_manager.py +0 -0
  159. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/pytorch_backend_manager.py +0 -0
  160. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/system_node_symlink_manager.py +0 -0
  161. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/user_content_symlink_manager.py +0 -0
  162. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/merging/__init__.py +0 -0
  163. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/merging/atomic_executor.py +0 -0
  164. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/merging/merge_validator.py +0 -0
  165. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/merging/semantic_merger.py +0 -0
  166. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/comfyui_builtin_versions.py +0 -0
  167. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/commit.py +0 -0
  168. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/environment.py +0 -0
  169. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/merge_plan.py +0 -0
  170. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/node_mapping.py +0 -0
  171. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/overlay.py +0 -0
  172. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/protocols.py +0 -0
  173. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/ref_diff.py +0 -0
  174. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/registry.py +0 -0
  175. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/sync.py +0 -0
  176. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/system.py +0 -0
  177. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/py.typed +0 -0
  178. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/comfyui_builtin_versions_repository.py +0 -0
  179. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/migrate_paths.py +0 -0
  180. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/node_mappings_repository.py +0 -0
  181. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/workflow_repository.py +0 -0
  182. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/resolvers/__init__.py +0 -0
  183. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/resolvers/model_resolver.py +0 -0
  184. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/huggingface_url.py +0 -0
  185. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/registry_data_manager.py +0 -0
  186. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/strategies/__init__.py +0 -0
  187. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/strategies/auto.py +0 -0
  188. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/strategies/confirmation.py +0 -0
  189. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/__init__.py +0 -0
  190. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/builtin_extractor.py +0 -0
  191. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/common.py +0 -0
  192. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/conflict_analyzer.py +0 -0
  193. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/conflict_parser.py +0 -0
  194. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/dependency_parser.py +0 -0
  195. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/dependency_probe.py +0 -0
  196. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/download.py +0 -0
  197. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/environment_cleanup.py +0 -0
  198. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/environment_lock.py +0 -0
  199. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/filesystem.py +0 -0
  200. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/folder_paths_extractor.py +0 -0
  201. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/input_signature.py +0 -0
  202. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/pytorch.py +0 -0
  203. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/pytorch_prober.py +0 -0
  204. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/requirements.py +0 -0
  205. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/retry.py +0 -0
  206. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/symlink_utils.py +0 -0
  207. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/system_detector.py +0 -0
  208. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/uuid.py +0 -0
  209. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/uv_error_handler.py +0 -0
  210. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/version.py +0 -0
  211. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/workflow_hash.py +0 -0
  212. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/validation/__init__.py +0 -0
  213. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/validation/resolution_tester.py +0 -0
  214. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/README.md +0 -0
  215. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/caching/TEST_REDUCTION_SUMMARY.md +0 -0
  216. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/caching/__init__.py +0 -0
  217. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/caching/test_workflow_cache.py +0 -0
  218. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/conftest.py +0 -0
  219. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/models/test_models.json +0 -0
  220. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/checkpoint_loader_with_missing_model.json +0 -0
  221. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/kjnodes_workflow.json +0 -0
  222. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/simple_txt2img.json +0 -0
  223. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/with_custom_node.json +0 -0
  224. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/with_missing_model.json +0 -0
  225. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/workflow_with_duplicates.json +0 -0
  226. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/workflow_with_properties.json +0 -0
  227. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/workflow_without_properties.json +0 -0
  228. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/helpers/__init__.py +0 -0
  229. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/helpers/model_index_builder.py +0 -0
  230. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/helpers/pyproject_assertions.py +0 -0
  231. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/helpers/workflow_builder.py +0 -0
  232. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_atomic_semantic_merge.py +0 -0
  233. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_auto_model_index_sync.py +0 -0
  234. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_branch_workflow_preservation.py +0 -0
  235. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_cache_invalidation_on_model_deletion.py +0 -0
  236. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_cache_node_version_invalidation.py +0 -0
  237. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_checkout_b_with_modified_workflow.py +0 -0
  238. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_commit_git_changes.py +0 -0
  239. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_commit_git_changes_SUMMARY.md +0 -0
  240. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_commit_history.py +0 -0
  241. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_context_aware_node_resolution.py +0 -0
  242. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_create_with_version_spec.py +0 -0
  243. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_custom_node_path_preservation.py +0 -0
  244. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_deferred_model_downloads.py +0 -0
  245. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_deleted_model_download_intent.py +0 -0
  246. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_dependency_group_removal.py +0 -0
  247. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_dev_node_improvements.py +0 -0
  248. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_download_cleanup.py +0 -0
  249. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_download_intent_cache_invalidation.py +0 -0
  250. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_environment_basic.py +0 -0
  251. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_environment_branching.py +0 -0
  252. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_environment_create_progress.py +0 -0
  253. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_branching.py +0 -0
  254. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_import.py +0 -0
  255. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_pull_push.py +0 -0
  256. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_remote.py +0 -0
  257. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_subdirectory_import.py +0 -0
  258. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_import_auto_remote.py +0 -0
  259. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_import_comfyui_version_bug.py +0 -0
  260. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_import_preview.py +0 -0
  261. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_category_mismatch_detection.py +0 -0
  262. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_directory_switch.py +0 -0
  263. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_download_integration.py +0 -0
  264. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_index_mismatch_bug_SUMMARY.md +0 -0
  265. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_path_sync_detection.py +0 -0
  266. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_resolution_stale_directory.py +0 -0
  267. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_show_command.py +0 -0
  268. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_source_management.py +0 -0
  269. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_source_preservation.py +0 -0
  270. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_source_preservation_SUMMARY.md +0 -0
  271. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_source_removal.py +0 -0
  272. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_multiple_optional_group_failures.py +0 -0
  273. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_node_prune.py +0 -0
  274. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_node_version_replacement.py +0 -0
  275. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_opencv_conflict_resolution.py +0 -0
  276. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_overlay_e2e.py +0 -0
  277. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_overlay_git_integration.py +0 -0
  278. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_overlay_system_integration.py +0 -0
  279. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_package_config.py +0 -0
  280. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_per_environment_manager.py +0 -0
  281. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_pytorch_reconfiguration.py +0 -0
  282. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_registry_node_update_empty_download_url.py +0 -0
  283. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_repair_completion_marker.py +0 -0
  284. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_repair_model_download.py +0 -0
  285. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_repair_node_removal.py +0 -0
  286. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_repair_workflow.py +0 -0
  287. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_requirements_inline_comments_bug.py +0 -0
  288. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_runtime_restart_workflow_preservation.py +0 -0
  289. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_status_abstraction.py +0 -0
  290. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_status_uninstalled_nodes.py +0 -0
  291. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_caching_integration.py +0 -0
  292. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_commit_flow.py +0 -0
  293. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_model_criticality_update.py +0 -0
  294. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_path_update_after_interactive_resolution.py +0 -0
  295. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_resolution_cleanup.py +0 -0
  296. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_resolution_pipeline.py +0 -0
  297. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_resolve_install.py +0 -0
  298. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_subgraph_resolution.py +0 -0
  299. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/test_public_api.py +0 -0
  300. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_config_comparison.py +0 -0
  301. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_custom_node_scanner.py +0 -0
  302. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_ref_diff_analyzer.py +0 -0
  303. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_status_scanner_disabled_nodes.py +0 -0
  304. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/caching/test_cache_base.py +0 -0
  305. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/caching/test_comfyui_cache.py +0 -0
  306. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/caching/test_custom_node_cache_refactor.py +0 -0
  307. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/caching/test_workspace_relative_caching.py +0 -0
  308. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/configs/__init__.py +0 -0
  309. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/configs/test_package_config.py +0 -0
  310. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/core/test_environment_operation_locking.py +0 -0
  311. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/core/test_import_no_manager.py +0 -0
  312. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/core/test_reserved_environment_names.py +0 -0
  313. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_export_import_overlays.py +0 -0
  314. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_git_manager_log_refs.py +0 -0
  315. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_model_index_manager.py +0 -0
  316. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_node_conflict_detection.py +0 -0
  317. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_overlay_fuzz.py +0 -0
  318. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_overlay_injection.py +0 -0
  319. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_overlay_manager.py +0 -0
  320. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pyproject_schema_version.py +0 -0
  321. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pytorch_backend_manager.py +0 -0
  322. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pytorch_stripping.py +0 -0
  323. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_sqlite_manager.py +0 -0
  324. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_uv_no_build_isolation.py +0 -0
  325. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_workflow_node_cleanup.py +0 -0
  326. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_workflow_status.py +0 -0
  327. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/merging/__init__.py +0 -0
  328. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/merging/test_atomic_executor.py +0 -0
  329. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/merging/test_merge_validator.py +0 -0
  330. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/merging/test_semantic_merger.py +0 -0
  331. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_comfyui_builtin_versions.py +0 -0
  332. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_overlay.py +0 -0
  333. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_ref_diff.py +0 -0
  334. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_workflow_subgraph.py +0 -0
  335. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/resolvers/test_global_node_resolver_v2.py +0 -0
  336. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/resolvers/test_model_resolver.py +0 -0
  337. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_global_node_resolver.py +0 -0
  338. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_huggingface_url.py +0 -0
  339. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_registry_data_manager.py +0 -0
  340. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_scan_requirements_substitution.py +0 -0
  341. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_add_dependencies_substitution.py +0 -0
  342. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_auto_strategies.py +0 -0
  343. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_builtin_extractor.py +0 -0
  344. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_environment_py_dependencies.py +0 -0
  345. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_folder_paths_extractor.py +0 -0
  346. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_github_url_installation.py +0 -0
  347. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_minimal_schema_compatibility.py +0 -0
  348. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_model_downloader_errors.py +0 -0
  349. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_model_symlink_manager.py +0 -0
  350. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_node_callbacks.py +0 -0
  351. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_node_conflict_context.py +0 -0
  352. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_node_mappings_repository.py +0 -0
  353. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_unified_node_search.py +0 -0
  354. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_user_content_symlink_manager.py +0 -0
  355. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_uv_error_handling.py +0 -0
  356. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_uv_error_parser.py +0 -0
  357. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_workflow_manager_deduplication.py +0 -0
  358. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_workspace_config_resilience.py +0 -0
  359. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_conflict_analyzer.py +0 -0
  360. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_conflict_parser.py +0 -0
  361. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_dependency_parser.py +0 -0
  362. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_dependency_probe.py +0 -0
  363. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_environment_cleanup.py +0 -0
  364. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_input_signature.py +0 -0
  365. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_pytorch.py +0 -0
  366. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_pytorch_prober.py +0 -0
  367. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_requirements.py +0 -0
  368. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_symlink_utils.py +0 -0
  369. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_uuid.py +0 -0
  370. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_version.py +0 -0
  371. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/utils/__init__.py +0 -0
  372. {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/utils/test_workflow_hash.py +0 -0
@@ -0,0 +1,122 @@
1
+ <!-- NOTE: packages/core/AGENTS.md and packages/core/CLAUDE.md must stay in sync. -->
2
+
3
+ # ComfyGit Core Agent Guide
4
+
5
+ `packages/core` is the UI-agnostic library package. It owns workspace and
6
+ environment state, manifest semantics, sync/materialization behavior, model and
7
+ node metadata, git orchestration, and callback/protocol contracts used by CLI,
8
+ manager, deploy, and future runtime tooling.
9
+
10
+ ## Active Truth Layer
11
+
12
+ Read root truth-layer docs before changing core behavior:
13
+
14
+ - `../../docs/contracts/core/CONTRACT.md` - active core contract and invariants.
15
+ - `../../docs/specs/environment-manifest-model.md` - tracked manifest semantics.
16
+ - `../../docs/specs/environment-sync-lifecycle.md` - sync/run/git lifecycle.
17
+ - `../../docs/specs/dependency-criticality.md` - model/node required vs optional behavior.
18
+ - `../../docs/spec-driven-development.md` - clause syntax and validation rules.
19
+
20
+ Package docs are supporting reference:
21
+
22
+ - `docs/architecture.md` - core layer overview.
23
+ - `docs/layer-hierarchy.md` - package-local layering reference.
24
+ - `docs/knowledge/` - topic-specific behavior notes.
25
+ - `docs/plans/` - planning docs; verify against truth-layer clauses before treating as current.
26
+
27
+ ## Core Boundaries
28
+
29
+ - Keep core independent of CLI, manager UI, and ComfyUI panel rendering.
30
+ - Avoid normal-use `print()` and `input()` in core; expose callbacks,
31
+ strategies, protocols, return values, and exceptions so callers own UX.
32
+ - Prefer `Workspace` and `Environment` as public entry points. Keep direct manager
33
+ access for internal composition, tests, and package-local advanced behavior.
34
+ - Do not put service-specific deployment policy into core. Core should
35
+ write/read portable manifest semantics that runtime adapters can consume.
36
+
37
+ ## Source Map
38
+
39
+ | Path | Purpose |
40
+ | --- | --- |
41
+ | `src/comfygit_core/core/` | Public `Workspace` and `Environment` APIs. |
42
+ | `src/comfygit_core/managers/` | Stateful orchestration for pyproject, uv, git, nodes, workflows, models, overlays, and symlinks. |
43
+ | `src/comfygit_core/models/` | Dataclasses, protocols, exceptions, manifest/workflow/sync types. |
44
+ | `src/comfygit_core/resolvers/` | Node and model resolution logic. |
45
+ | `src/comfygit_core/services/` | Stateless business logic, registry/model lookup, downloads, workflow services. |
46
+ | `src/comfygit_core/repositories/` | SQLite-backed caches and persistent indexes. |
47
+ | `src/comfygit_core/analyzers/` | Workflow, git, config, model, and custom-node analysis. |
48
+ | `src/comfygit_core/integrations/` | External command integrations such as uv. |
49
+ | `src/comfygit_core/utils/` | Low-level filesystem, git, dependency, PyTorch, retry, and parsing helpers. |
50
+
51
+ Check existing managers/services before adding new abstractions.
52
+
53
+ ## Key Managers
54
+
55
+ | Manager | File | Main responsibility |
56
+ | --- | --- | --- |
57
+ | `PyprojectManager` | `managers/pyproject_manager.py` | Manifest CRUD and temporary uv/PyTorch injection. |
58
+ | `UVProjectManager` | `managers/uv_project_manager.py` | uv sync/add/remove operations. |
59
+ | `OverlayManager` | `managers/overlay_manager.py` | Overlay loading and legacy `.local-uv-config` migration. |
60
+ | `PyTorchBackendManager` | `managers/pytorch_backend_manager.py` | `.pytorch-backend`, GPU probing, torch source config. |
61
+ | `NodeManager` | `managers/node_manager.py` | Custom node install/remove/update. |
62
+ | `WorkflowManager` | `managers/workflow_manager.py` | Workflow tracking, node/model resolution, contract metadata. |
63
+ | `EnvironmentModelManager` | `managers/environment_model_manager.py` | Environment-level model status and metadata aggregation. |
64
+ | `GitManager` | `managers/git_manager.py` | Environment repo git operations. |
65
+ | `ExportImportManager` | `managers/export_import_manager.py` | Portable environment import/export. |
66
+
67
+ ## Manifest And Local State
68
+
69
+ Tracked portable truth lives in each environment repo's `pyproject.toml`.
70
+ Runtime/materialized state lives under environment runtime directories such as
71
+ `.cec/`, virtualenvs, ComfyUI checkouts, symlinks, caches, and local SQLite DBs.
72
+
73
+ Machine-local sync inputs are not portable manifest truth:
74
+
75
+ - `.pytorch-backend` stores local torch backend choice and generated source pins.
76
+ - Local uv overrides now flow through overlays, with legacy `.local-uv-config`
77
+ migrated by `OverlayManager`.
78
+
79
+ `PyprojectManager.uv_injection_context()` temporarily merges local overlays and
80
+ PyTorch backend config into `pyproject.toml` for uv operations, then restores the
81
+ tracked manifest in a `finally` path. Preserve that invariant.
82
+
83
+ ## Dependency Criticality
84
+
85
+ Current model criticality supports required, flexible, and optional. Required
86
+ unresolved models are reproducibility blockers; optional unresolved models are
87
+ warnings.
88
+
89
+ Custom node criticality is planned as explicit manifest metadata:
90
+
91
+ - Supported values should start as `required` and `optional`.
92
+ - Missing criticality reads as `required`.
93
+ - Optional unresolved nodes warn instead of blocking build readiness.
94
+ - Workflow graph usage can inform UI messaging, but must not silently downgrade
95
+ user-declared custom node criticality.
96
+
97
+ ## Testing
98
+
99
+ Run tests from the repo root with uv:
100
+
101
+ ```bash
102
+ uv run pytest packages/core/tests/ -v
103
+ uv run pytest packages/core/tests/unit/managers/test_pyproject_manager.py -v
104
+ uv run pytest packages/core/tests/ -k "injection" -v
105
+ ```
106
+
107
+ Core tests should usually exercise core APIs and fixtures rather than subprocess
108
+ CLI calls. See `tests/README.md` for fixture details:
109
+
110
+ - `test_workspace` creates an isolated workspace.
111
+ - `test_env` creates a minimal environment without cloning ComfyUI.
112
+ - `test_models` creates indexed model stubs.
113
+ - `tests/helpers/` has workflow builders and pyproject assertions.
114
+
115
+ ## Style
116
+
117
+ - Keep orchestration methods scannable; extract complex decision logic.
118
+ - Prefer guard clauses over nested branches.
119
+ - Avoid state-tracking boolean flags when the actual state can be checked.
120
+ - Keep compatibility/fallback code only when it protects real current behavior.
121
+ - Add focused tests for main paths and important edge cases; avoid large matrices
122
+ for low-risk changes.
@@ -0,0 +1,122 @@
1
+ <!-- NOTE: packages/core/AGENTS.md and packages/core/CLAUDE.md must stay in sync. -->
2
+
3
+ # ComfyGit Core Agent Guide
4
+
5
+ `packages/core` is the UI-agnostic library package. It owns workspace and
6
+ environment state, manifest semantics, sync/materialization behavior, model and
7
+ node metadata, git orchestration, and callback/protocol contracts used by CLI,
8
+ manager, deploy, and future runtime tooling.
9
+
10
+ ## Active Truth Layer
11
+
12
+ Read root truth-layer docs before changing core behavior:
13
+
14
+ - `../../docs/contracts/core/CONTRACT.md` - active core contract and invariants.
15
+ - `../../docs/specs/environment-manifest-model.md` - tracked manifest semantics.
16
+ - `../../docs/specs/environment-sync-lifecycle.md` - sync/run/git lifecycle.
17
+ - `../../docs/specs/dependency-criticality.md` - model/node required vs optional behavior.
18
+ - `../../docs/spec-driven-development.md` - clause syntax and validation rules.
19
+
20
+ Package docs are supporting reference:
21
+
22
+ - `docs/architecture.md` - core layer overview.
23
+ - `docs/layer-hierarchy.md` - package-local layering reference.
24
+ - `docs/knowledge/` - topic-specific behavior notes.
25
+ - `docs/plans/` - planning docs; verify against truth-layer clauses before treating as current.
26
+
27
+ ## Core Boundaries
28
+
29
+ - Keep core independent of CLI, manager UI, and ComfyUI panel rendering.
30
+ - Avoid normal-use `print()` and `input()` in core; expose callbacks,
31
+ strategies, protocols, return values, and exceptions so callers own UX.
32
+ - Prefer `Workspace` and `Environment` as public entry points. Keep direct manager
33
+ access for internal composition, tests, and package-local advanced behavior.
34
+ - Do not put service-specific deployment policy into core. Core should
35
+ write/read portable manifest semantics that runtime adapters can consume.
36
+
37
+ ## Source Map
38
+
39
+ | Path | Purpose |
40
+ | --- | --- |
41
+ | `src/comfygit_core/core/` | Public `Workspace` and `Environment` APIs. |
42
+ | `src/comfygit_core/managers/` | Stateful orchestration for pyproject, uv, git, nodes, workflows, models, overlays, and symlinks. |
43
+ | `src/comfygit_core/models/` | Dataclasses, protocols, exceptions, manifest/workflow/sync types. |
44
+ | `src/comfygit_core/resolvers/` | Node and model resolution logic. |
45
+ | `src/comfygit_core/services/` | Stateless business logic, registry/model lookup, downloads, workflow services. |
46
+ | `src/comfygit_core/repositories/` | SQLite-backed caches and persistent indexes. |
47
+ | `src/comfygit_core/analyzers/` | Workflow, git, config, model, and custom-node analysis. |
48
+ | `src/comfygit_core/integrations/` | External command integrations such as uv. |
49
+ | `src/comfygit_core/utils/` | Low-level filesystem, git, dependency, PyTorch, retry, and parsing helpers. |
50
+
51
+ Check existing managers/services before adding new abstractions.
52
+
53
+ ## Key Managers
54
+
55
+ | Manager | File | Main responsibility |
56
+ | --- | --- | --- |
57
+ | `PyprojectManager` | `managers/pyproject_manager.py` | Manifest CRUD and temporary uv/PyTorch injection. |
58
+ | `UVProjectManager` | `managers/uv_project_manager.py` | uv sync/add/remove operations. |
59
+ | `OverlayManager` | `managers/overlay_manager.py` | Overlay loading and legacy `.local-uv-config` migration. |
60
+ | `PyTorchBackendManager` | `managers/pytorch_backend_manager.py` | `.pytorch-backend`, GPU probing, torch source config. |
61
+ | `NodeManager` | `managers/node_manager.py` | Custom node install/remove/update. |
62
+ | `WorkflowManager` | `managers/workflow_manager.py` | Workflow tracking, node/model resolution, contract metadata. |
63
+ | `EnvironmentModelManager` | `managers/environment_model_manager.py` | Environment-level model status and metadata aggregation. |
64
+ | `GitManager` | `managers/git_manager.py` | Environment repo git operations. |
65
+ | `ExportImportManager` | `managers/export_import_manager.py` | Portable environment import/export. |
66
+
67
+ ## Manifest And Local State
68
+
69
+ Tracked portable truth lives in each environment repo's `pyproject.toml`.
70
+ Runtime/materialized state lives under environment runtime directories such as
71
+ `.cec/`, virtualenvs, ComfyUI checkouts, symlinks, caches, and local SQLite DBs.
72
+
73
+ Machine-local sync inputs are not portable manifest truth:
74
+
75
+ - `.pytorch-backend` stores local torch backend choice and generated source pins.
76
+ - Local uv overrides now flow through overlays, with legacy `.local-uv-config`
77
+ migrated by `OverlayManager`.
78
+
79
+ `PyprojectManager.uv_injection_context()` temporarily merges local overlays and
80
+ PyTorch backend config into `pyproject.toml` for uv operations, then restores the
81
+ tracked manifest in a `finally` path. Preserve that invariant.
82
+
83
+ ## Dependency Criticality
84
+
85
+ Current model criticality supports required, flexible, and optional. Required
86
+ unresolved models are reproducibility blockers; optional unresolved models are
87
+ warnings.
88
+
89
+ Custom node criticality is planned as explicit manifest metadata:
90
+
91
+ - Supported values should start as `required` and `optional`.
92
+ - Missing criticality reads as `required`.
93
+ - Optional unresolved nodes warn instead of blocking build readiness.
94
+ - Workflow graph usage can inform UI messaging, but must not silently downgrade
95
+ user-declared custom node criticality.
96
+
97
+ ## Testing
98
+
99
+ Run tests from the repo root with uv:
100
+
101
+ ```bash
102
+ uv run pytest packages/core/tests/ -v
103
+ uv run pytest packages/core/tests/unit/managers/test_pyproject_manager.py -v
104
+ uv run pytest packages/core/tests/ -k "injection" -v
105
+ ```
106
+
107
+ Core tests should usually exercise core APIs and fixtures rather than subprocess
108
+ CLI calls. See `tests/README.md` for fixture details:
109
+
110
+ - `test_workspace` creates an isolated workspace.
111
+ - `test_env` creates a minimal environment without cloning ComfyUI.
112
+ - `test_models` creates indexed model stubs.
113
+ - `tests/helpers/` has workflow builders and pyproject assertions.
114
+
115
+ ## Style
116
+
117
+ - Keep orchestration methods scannable; extract complex decision logic.
118
+ - Prefer guard clauses over nested branches.
119
+ - Avoid state-tracking boolean flags when the actual state can be checked.
120
+ - Keep compatibility/fallback code only when it protects real current behavior.
121
+ - Add focused tests for main paths and important edge cases; avoid large matrices
122
+ for low-risk changes.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comfygit-core
3
- Version: 0.3.22
3
+ Version: 0.4.1
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,10 +10,10 @@ 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.28.0
13
+ Requires-Dist: requests>=2.33.0
14
14
  Requires-Dist: requirements-parser>=0.11.0
15
15
  Requires-Dist: tomlkit>=0.11.0
16
- Requires-Dist: uv>=0.7
16
+ Requires-Dist: uv>=0.11.8
17
17
  Requires-Dist: xxhash>=2.0.0
18
18
  Description-Content-Type: text/markdown
19
19
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "comfygit-core"
3
- version = "0.3.22"
3
+ version = "0.4.1"
4
4
  description = "ComfyGit Core - Git-based ComfyUI environment manager"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -8,10 +8,10 @@ dependencies = [
8
8
  "blake3>=0.3.3",
9
9
  "huggingface_hub>=0.11.0",
10
10
  "packaging>=16.2",
11
- "requests>=2.28.0",
11
+ "requests>=2.33.0",
12
12
  "requirements-parser>=0.11.0",
13
13
  "tomlkit>=0.11.0",
14
- "uv>=0.7",
14
+ "uv>=0.11.8",
15
15
  "xxhash>=2.0.0",
16
16
  ]
17
17
 
@@ -30,5 +30,5 @@ packages = ["src/comfygit_core"]
30
30
 
31
31
  [dependency-groups]
32
32
  dev = [
33
- "pytest>=8.4.1",
33
+ "pytest>=9.0.3",
34
34
  ]
@@ -38,7 +38,8 @@ class NodeClassifier:
38
38
  def __init__(
39
39
  self,
40
40
  cec_path: Path | None = None,
41
- builtin_versions_repository: ComfyUIBuiltinVersionsRepository | None = None
41
+ builtin_versions_repository: ComfyUIBuiltinVersionsRepository | None = None,
42
+ version_agnostic: bool = False,
42
43
  ):
43
44
  """
44
45
  Initialize node classifier with environment-specific or global builtins.
@@ -48,11 +49,28 @@ class NodeClassifier:
48
49
  If provided, loads from .cec/comfyui_builtins.json.
49
50
  If None or file missing, falls back to global config.
50
51
  builtin_versions_repository: Optional repository for version-indexed builtins.
52
+ version_agnostic: If True, treat ALL known builtins as present regardless
53
+ of version. Used for standalone/web analysis where we're
54
+ not tied to a specific ComfyUI installation.
51
55
  """
52
56
  self.builtin_versions_repository = builtin_versions_repository
57
+ self.version_agnostic = version_agnostic
53
58
  self.builtin_nodes, detected_version = self._load_builtin_nodes(cec_path)
54
59
  self.comfyui_version = detected_version or self._load_comfyui_version_from_pyproject(cec_path)
55
60
 
61
+ # In version-agnostic mode, expand builtin_nodes to include ALL known builtins
62
+ # so they classify as "builtin" rather than "version_gated"
63
+ if self.version_agnostic and self.builtin_versions_repository:
64
+ db = self.builtin_versions_repository.database
65
+ if db:
66
+ extra = set(db.builtins.keys()) - self.builtin_nodes
67
+ if extra:
68
+ logger.debug(
69
+ "Version-agnostic mode: adding %d version-indexed builtins to known set",
70
+ len(extra),
71
+ )
72
+ self.builtin_nodes = self.builtin_nodes | extra
73
+
56
74
  def _load_builtin_nodes(self, cec_path: Path | None) -> tuple[set[str], str | None]:
57
75
  """Load builtin nodes from environment or global fallback."""
58
76
  if cec_path:
@@ -5,6 +5,8 @@ import subprocess
5
5
  from pathlib import Path
6
6
  from typing import TYPE_CHECKING
7
7
 
8
+ from packaging.version import InvalidVersion, Version
9
+
8
10
  from comfygit_core.constants import CUSTOM_NODES_BLACKLIST
9
11
 
10
12
  from ..logging.logging_config import get_logger
@@ -25,6 +27,20 @@ if TYPE_CHECKING:
25
27
  logger = get_logger(__name__)
26
28
 
27
29
 
30
+ def _versions_match(actual: str | None, expected: str | None) -> bool:
31
+ """Compare node versions using package-version semantics when possible."""
32
+ if actual == expected:
33
+ return True
34
+
35
+ if not actual or not expected:
36
+ return False
37
+
38
+ try:
39
+ return Version(actual) == Version(expected)
40
+ except InvalidVersion:
41
+ return False
42
+
43
+
28
44
  class StatusScanner:
29
45
  """Scans environment to get current state."""
30
46
 
@@ -359,12 +375,16 @@ class StatusScanner:
359
375
  if expected_node.source == 'development':
360
376
  continue
361
377
 
362
- if expected_node.version and current_node.version != expected_node.version:
378
+ actual_version = current_node.version
379
+ if expected_node.source == "git" and current_node.git_commit:
380
+ actual_version = current_node.git_commit
381
+
382
+ if expected_node.version and not _versions_match(actual_version, expected_node.version):
363
383
  comparison.version_mismatches.append(
364
384
  {
365
385
  "name": name,
366
386
  "expected": expected_node.version,
367
- "actual": current_node.version,
387
+ "actual": actual_version,
368
388
  }
369
389
  )
370
390
 
@@ -7,9 +7,10 @@ from typing import TYPE_CHECKING
7
7
  from comfygit_core.repositories.workflow_repository import WorkflowRepository
8
8
 
9
9
  from ..configs.comfyui_models import MULTI_MODEL_WIDGET_CONFIGS
10
- from ..configs.model_config import ModelConfig
10
+ from ..configs.model_config import ModelConfig, ModelLoaderWidgetMapping
11
11
  from ..logging.logging_config import get_logger
12
12
  from ..models.workflow import (
13
+ NodeInput,
13
14
  Workflow,
14
15
  WorkflowDependencies,
15
16
  WorkflowNode,
@@ -34,11 +35,13 @@ class WorkflowDependencyParser:
34
35
  workflow_name: str | None = None,
35
36
  model_config: ModelConfig | None = None,
36
37
  cec_path: Path | None = None,
37
- builtin_versions_repository: ComfyUIBuiltinVersionsRepository | None = None
38
+ builtin_versions_repository: ComfyUIBuiltinVersionsRepository | None = None,
39
+ version_agnostic: bool = False,
38
40
  ):
39
- self.model_config = model_config or ModelConfig.load()
41
+ self.model_config = model_config or ModelConfig.load(cec_path=cec_path)
40
42
  self.cec_path = cec_path
41
43
  self.builtin_versions_repository = builtin_versions_repository
44
+ self.version_agnostic = version_agnostic
42
45
 
43
46
  # Accept either Workflow object or Path
44
47
  if isinstance(workflow, Path):
@@ -67,7 +70,8 @@ class WorkflowDependencyParser:
67
70
  # Create classifier with environment-specific builtins
68
71
  classifier = NodeClassifier(
69
72
  self.cec_path,
70
- builtin_versions_repository=self.builtin_versions_repository
73
+ builtin_versions_repository=self.builtin_versions_repository,
74
+ version_agnostic=self.version_agnostic,
71
75
  )
72
76
 
73
77
  # Analyze and resolve models and nodes
@@ -112,8 +116,7 @@ class WorkflowDependencyParser:
112
116
 
113
117
  Uses explicit extraction strategies:
114
118
  1. Extract from properties.models (preferred - has URLs for auto-download)
115
- 2. Extract from known multi-model node widget configs
116
- 3. Extract from known single-model loader widget config
119
+ 2. Extract from configured/generated model-loader widget metadata
117
120
 
118
121
  Args:
119
122
  node_id: Scoped node ID from workflow.nodes dict key (e.g., "uuid:12" for subgraph nodes)
@@ -126,14 +129,11 @@ class WorkflowDependencyParser:
126
129
  if property_models:
127
130
  refs.extend(self._extract_from_properties_models(node_id, node_info, property_models))
128
131
 
129
- # Strategy 2: Multi-model nodes (explicit widget indices from config)
130
- if node_info.type in MULTI_MODEL_WIDGET_CONFIGS:
131
- widget_refs = self._extract_multi_model_widgets(node_id, node_info)
132
- refs = self._merge_model_refs(refs, widget_refs)
133
-
134
- # Strategy 3: Standard single-model loaders
135
- elif self.model_config.is_model_loader_node(node_info.type):
136
- widget_refs = self._extract_single_model_widget(node_id, node_info)
132
+ # Strategy 2: Generated/static model loader widget metadata
133
+ if self.model_config.is_model_loader_node(node_info.type):
134
+ widget_refs = self._extract_model_loader_widgets(node_id, node_info)
135
+ if not widget_refs:
136
+ widget_refs = self._extract_static_fallback_widgets(node_id, node_info)
137
137
  refs = self._merge_model_refs(refs, widget_refs)
138
138
 
139
139
  return refs
@@ -178,42 +178,117 @@ class WorkflowDependencyParser:
178
178
  return idx
179
179
  return None
180
180
 
181
- def _extract_multi_model_widgets(self, node_id: str, node_info: WorkflowNode) -> list[WorkflowNodeWidgetRef]:
182
- """Extract models from multi-model nodes using MULTI_MODEL_WIDGET_CONFIGS.
181
+ def _find_widget_index_for_input_name(
182
+ self,
183
+ inputs: list[NodeInput],
184
+ widget_name: str,
185
+ ) -> int | None:
186
+ """Find frontend widget index from ComfyUI input metadata."""
187
+ widget_idx = 0
188
+ for input_info in inputs:
189
+ if input_info.link is not None:
190
+ continue
191
+
192
+ widget_metadata = input_info.widget or {}
193
+ if widget_metadata:
194
+ candidate_names = {input_info.name}
195
+ metadata_name = widget_metadata.get("name")
196
+ if isinstance(metadata_name, str):
197
+ candidate_names.add(metadata_name)
198
+
199
+ if widget_name in candidate_names:
200
+ return widget_idx
201
+
202
+ widget_idx += 1
203
+
204
+ return None
205
+
206
+ def _resolve_model_widget_index(
207
+ self,
208
+ node_info: WorkflowNode,
209
+ mapping: ModelLoaderWidgetMapping,
210
+ mapping_count: int,
211
+ ) -> int | None:
212
+ if mapping.widget_name:
213
+ index = self._find_widget_index_for_input_name(
214
+ node_info.inputs,
215
+ mapping.widget_name,
216
+ )
217
+ if index is not None:
218
+ return index
219
+
220
+ if mapping.widget_index is not None:
221
+ return mapping.widget_index
183
222
 
184
- Note: Unlike pattern matching, multi-model configs explicitly define which
185
- widgets contain models, so we trust them without extension filtering.
186
- This allows CheckpointLoader to capture both .safetensors and .yaml configs.
187
- """
188
- refs = []
189
- widget_indices = MULTI_MODEL_WIDGET_CONFIGS.get(node_info.type, [])
190
223
  widgets = node_info.widgets_values or []
224
+ if mapping_count == 1 and len(widgets) == 1:
225
+ return 0
191
226
 
192
- for widget_idx in widget_indices:
193
- if widget_idx < len(widgets) and widgets[widget_idx]:
194
- value = widgets[widget_idx]
195
- if isinstance(value, str) and value.strip():
196
- refs.append(WorkflowNodeWidgetRef(
197
- node_id=node_id,
198
- node_type=node_info.type,
199
- widget_index=widget_idx,
200
- widget_value=value
201
- ))
202
- return refs
227
+ return None
203
228
 
204
- def _extract_single_model_widget(self, node_id: str, node_info: WorkflowNode) -> list[WorkflowNodeWidgetRef]:
205
- """Extract model from standard single-model loader nodes."""
206
- refs = []
207
- widget_idx = self.model_config.get_widget_index_for_node(node_info.type)
229
+ def _extract_model_loader_widgets(
230
+ self,
231
+ node_id: str,
232
+ node_info: WorkflowNode,
233
+ ) -> list[WorkflowNodeWidgetRef]:
234
+ """Extract model refs from configured/generated model loader widgets."""
235
+ refs: list[WorkflowNodeWidgetRef] = []
236
+ mappings = self.model_config.get_model_loader_widgets(node_info.type)
208
237
  widgets = node_info.widgets_values or []
209
238
 
210
- if widget_idx < len(widgets) and widgets[widget_idx]:
239
+ for mapping in mappings:
240
+ widget_idx = self._resolve_model_widget_index(
241
+ node_info,
242
+ mapping,
243
+ len(mappings),
244
+ )
245
+ if widget_idx is None or widget_idx >= len(widgets):
246
+ continue
247
+
248
+ value = widgets[widget_idx]
249
+ if not isinstance(value, str) or not value.strip():
250
+ continue
251
+
211
252
  refs.append(WorkflowNodeWidgetRef(
212
253
  node_id=node_id,
213
254
  node_type=node_info.type,
214
255
  widget_index=widget_idx,
215
- widget_value=widgets[widget_idx]
256
+ widget_value=value,
257
+ property_directory=mapping.directories[0] if mapping.directories else None,
216
258
  ))
259
+
260
+ return refs
261
+
262
+ def _extract_static_fallback_widgets(
263
+ self,
264
+ node_id: str,
265
+ node_info: WorkflowNode,
266
+ ) -> list[WorkflowNodeWidgetRef]:
267
+ """Fallback for workflows without frontend input widget metadata."""
268
+ refs: list[WorkflowNodeWidgetRef] = []
269
+ widgets = node_info.widgets_values or []
270
+ widget_indices = MULTI_MODEL_WIDGET_CONFIGS.get(
271
+ node_info.type,
272
+ [self.model_config.get_widget_index_for_node(node_info.type)],
273
+ )
274
+ directories = self.model_config.get_directories_for_node(node_info.type)
275
+
276
+ for widget_idx in widget_indices:
277
+ if widget_idx >= len(widgets):
278
+ continue
279
+ value = widgets[widget_idx]
280
+ if not isinstance(value, str) or not value.strip():
281
+ continue
282
+ refs.append(
283
+ WorkflowNodeWidgetRef(
284
+ node_id=node_id,
285
+ node_type=node_info.type,
286
+ widget_index=widget_idx,
287
+ widget_value=value,
288
+ property_directory=directories[0] if directories else None,
289
+ )
290
+ )
291
+
217
292
  return refs
218
293
 
219
294
  def _merge_model_refs(