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.
- comfygit_core-0.4.1/AGENTS.md +122 -0
- comfygit_core-0.4.1/CLAUDE.md +122 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/PKG-INFO +3 -3
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/pyproject.toml +4 -4
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/node_classifier.py +19 -1
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/status_scanner.py +22 -2
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/workflow_dependency_parser.py +114 -39
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/workflow_cache.py +78 -28
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/clients/civitai_client.py +182 -6
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/clients/github_client.py +35 -16
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/configs/__init__.py +2 -2
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/configs/comfyui_models.py +10 -0
- comfygit_core-0.4.1/src/comfygit_core/configs/model_config.py +416 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/constants.py +2 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/core/environment.py +362 -91
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/core/workspace.py +194 -3
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/factories/environment_factory.py +82 -6
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/factories/uv_factory.py +11 -3
- comfygit_core-0.4.1/src/comfygit_core/lifecycle/__init__.py +51 -0
- comfygit_core-0.4.1/src/comfygit_core/lifecycle/comfyui_readiness.py +163 -0
- comfygit_core-0.4.1/src/comfygit_core/lifecycle/switch_observer.py +249 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/environment_model_manager.py +31 -2
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/export_import_manager.py +11 -2
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/git_manager.py +8 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/node_manager.py +421 -15
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/pyproject_manager.py +259 -30
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/uv_project_manager.py +8 -5
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/workflow_manager.py +428 -202
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/__init__.py +27 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/civitai.py +18 -4
- comfygit_core-0.4.1/src/comfygit_core/models/dependency_resolution.py +73 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/exceptions.py +18 -3
- comfygit_core-0.4.1/src/comfygit_core/models/manifest.py +348 -0
- comfygit_core-0.4.1/src/comfygit_core/models/materialization.py +41 -0
- comfygit_core-0.4.1/src/comfygit_core/models/readiness.py +90 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/shared.py +50 -2
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/workflow.py +77 -10
- comfygit_core-0.4.1/src/comfygit_core/models/workflow_contract.py +448 -0
- comfygit_core-0.4.1/src/comfygit_core/models/workflow_execution.py +78 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/workspace_config.py +6 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/__init__.py +2 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/model_repository.py +88 -30
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/workspace_config_repository.py +32 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/resolvers/global_node_resolver.py +40 -12
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/__init__.py +18 -1
- comfygit_core-0.4.1/src/comfygit_core/services/dependency_resolution_preview.py +368 -0
- comfygit_core-0.4.1/src/comfygit_core/services/environment_readiness.py +361 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/import_analyzer.py +20 -2
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/model_downloader.py +70 -47
- comfygit_core-0.4.1/src/comfygit_core/services/model_source_lookup.py +158 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/node_lookup_service.py +43 -24
- comfygit_core-0.4.1/src/comfygit_core/services/workflow_analysis_service.py +611 -0
- comfygit_core-0.4.1/src/comfygit_core/services/workflow_execution.py +409 -0
- comfygit_core-0.4.1/src/comfygit_core/services/workflow_input.py +79 -0
- comfygit_core-0.4.1/src/comfygit_core/services/workflow_resolution_service.py +228 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/comfyui_ops.py +1 -1
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/git.py +131 -14
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/model_categories.py +12 -2
- comfygit_core-0.4.1/src/comfygit_core/utils/model_loader_extractor.py +349 -0
- comfygit_core-0.4.1/src/comfygit_core/utils/node_identity.py +60 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/caching/test_workflow_cache_context_hash.py +73 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_dev_node_git_references.py +31 -5
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_export_import.py +13 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_optional_dependency_groups.py +13 -4
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_pyproject_batch_writes.py +123 -2
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_registry_git_fallback.py +15 -28
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_deletion_cleanup.py +129 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_workflow_dependency_parser.py +110 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/clients/test_civitai_client.py +56 -1
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/clients/test_civitai_parsing.py +17 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/clients/test_github_releases.py +28 -1
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/core/test_environment_uninstalled_nodes.py +29 -0
- comfygit_core-0.4.1/tests/unit/core/test_import_download_failures.py +112 -0
- comfygit_core-0.4.1/tests/unit/core/test_sync_node_dependency_provisioning.py +121 -0
- comfygit_core-0.4.1/tests/unit/core/test_workspace_model_delete.py +89 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/factories/test_environment_factory_manager_install.py +2 -1
- comfygit_core-0.4.1/tests/unit/lifecycle/test_comfyui_readiness.py +41 -0
- comfygit_core-0.4.1/tests/unit/managers/test_environment_model_manager.py +92 -0
- comfygit_core-0.4.1/tests/unit/managers/test_git_manager_gitignore.py +61 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_model_short_hash.py +10 -1
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_node_manager.py +262 -13
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pyproject_manager.py +396 -4
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pytorch_injection.py +43 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_workflow_manager.py +179 -0
- comfygit_core-0.4.1/tests/unit/models/test_workflow_dependencies.py +30 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_workflow_roundtrip.py +48 -0
- comfygit_core-0.4.1/tests/unit/services/test_dependency_resolution_preview.py +336 -0
- comfygit_core-0.4.1/tests/unit/services/test_environment_readiness.py +322 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_import_analyzer.py +15 -2
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_model_downloader.py +141 -0
- comfygit_core-0.4.1/tests/unit/services/test_model_source_lookup.py +84 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_node_lookup_api_first.py +76 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_node_lookup_version_fallback.py +9 -16
- comfygit_core-0.4.1/tests/unit/services/test_workflow_analysis_service.py +135 -0
- comfygit_core-0.4.1/tests/unit/services/test_workflow_execution.py +362 -0
- comfygit_core-0.4.1/tests/unit/services/test_workflow_input.py +123 -0
- comfygit_core-0.4.1/tests/unit/services/test_workflow_resolution_service.py +92 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_dev_node_rename_detection.py +97 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_external_uv_cache.py +1 -2
- comfygit_core-0.4.1/tests/unit/test_github_auth_config.py +69 -0
- comfygit_core-0.4.1/tests/unit/test_headless_import.py +34 -0
- comfygit_core-0.4.1/tests/unit/test_materialization.py +141 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_model_config_dynamic_loading.py +48 -0
- comfygit_core-0.4.1/tests/unit/test_model_loader_extractor.py +80 -0
- comfygit_core-0.4.1/tests/unit/test_model_repository_cleanup.py +45 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_node_resolution_context.py +61 -0
- comfygit_core-0.4.1/tests/unit/utils/test_git.py +220 -0
- comfygit_core-0.4.1/tests/unit/utils/test_node_identity.py +48 -0
- comfygit_core-0.3.22/AGENTS.md +0 -61
- comfygit_core-0.3.22/CLAUDE.md +0 -86
- comfygit_core-0.3.22/src/comfygit_core/configs/model_config.py +0 -224
- comfygit_core-0.3.22/src/comfygit_core/models/manifest.py +0 -131
- comfygit_core-0.3.22/tests/unit/utils/test_git.py +0 -62
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/.gitignore +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/.python-version +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/LICENSE.txt +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/README.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/architecture-deep-dive.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/architecture.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/knowledge/comfyui-node-loader-base-directories.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/knowledge/model-tracking-system.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/knowledge/node-resolution-behavior.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/layer-hierarchy.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/docs/plans/uv-overlay-system.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/config_comparison.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/custom_node_scanner.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/git_change_parser.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/model_scanner.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/node_git_analyzer.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/analyzers/ref_diff_analyzer.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/api_cache.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/base.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/comfyui_cache.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/caching/custom_node_cache.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/clients/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/clients/registry_client.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/configs/comfyui_builtin_nodes.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/configs/package_config.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/core/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/data/overlays/stock/sageattention.toml +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/data/overlays/stock/triton.toml +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/data/overlays/stock/xformers.toml +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/factories/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/factories/workspace_factory.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/infrastructure/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/infrastructure/sqlite_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/integrations/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/integrations/uv_command.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/logging/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/logging/logging_config.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/environment_git_orchestrator.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/model_download_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/model_symlink_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/overlay_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/pytorch_backend_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/system_node_symlink_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/managers/user_content_symlink_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/merging/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/merging/atomic_executor.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/merging/merge_validator.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/merging/semantic_merger.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/comfyui_builtin_versions.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/commit.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/environment.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/merge_plan.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/node_mapping.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/overlay.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/protocols.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/ref_diff.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/registry.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/sync.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/models/system.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/py.typed +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/comfyui_builtin_versions_repository.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/migrate_paths.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/node_mappings_repository.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/repositories/workflow_repository.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/resolvers/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/resolvers/model_resolver.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/huggingface_url.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/services/registry_data_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/strategies/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/strategies/auto.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/strategies/confirmation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/builtin_extractor.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/common.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/conflict_analyzer.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/conflict_parser.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/dependency_parser.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/dependency_probe.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/download.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/environment_cleanup.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/environment_lock.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/filesystem.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/folder_paths_extractor.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/input_signature.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/pytorch.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/pytorch_prober.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/requirements.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/retry.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/symlink_utils.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/system_detector.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/uuid.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/uv_error_handler.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/version.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/utils/workflow_hash.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/validation/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/src/comfygit_core/validation/resolution_tester.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/README.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/caching/TEST_REDUCTION_SUMMARY.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/caching/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/caching/test_workflow_cache.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/conftest.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/models/test_models.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/checkpoint_loader_with_missing_model.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/kjnodes_workflow.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/simple_txt2img.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/with_custom_node.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/with_missing_model.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/workflow_with_duplicates.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/workflow_with_properties.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/fixtures/workflows/workflow_without_properties.json +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/helpers/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/helpers/model_index_builder.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/helpers/pyproject_assertions.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/helpers/workflow_builder.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_atomic_semantic_merge.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_auto_model_index_sync.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_branch_workflow_preservation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_cache_invalidation_on_model_deletion.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_cache_node_version_invalidation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_checkout_b_with_modified_workflow.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_commit_git_changes.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_commit_git_changes_SUMMARY.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_commit_history.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_context_aware_node_resolution.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_create_with_version_spec.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_custom_node_path_preservation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_deferred_model_downloads.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_deleted_model_download_intent.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_dependency_group_removal.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_dev_node_improvements.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_download_cleanup.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_download_intent_cache_invalidation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_environment_basic.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_environment_branching.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_environment_create_progress.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_branching.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_import.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_pull_push.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_remote.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_git_subdirectory_import.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_import_auto_remote.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_import_comfyui_version_bug.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_import_preview.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_category_mismatch_detection.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_directory_switch.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_download_integration.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_index_mismatch_bug_SUMMARY.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_path_sync_detection.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_resolution_stale_directory.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_show_command.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_source_management.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_source_preservation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_source_preservation_SUMMARY.md +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_model_source_removal.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_multiple_optional_group_failures.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_node_prune.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_node_version_replacement.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_opencv_conflict_resolution.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_overlay_e2e.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_overlay_git_integration.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_overlay_system_integration.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_package_config.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_per_environment_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_pytorch_reconfiguration.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_registry_node_update_empty_download_url.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_repair_completion_marker.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_repair_model_download.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_repair_node_removal.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_repair_workflow.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_requirements_inline_comments_bug.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_runtime_restart_workflow_preservation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_status_abstraction.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_status_uninstalled_nodes.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_caching_integration.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_commit_flow.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_model_criticality_update.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_path_update_after_interactive_resolution.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_resolution_cleanup.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_resolution_pipeline.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_resolve_install.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/integration/test_workflow_subgraph_resolution.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/test_public_api.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_config_comparison.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_custom_node_scanner.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_ref_diff_analyzer.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/analyzers/test_status_scanner_disabled_nodes.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/caching/test_cache_base.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/caching/test_comfyui_cache.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/caching/test_custom_node_cache_refactor.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/caching/test_workspace_relative_caching.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/configs/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/configs/test_package_config.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/core/test_environment_operation_locking.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/core/test_import_no_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/core/test_reserved_environment_names.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_export_import_overlays.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_git_manager_log_refs.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_model_index_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_node_conflict_detection.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_overlay_fuzz.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_overlay_injection.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_overlay_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pyproject_schema_version.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pytorch_backend_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_pytorch_stripping.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_sqlite_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_uv_no_build_isolation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_workflow_node_cleanup.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/managers/test_workflow_status.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/merging/__init__.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/merging/test_atomic_executor.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/merging/test_merge_validator.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/merging/test_semantic_merger.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_comfyui_builtin_versions.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_overlay.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_ref_diff.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/models/test_workflow_subgraph.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/resolvers/test_global_node_resolver_v2.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/resolvers/test_model_resolver.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_global_node_resolver.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_huggingface_url.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_registry_data_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/services/test_scan_requirements_substitution.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_add_dependencies_substitution.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_auto_strategies.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_builtin_extractor.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_environment_py_dependencies.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_folder_paths_extractor.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_github_url_installation.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_minimal_schema_compatibility.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_model_downloader_errors.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_model_symlink_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_node_callbacks.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_node_conflict_context.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_node_mappings_repository.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_unified_node_search.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_user_content_symlink_manager.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_uv_error_handling.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_uv_error_parser.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_workflow_manager_deduplication.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/test_workspace_config_resilience.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_conflict_analyzer.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_conflict_parser.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_dependency_parser.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_dependency_probe.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_environment_cleanup.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_input_signature.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_pytorch.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_pytorch_prober.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_requirements.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_symlink_utils.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_uuid.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/unit/utils/test_version.py +0 -0
- {comfygit_core-0.3.22 → comfygit_core-0.4.1}/tests/utils/__init__.py +0 -0
- {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
|
+
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.
|
|
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.
|
|
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
|
+
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.
|
|
11
|
+
"requests>=2.33.0",
|
|
12
12
|
"requirements-parser>=0.11.0",
|
|
13
13
|
"tomlkit>=0.11.0",
|
|
14
|
-
"uv>=0.
|
|
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>=
|
|
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
|
-
|
|
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":
|
|
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
|
|
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:
|
|
130
|
-
if node_info.type
|
|
131
|
-
widget_refs = self.
|
|
132
|
-
|
|
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
|
|
182
|
-
|
|
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
|
-
|
|
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
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
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=
|
|
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(
|