comfygit-core 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- comfygit_core/analyzers/custom_node_scanner.py +109 -0
- comfygit_core/analyzers/git_change_parser.py +156 -0
- comfygit_core/analyzers/model_scanner.py +318 -0
- comfygit_core/analyzers/node_classifier.py +58 -0
- comfygit_core/analyzers/node_git_analyzer.py +77 -0
- comfygit_core/analyzers/status_scanner.py +362 -0
- comfygit_core/analyzers/workflow_dependency_parser.py +143 -0
- comfygit_core/caching/__init__.py +16 -0
- comfygit_core/caching/api_cache.py +210 -0
- comfygit_core/caching/base.py +212 -0
- comfygit_core/caching/comfyui_cache.py +100 -0
- comfygit_core/caching/custom_node_cache.py +320 -0
- comfygit_core/caching/workflow_cache.py +797 -0
- comfygit_core/clients/__init__.py +4 -0
- comfygit_core/clients/civitai_client.py +412 -0
- comfygit_core/clients/github_client.py +349 -0
- comfygit_core/clients/registry_client.py +230 -0
- comfygit_core/configs/comfyui_builtin_nodes.py +1614 -0
- comfygit_core/configs/comfyui_models.py +62 -0
- comfygit_core/configs/model_config.py +151 -0
- comfygit_core/constants.py +82 -0
- comfygit_core/core/environment.py +1635 -0
- comfygit_core/core/workspace.py +898 -0
- comfygit_core/factories/environment_factory.py +419 -0
- comfygit_core/factories/uv_factory.py +61 -0
- comfygit_core/factories/workspace_factory.py +109 -0
- comfygit_core/infrastructure/sqlite_manager.py +156 -0
- comfygit_core/integrations/__init__.py +7 -0
- comfygit_core/integrations/uv_command.py +318 -0
- comfygit_core/logging/logging_config.py +15 -0
- comfygit_core/managers/environment_git_orchestrator.py +316 -0
- comfygit_core/managers/environment_model_manager.py +296 -0
- comfygit_core/managers/export_import_manager.py +116 -0
- comfygit_core/managers/git_manager.py +667 -0
- comfygit_core/managers/model_download_manager.py +252 -0
- comfygit_core/managers/model_symlink_manager.py +166 -0
- comfygit_core/managers/node_manager.py +1378 -0
- comfygit_core/managers/pyproject_manager.py +1321 -0
- comfygit_core/managers/user_content_symlink_manager.py +436 -0
- comfygit_core/managers/uv_project_manager.py +569 -0
- comfygit_core/managers/workflow_manager.py +1944 -0
- comfygit_core/models/civitai.py +432 -0
- comfygit_core/models/commit.py +18 -0
- comfygit_core/models/environment.py +293 -0
- comfygit_core/models/exceptions.py +378 -0
- comfygit_core/models/manifest.py +132 -0
- comfygit_core/models/node_mapping.py +201 -0
- comfygit_core/models/protocols.py +248 -0
- comfygit_core/models/registry.py +63 -0
- comfygit_core/models/shared.py +356 -0
- comfygit_core/models/sync.py +42 -0
- comfygit_core/models/system.py +204 -0
- comfygit_core/models/workflow.py +914 -0
- comfygit_core/models/workspace_config.py +71 -0
- comfygit_core/py.typed +0 -0
- comfygit_core/repositories/migrate_paths.py +49 -0
- comfygit_core/repositories/model_repository.py +958 -0
- comfygit_core/repositories/node_mappings_repository.py +246 -0
- comfygit_core/repositories/workflow_repository.py +57 -0
- comfygit_core/repositories/workspace_config_repository.py +121 -0
- comfygit_core/resolvers/global_node_resolver.py +459 -0
- comfygit_core/resolvers/model_resolver.py +250 -0
- comfygit_core/services/import_analyzer.py +218 -0
- comfygit_core/services/model_downloader.py +422 -0
- comfygit_core/services/node_lookup_service.py +251 -0
- comfygit_core/services/registry_data_manager.py +161 -0
- comfygit_core/strategies/__init__.py +4 -0
- comfygit_core/strategies/auto.py +72 -0
- comfygit_core/strategies/confirmation.py +69 -0
- comfygit_core/utils/comfyui_ops.py +125 -0
- comfygit_core/utils/common.py +164 -0
- comfygit_core/utils/conflict_parser.py +232 -0
- comfygit_core/utils/dependency_parser.py +231 -0
- comfygit_core/utils/download.py +216 -0
- comfygit_core/utils/environment_cleanup.py +111 -0
- comfygit_core/utils/filesystem.py +178 -0
- comfygit_core/utils/git.py +1184 -0
- comfygit_core/utils/input_signature.py +145 -0
- comfygit_core/utils/model_categories.py +52 -0
- comfygit_core/utils/pytorch.py +71 -0
- comfygit_core/utils/requirements.py +211 -0
- comfygit_core/utils/retry.py +242 -0
- comfygit_core/utils/symlink_utils.py +119 -0
- comfygit_core/utils/system_detector.py +258 -0
- comfygit_core/utils/uuid.py +28 -0
- comfygit_core/utils/uv_error_handler.py +158 -0
- comfygit_core/utils/version.py +73 -0
- comfygit_core/utils/workflow_hash.py +90 -0
- comfygit_core/validation/resolution_tester.py +297 -0
- comfygit_core-0.2.0.dist-info/METADATA +939 -0
- comfygit_core-0.2.0.dist-info/RECORD +93 -0
- comfygit_core-0.2.0.dist-info/WHEEL +4 -0
- comfygit_core-0.2.0.dist-info/licenses/LICENSE.txt +661 -0
|
@@ -0,0 +1,939 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: comfygit-core
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: ComfyGit Core - Git-based ComfyUI environment manager
|
|
5
|
+
License-File: LICENSE.txt
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
8
|
+
Requires-Dist: blake3>=1.0.5
|
|
9
|
+
Requires-Dist: packaging>=25.0
|
|
10
|
+
Requires-Dist: psutil>=7.0.0
|
|
11
|
+
Requires-Dist: pyyaml>=6.0
|
|
12
|
+
Requires-Dist: requests>=2.32.4
|
|
13
|
+
Requires-Dist: requirements-parser>=0.13.0
|
|
14
|
+
Requires-Dist: tomlkit>=0.13.3
|
|
15
|
+
Requires-Dist: uv>=0.9.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# ComfyDock Core
|
|
19
|
+
|
|
20
|
+
Core library for programmatic ComfyUI environment and package management. Build custom tools, GUIs, web interfaces, or CI/CD integrations on top of ComfyDock's architecture.
|
|
21
|
+
|
|
22
|
+
> **⚠️ MVP Status**: This library is under active development. APIs may change between versions. Pin your dependencies to specific versions in production.
|
|
23
|
+
|
|
24
|
+
## What is ComfyDock Core?
|
|
25
|
+
|
|
26
|
+
ComfyDock Core is the **reusable library** that powers the `cfd` CLI and can power your own tools. It provides:
|
|
27
|
+
|
|
28
|
+
- **Workspace & Environment Management** - Create and manage isolated ComfyUI installations
|
|
29
|
+
- **Custom Node Management** - Install, update, remove nodes with conflict detection
|
|
30
|
+
- **Workflow Tracking** - Track workflows and resolve missing dependencies
|
|
31
|
+
- **Model Management** - Content-addressable model index with automatic resolution
|
|
32
|
+
- **Version Control** - Git-based commit/rollback for environment snapshots
|
|
33
|
+
- **Export/Import** - Package and share complete working environments
|
|
34
|
+
- **Strategy Pattern** - Plug in your own UI logic via callbacks
|
|
35
|
+
|
|
36
|
+
This is a **library, not a CLI**. No `print()` or `input()` statements - all user interaction happens through callbacks you provide.
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
Published separately to PyPI as `comfydock-core`:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# With pip
|
|
44
|
+
pip install comfydock-core
|
|
45
|
+
|
|
46
|
+
# With uv
|
|
47
|
+
uv add comfydock-core
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
### Basic Workspace and Environment Operations
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from pathlib import Path
|
|
56
|
+
from comfydock_core.factories.workspace_factory import WorkspaceFactory
|
|
57
|
+
|
|
58
|
+
# Create a new workspace
|
|
59
|
+
workspace = WorkspaceFactory.create(Path.home() / "my-comfyui-workspace")
|
|
60
|
+
|
|
61
|
+
# Or find an existing workspace
|
|
62
|
+
workspace = WorkspaceFactory.find(Path.home() / "my-comfyui-workspace")
|
|
63
|
+
|
|
64
|
+
# Create an environment (downloads ComfyUI, sets up Python venv)
|
|
65
|
+
env = workspace.create_environment(
|
|
66
|
+
name="production",
|
|
67
|
+
python_version="3.11",
|
|
68
|
+
comfyui_version="master", # or specific commit hash
|
|
69
|
+
torch_backend="auto" # auto-detect GPU, or "cpu", "cu121", etc.
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# List all environments
|
|
73
|
+
environments = workspace.list_environments()
|
|
74
|
+
for env in environments:
|
|
75
|
+
print(f"Environment: {env.name} at {env.path}")
|
|
76
|
+
|
|
77
|
+
# Get a specific environment
|
|
78
|
+
env = workspace.get_environment("production")
|
|
79
|
+
|
|
80
|
+
# Set active environment (for CLI convenience, optional for library usage)
|
|
81
|
+
workspace.set_active_environment("production")
|
|
82
|
+
active = workspace.get_active_environment()
|
|
83
|
+
|
|
84
|
+
# Delete an environment
|
|
85
|
+
workspace.delete_environment("production")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**API Reference**: See `src/comfydock_core/core/workspace.py` for full `Workspace` API and `src/comfydock_core/factories/workspace_factory.py` for factory methods.
|
|
89
|
+
|
|
90
|
+
### Node Management
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
# Add a node from ComfyUI registry
|
|
94
|
+
result = env.add_node("comfyui-akatz-nodes")
|
|
95
|
+
|
|
96
|
+
# Add a node from GitHub URL
|
|
97
|
+
result = env.add_node(
|
|
98
|
+
"https://github.com/ltdrdata/ComfyUI-Impact-Pack",
|
|
99
|
+
version="v5.0" # optional: specify branch, tag, or commit
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Track a development node (your own node under development)
|
|
103
|
+
result = env.add_node(
|
|
104
|
+
"/path/to/my-custom-node",
|
|
105
|
+
dev=True # marks as development node, preserved on removal
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# List installed nodes
|
|
109
|
+
nodes = env.list_nodes()
|
|
110
|
+
for node in nodes:
|
|
111
|
+
print(f"{node.name}: {node.source} ({node.version})")
|
|
112
|
+
|
|
113
|
+
# Remove a node
|
|
114
|
+
result = env.remove_node("comfyui-manager")
|
|
115
|
+
|
|
116
|
+
# Update a node to latest version
|
|
117
|
+
update_result = env.update_node("comfyui-impact-pack")
|
|
118
|
+
if update_result.updated:
|
|
119
|
+
print(f"Updated from {update_result.old_version} to {update_result.new_version}")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Node Sources**: Nodes can come from:
|
|
123
|
+
- `registry` - ComfyUI official registry
|
|
124
|
+
- `git` - GitHub/GitLab repositories
|
|
125
|
+
- `development` - Local nodes under development
|
|
126
|
+
|
|
127
|
+
**API Reference**: See `src/comfydock_core/core/environment.py` for node methods and `src/comfydock_core/managers/node_manager.py` for implementation details.
|
|
128
|
+
|
|
129
|
+
### Workflow Tracking and Resolution
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from pathlib import Path
|
|
133
|
+
|
|
134
|
+
# Track a workflow (registers it for monitoring)
|
|
135
|
+
env.track_workflow(Path("my-workflow.json"))
|
|
136
|
+
|
|
137
|
+
# List tracked workflows
|
|
138
|
+
workflows = env.list_workflows()
|
|
139
|
+
|
|
140
|
+
# Resolve workflow dependencies (finds missing nodes and models)
|
|
141
|
+
result = env.resolve_workflow(
|
|
142
|
+
"my-workflow.json",
|
|
143
|
+
node_strategy=my_node_strategy, # custom strategy for ambiguous nodes
|
|
144
|
+
model_strategy=my_model_strategy, # custom strategy for missing models
|
|
145
|
+
install_nodes=True # automatically install missing nodes
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Check resolution results
|
|
149
|
+
if result.all_nodes_resolved:
|
|
150
|
+
print("All nodes available")
|
|
151
|
+
else:
|
|
152
|
+
print(f"Missing nodes: {result.unresolved_nodes}")
|
|
153
|
+
|
|
154
|
+
if result.all_models_found:
|
|
155
|
+
print("All models found")
|
|
156
|
+
else:
|
|
157
|
+
print(f"Missing models: {result.missing_models}")
|
|
158
|
+
|
|
159
|
+
# Untrack a workflow
|
|
160
|
+
env.untrack_workflow("my-workflow.json")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Workflow Resolution Process**:
|
|
164
|
+
1. Parse workflow JSON for node types and model references
|
|
165
|
+
2. Match node types to installed nodes or registry entries
|
|
166
|
+
3. Match model references to indexed models by hash
|
|
167
|
+
4. Return detailed status with resolution results
|
|
168
|
+
|
|
169
|
+
**API Reference**: See `src/comfydock_core/managers/workflow_manager.py` for workflow operations and `src/comfydock_core/models/workflow.py` for data structures.
|
|
170
|
+
|
|
171
|
+
### Model Management
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
# Set global models directory (workspace-wide)
|
|
175
|
+
workspace.set_models_directory(Path.home() / "my-models")
|
|
176
|
+
|
|
177
|
+
# Sync model index (scan directory and update database)
|
|
178
|
+
workspace.sync_model_index()
|
|
179
|
+
|
|
180
|
+
# Find models by hash, filename, or path
|
|
181
|
+
models = workspace.find_model("juggernaut")
|
|
182
|
+
for model in models:
|
|
183
|
+
print(f"{model.filename}: {model.hash_quick}")
|
|
184
|
+
|
|
185
|
+
# Download a model from URL
|
|
186
|
+
download_result = workspace.download_model(
|
|
187
|
+
url="https://civitai.com/api/download/models/12345",
|
|
188
|
+
category="checkpoints", # auto-path to checkpoints/
|
|
189
|
+
filename="my-model.safetensors" # optional override
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
# Add download source to existing model (for sharing)
|
|
193
|
+
workspace.add_model_source(
|
|
194
|
+
model_hash="abc123...",
|
|
195
|
+
url="https://civitai.com/models/..."
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# Models are symlinked into environments automatically
|
|
199
|
+
# No duplication - all environments share the workspace model index
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Model Index**: Uses Blake3 quick hash (first/middle/last 15MB) for fast identification and full SHA256 hash for verification during export/import.
|
|
203
|
+
|
|
204
|
+
**API Reference**: See `src/comfydock_core/core/workspace.py` for model methods and `src/comfydock_core/repositories/model_repository.py` for database operations.
|
|
205
|
+
|
|
206
|
+
### Version Control (Commit/Rollback)
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
# Commit current state (creates git snapshot in .cec/)
|
|
210
|
+
commit_result = env.commit(
|
|
211
|
+
message="Added Impact Pack and configured workflows"
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# View commit history
|
|
215
|
+
commits = env.get_commit_history()
|
|
216
|
+
for commit in commits:
|
|
217
|
+
print(f"v{commit.version}: {commit.message} ({commit.timestamp})")
|
|
218
|
+
|
|
219
|
+
# Rollback to previous version
|
|
220
|
+
env.rollback(
|
|
221
|
+
target="v2", # version identifier, or None to discard uncommitted changes
|
|
222
|
+
force=False # if True, discard uncommitted changes without error
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Check for uncommitted changes
|
|
226
|
+
status = env.get_status()
|
|
227
|
+
if status.has_uncommitted_changes:
|
|
228
|
+
print("Uncommitted changes detected")
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**What Gets Committed**:
|
|
232
|
+
- `pyproject.toml` - Node metadata, model references, Python dependencies
|
|
233
|
+
- `uv.lock` - Locked Python dependency versions
|
|
234
|
+
- `.cec/workflows/` - Tracked workflow files
|
|
235
|
+
|
|
236
|
+
**What Doesn't Get Committed**:
|
|
237
|
+
- Node source code (tracked in metadata, downloaded on demand)
|
|
238
|
+
- Model files (too large, referenced by hash)
|
|
239
|
+
- `.venv/` - Python virtual environment (recreated from lock)
|
|
240
|
+
|
|
241
|
+
**API Reference**: See `src/comfydock_core/core/environment.py` for version control methods and `src/comfydock_core/managers/git_manager.py` for git operations.
|
|
242
|
+
|
|
243
|
+
### Export and Import
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
from comfydock_core.models.protocols import ExportCallbacks, ImportCallbacks
|
|
247
|
+
|
|
248
|
+
# Export environment to tarball
|
|
249
|
+
class MyExportCallbacks(ExportCallbacks):
|
|
250
|
+
def on_progress(self, step: str, current: int, total: int):
|
|
251
|
+
print(f"{step}: {current}/{total}")
|
|
252
|
+
|
|
253
|
+
workspace.export_environment(
|
|
254
|
+
env_name="production",
|
|
255
|
+
output_path="production-env.tar.gz",
|
|
256
|
+
callbacks=MyExportCallbacks()
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# Import environment from tarball
|
|
260
|
+
class MyImportCallbacks(ImportCallbacks):
|
|
261
|
+
def on_node_download_start(self, node_name: str):
|
|
262
|
+
print(f"Downloading node: {node_name}")
|
|
263
|
+
|
|
264
|
+
def on_model_download_progress(self, filename: str, progress: float):
|
|
265
|
+
print(f"Model {filename}: {progress*100:.1f}%")
|
|
266
|
+
|
|
267
|
+
workspace.import_environment(
|
|
268
|
+
source="production-env.tar.gz",
|
|
269
|
+
name="imported-production",
|
|
270
|
+
callbacks=MyImportCallbacks(),
|
|
271
|
+
torch_backend="auto"
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
# Import from git repository
|
|
275
|
+
workspace.import_environment(
|
|
276
|
+
source="https://github.com/user/my-comfyui-env.git",
|
|
277
|
+
name="team-env",
|
|
278
|
+
branch="main", # optional: branch, tag, or commit
|
|
279
|
+
callbacks=MyImportCallbacks()
|
|
280
|
+
)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Export Contents**:
|
|
284
|
+
- Environment configuration (pyproject.toml, uv.lock)
|
|
285
|
+
- Tracked workflows
|
|
286
|
+
- Development node source code
|
|
287
|
+
- Node metadata (registry IDs, git URLs + commits)
|
|
288
|
+
- Model download sources (CivitAI/HuggingFace URLs)
|
|
289
|
+
|
|
290
|
+
**Import Process**:
|
|
291
|
+
1. Extract/clone environment configuration
|
|
292
|
+
2. Download missing custom nodes
|
|
293
|
+
3. Download missing models (if sources available)
|
|
294
|
+
4. Create Python virtual environment
|
|
295
|
+
5. Install dependencies from lock file
|
|
296
|
+
|
|
297
|
+
**API Reference**: See `src/comfydock_core/models/protocols.py` for callback protocols and `src/comfydock_core/managers/export_import_manager.py` for implementation.
|
|
298
|
+
|
|
299
|
+
### Git Remote Operations
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
# Add a git remote (for environment sharing via git)
|
|
303
|
+
env.add_remote(name="origin", url="https://github.com/user/my-env.git")
|
|
304
|
+
|
|
305
|
+
# List remotes
|
|
306
|
+
remotes = env.list_remotes()
|
|
307
|
+
|
|
308
|
+
# Push to remote
|
|
309
|
+
env.push_to_remote(remote="origin", force=False)
|
|
310
|
+
|
|
311
|
+
# Pull from remote
|
|
312
|
+
env.pull_from_remote(remote="origin", force=False)
|
|
313
|
+
|
|
314
|
+
# Remove a remote
|
|
315
|
+
env.remove_remote(name="origin")
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Remote Collaboration**: Each environment's `.cec/` directory is a git repository. You can push to GitHub/GitLab and others can import from the URL.
|
|
319
|
+
|
|
320
|
+
**API Reference**: See `src/comfydock_core/core/environment.py` for remote methods.
|
|
321
|
+
|
|
322
|
+
### Python Dependency Management
|
|
323
|
+
|
|
324
|
+
```python
|
|
325
|
+
# Add Python packages to environment
|
|
326
|
+
env.add_python_dependencies(["opencv-python>=4.5.0", "pillow"])
|
|
327
|
+
|
|
328
|
+
# Add from requirements.txt
|
|
329
|
+
env.add_python_dependencies_from_file(Path("requirements.txt"))
|
|
330
|
+
|
|
331
|
+
# Remove Python packages
|
|
332
|
+
env.remove_python_dependencies(["opencv-python"])
|
|
333
|
+
|
|
334
|
+
# List dependencies
|
|
335
|
+
deps = env.list_python_dependencies()
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Dependency Isolation**: Each custom node gets its own dependency group in `pyproject.toml` to isolate conflicts.
|
|
339
|
+
|
|
340
|
+
**API Reference**: See `src/comfydock_core/core/environment.py` for Python dependency methods.
|
|
341
|
+
|
|
342
|
+
## Strategy Pattern (Custom UI Integration)
|
|
343
|
+
|
|
344
|
+
ComfyDock Core uses the **strategy pattern** to allow custom frontends to provide their own UI logic. No hardcoded prompts or dialogs.
|
|
345
|
+
|
|
346
|
+
### Node Resolution Strategy
|
|
347
|
+
|
|
348
|
+
When adding nodes with ambiguous names, provide a strategy to resolve:
|
|
349
|
+
|
|
350
|
+
```python
|
|
351
|
+
from comfydock_core.models.protocols import NodeResolutionStrategy
|
|
352
|
+
from comfydock_core.models.shared import NodeInfo
|
|
353
|
+
|
|
354
|
+
class CLINodeStrategy(NodeResolutionStrategy):
|
|
355
|
+
"""Interactive CLI node resolution."""
|
|
356
|
+
|
|
357
|
+
def resolve_ambiguous(
|
|
358
|
+
self,
|
|
359
|
+
node_identifier: str,
|
|
360
|
+
candidates: list[NodeInfo]
|
|
361
|
+
) -> NodeInfo:
|
|
362
|
+
"""User picks from multiple matches."""
|
|
363
|
+
print(f"Multiple nodes match '{node_identifier}':")
|
|
364
|
+
for i, node in enumerate(candidates, 1):
|
|
365
|
+
print(f" {i}. {node.name} ({node.source})")
|
|
366
|
+
|
|
367
|
+
choice = int(input("Select: ")) - 1
|
|
368
|
+
return candidates[choice]
|
|
369
|
+
|
|
370
|
+
def resolve_optional(
|
|
371
|
+
self,
|
|
372
|
+
node_identifier: str,
|
|
373
|
+
is_required: bool
|
|
374
|
+
) -> bool:
|
|
375
|
+
"""User decides whether to install optional node."""
|
|
376
|
+
if is_required:
|
|
377
|
+
return True
|
|
378
|
+
|
|
379
|
+
response = input(f"Install optional node '{node_identifier}'? (y/N): ")
|
|
380
|
+
return response.lower() == 'y'
|
|
381
|
+
|
|
382
|
+
# Use your strategy
|
|
383
|
+
env.add_node("comfyui", strategy=CLINodeStrategy())
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Model Resolution Strategy
|
|
387
|
+
|
|
388
|
+
When workflows reference missing models:
|
|
389
|
+
|
|
390
|
+
```python
|
|
391
|
+
from comfydock_core.models.protocols import ModelResolutionStrategy
|
|
392
|
+
from comfydock_core.models.shared import ModelDetails
|
|
393
|
+
|
|
394
|
+
class CLIModelStrategy(ModelResolutionStrategy):
|
|
395
|
+
"""Interactive CLI model resolution."""
|
|
396
|
+
|
|
397
|
+
def resolve_missing_model(
|
|
398
|
+
self,
|
|
399
|
+
model_reference: str,
|
|
400
|
+
candidates: list[ModelDetails]
|
|
401
|
+
) -> ModelDetails | None:
|
|
402
|
+
"""User picks from search results or skips."""
|
|
403
|
+
if not candidates:
|
|
404
|
+
print(f"No models found for '{model_reference}'")
|
|
405
|
+
return None
|
|
406
|
+
|
|
407
|
+
print(f"Found models for '{model_reference}':")
|
|
408
|
+
for i, model in enumerate(candidates, 1):
|
|
409
|
+
print(f" {i}. {model.filename} ({model.size_mb:.1f} MB)")
|
|
410
|
+
print(f" {len(candidates)+1}. Skip")
|
|
411
|
+
|
|
412
|
+
choice = int(input("Select: "))
|
|
413
|
+
if choice == len(candidates) + 1:
|
|
414
|
+
return None
|
|
415
|
+
|
|
416
|
+
return candidates[choice - 1]
|
|
417
|
+
|
|
418
|
+
# Use your strategy
|
|
419
|
+
env.resolve_workflow(
|
|
420
|
+
"my-workflow.json",
|
|
421
|
+
model_strategy=CLIModelStrategy()
|
|
422
|
+
)
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Confirmation Strategy
|
|
426
|
+
|
|
427
|
+
For destructive operations (node removal, rollback):
|
|
428
|
+
|
|
429
|
+
```python
|
|
430
|
+
from comfydock_core.strategies.confirmation import ConfirmationStrategy
|
|
431
|
+
|
|
432
|
+
class CLIConfirmationStrategy(ConfirmationStrategy):
|
|
433
|
+
"""Interactive CLI confirmations."""
|
|
434
|
+
|
|
435
|
+
def confirm_node_removal(self, node_name: str, is_dev: bool) -> bool:
|
|
436
|
+
"""User confirms node removal."""
|
|
437
|
+
msg = f"Remove node '{node_name}'"
|
|
438
|
+
if is_dev:
|
|
439
|
+
msg += " (development node will be disabled, not deleted)"
|
|
440
|
+
response = input(f"{msg}? (y/N): ")
|
|
441
|
+
return response.lower() == 'y'
|
|
442
|
+
|
|
443
|
+
def confirm_rollback(self, target_version: str, has_uncommitted: bool) -> bool:
|
|
444
|
+
"""User confirms rollback."""
|
|
445
|
+
msg = f"Rollback to {target_version}"
|
|
446
|
+
if has_uncommitted:
|
|
447
|
+
msg += " (uncommitted changes will be lost)"
|
|
448
|
+
response = input(f"{msg}? (y/N): ")
|
|
449
|
+
return response.lower() == 'y'
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Auto Strategies (Non-Interactive)
|
|
453
|
+
|
|
454
|
+
For automated/CI environments, use auto-confirm strategies:
|
|
455
|
+
|
|
456
|
+
```python
|
|
457
|
+
from comfydock_core.strategies.auto import (
|
|
458
|
+
AutoConfirmStrategy,
|
|
459
|
+
AutoNodeStrategy,
|
|
460
|
+
AutoModelStrategy
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
# Auto-confirm all operations
|
|
464
|
+
env.remove_node("some-node", strategy=AutoConfirmStrategy())
|
|
465
|
+
|
|
466
|
+
# Auto-select first match
|
|
467
|
+
env.add_node("ambiguous", strategy=AutoNodeStrategy())
|
|
468
|
+
|
|
469
|
+
# Auto-skip missing models
|
|
470
|
+
result = env.resolve_workflow(
|
|
471
|
+
"workflow.json",
|
|
472
|
+
model_strategy=AutoModelStrategy()
|
|
473
|
+
)
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**Available Strategies**:
|
|
477
|
+
- `NodeResolutionStrategy` - Handle ambiguous node names
|
|
478
|
+
- `ModelResolutionStrategy` - Handle missing model resolution
|
|
479
|
+
- `ConfirmationStrategy` - Handle destructive operations
|
|
480
|
+
- `RollbackStrategy` - Handle rollback confirmations
|
|
481
|
+
- `ExportCallbacks` - Progress updates during export
|
|
482
|
+
- `ImportCallbacks` - Progress updates during import
|
|
483
|
+
|
|
484
|
+
**API Reference**: See `src/comfydock_core/models/protocols.py` for all strategy protocols and `src/comfydock_core/strategies/` for built-in implementations.
|
|
485
|
+
|
|
486
|
+
## Architecture Overview
|
|
487
|
+
|
|
488
|
+
ComfyDock Core uses a **layered architecture** separating concerns:
|
|
489
|
+
|
|
490
|
+
```
|
|
491
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
492
|
+
│ API Layer (Workspace, Environment) │
|
|
493
|
+
│ - High-level operations │
|
|
494
|
+
│ - Public API surface │
|
|
495
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
496
|
+
│
|
|
497
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
498
|
+
│ Management Layer (Managers) │
|
|
499
|
+
│ - NodeManager: Node installation/removal │
|
|
500
|
+
│ - WorkflowManager: Workflow tracking/resolution │
|
|
501
|
+
│ - ModelSymlinkManager: Model symlinking │
|
|
502
|
+
│ - GitManager: Git operations │
|
|
503
|
+
│ - PyprojectManager: pyproject.toml manipulation │
|
|
504
|
+
│ - UVProjectManager: UV command execution │
|
|
505
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
506
|
+
│
|
|
507
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
508
|
+
│ Service Layer (Services) │
|
|
509
|
+
│ - NodeLookupService: Find nodes across sources │
|
|
510
|
+
│ - ModelDownloader: Download models from URLs │
|
|
511
|
+
│ - RegistryDataManager: ComfyUI registry cache │
|
|
512
|
+
│ - ImportAnalyzer: Preview imports │
|
|
513
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
514
|
+
│
|
|
515
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
516
|
+
│ Repository Layer (Data Access) │
|
|
517
|
+
│ - ModelRepository: SQLite model index │
|
|
518
|
+
│ - WorkflowRepository: Workflow caching │
|
|
519
|
+
│ - NodeMappingsRepository: Node-to-package mappings │
|
|
520
|
+
│ - WorkspaceConfigRepository: Workspace configuration │
|
|
521
|
+
└─────────────────────────────────────────────────────────────┘
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Component Organization
|
|
525
|
+
|
|
526
|
+
**Core (`core/`)**
|
|
527
|
+
- `workspace.py` - Multi-environment coordinator
|
|
528
|
+
- `environment.py` - Single environment abstraction
|
|
529
|
+
|
|
530
|
+
**Managers (`managers/`)** - Orchestrate operations, maintain state
|
|
531
|
+
- Depend on services and repositories
|
|
532
|
+
- Handle complex workflows (install node → update pyproject → sync venv)
|
|
533
|
+
|
|
534
|
+
**Services (`services/`)** - Stateless business logic
|
|
535
|
+
- Pure functions or stateless classes
|
|
536
|
+
- Reusable across different managers
|
|
537
|
+
|
|
538
|
+
**Repositories (`repositories/`)** - Data persistence
|
|
539
|
+
- Database access (SQLite)
|
|
540
|
+
- File I/O (JSON, TOML)
|
|
541
|
+
- Caching
|
|
542
|
+
|
|
543
|
+
**Analyzers (`analyzers/`)** - Parse and extract information
|
|
544
|
+
- Workflow dependency parsing
|
|
545
|
+
- Custom node scanning
|
|
546
|
+
- Status analysis
|
|
547
|
+
|
|
548
|
+
**Resolvers (`resolvers/`)** - Determine actions
|
|
549
|
+
- Map workflow nodes to packages
|
|
550
|
+
- Find model download sources
|
|
551
|
+
|
|
552
|
+
**Models (`models/`)** - Data structures
|
|
553
|
+
- Type definitions
|
|
554
|
+
- Dataclasses
|
|
555
|
+
- Protocols (strategy interfaces)
|
|
556
|
+
|
|
557
|
+
**Factories (`factories/`)** - Object construction
|
|
558
|
+
- Handle complex initialization
|
|
559
|
+
- Dependency injection
|
|
560
|
+
|
|
561
|
+
**Strategies (`strategies/`)** - Pluggable behavior
|
|
562
|
+
- Auto-confirm strategies
|
|
563
|
+
- Interactive strategies (in frontend)
|
|
564
|
+
|
|
565
|
+
## Use Cases
|
|
566
|
+
|
|
567
|
+
### Use Case 1: Building a GUI
|
|
568
|
+
|
|
569
|
+
```python
|
|
570
|
+
from PyQt6.QtWidgets import QProgressDialog
|
|
571
|
+
from comfydock_core.models.protocols import ImportCallbacks
|
|
572
|
+
|
|
573
|
+
class QtImportCallbacks(ImportCallbacks):
|
|
574
|
+
"""Qt-based progress UI for imports."""
|
|
575
|
+
|
|
576
|
+
def __init__(self, parent):
|
|
577
|
+
self.dialog = QProgressDialog(
|
|
578
|
+
"Importing environment...",
|
|
579
|
+
"Cancel",
|
|
580
|
+
0, 100,
|
|
581
|
+
parent
|
|
582
|
+
)
|
|
583
|
+
self.dialog.setWindowModality(Qt.WindowModal)
|
|
584
|
+
|
|
585
|
+
def on_node_download_start(self, node_name: str):
|
|
586
|
+
self.dialog.setLabelText(f"Downloading node: {node_name}")
|
|
587
|
+
|
|
588
|
+
def on_model_download_progress(self, filename: str, progress: float):
|
|
589
|
+
self.dialog.setValue(int(progress * 100))
|
|
590
|
+
self.dialog.setLabelText(f"Downloading model: {filename}")
|
|
591
|
+
|
|
592
|
+
def on_python_sync_start(self):
|
|
593
|
+
self.dialog.setLabelText("Installing Python dependencies...")
|
|
594
|
+
|
|
595
|
+
# Use in your Qt application
|
|
596
|
+
workspace.import_environment(
|
|
597
|
+
"shared-env.tar.gz",
|
|
598
|
+
callbacks=QtImportCallbacks(self.mainwindow)
|
|
599
|
+
)
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### Use Case 2: CI/CD Pipeline
|
|
603
|
+
|
|
604
|
+
```python
|
|
605
|
+
"""Validate workflow compatibility in CI pipeline."""
|
|
606
|
+
import sys
|
|
607
|
+
from comfydock_core.factories.workspace_factory import WorkspaceFactory
|
|
608
|
+
from comfydock_core.strategies.auto import AutoModelStrategy, AutoNodeStrategy
|
|
609
|
+
|
|
610
|
+
# Create test workspace
|
|
611
|
+
workspace = WorkspaceFactory.create("/tmp/ci-test-workspace")
|
|
612
|
+
env = workspace.create_environment("ci-test")
|
|
613
|
+
|
|
614
|
+
# Import workflow to test
|
|
615
|
+
env.track_workflow("workflow-to-test.json")
|
|
616
|
+
|
|
617
|
+
# Resolve with auto strategies (non-interactive)
|
|
618
|
+
result = env.resolve_workflow(
|
|
619
|
+
"workflow-to-test.json",
|
|
620
|
+
node_strategy=AutoNodeStrategy(),
|
|
621
|
+
model_strategy=AutoModelStrategy(),
|
|
622
|
+
install_nodes=True
|
|
623
|
+
)
|
|
624
|
+
|
|
625
|
+
# Check results
|
|
626
|
+
if not result.all_nodes_resolved:
|
|
627
|
+
print(f"ERROR: Missing nodes: {result.unresolved_nodes}")
|
|
628
|
+
sys.exit(1)
|
|
629
|
+
|
|
630
|
+
if not result.all_models_found:
|
|
631
|
+
print(f"WARNING: Missing models: {result.missing_models}")
|
|
632
|
+
# Could fail here or continue depending on requirements
|
|
633
|
+
|
|
634
|
+
print("✓ Workflow validation passed")
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### Use Case 3: Batch Environment Creation
|
|
638
|
+
|
|
639
|
+
```python
|
|
640
|
+
"""Create multiple environments from templates."""
|
|
641
|
+
from pathlib import Path
|
|
642
|
+
|
|
643
|
+
workspace = WorkspaceFactory.find()
|
|
644
|
+
|
|
645
|
+
# Define environment templates
|
|
646
|
+
templates = [
|
|
647
|
+
{"name": "video", "nodes": ["comfyui-animatediff", "comfyui-video-helper"]},
|
|
648
|
+
{"name": "upscale", "nodes": ["comfyui-ultimate-upscale"]},
|
|
649
|
+
{"name": "inpaint", "nodes": ["comfyui-inpaint-nodes"]},
|
|
650
|
+
]
|
|
651
|
+
|
|
652
|
+
for template in templates:
|
|
653
|
+
print(f"Creating {template['name']} environment...")
|
|
654
|
+
|
|
655
|
+
env = workspace.create_environment(
|
|
656
|
+
name=template['name'],
|
|
657
|
+
python_version="3.11"
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
# Add nodes
|
|
661
|
+
for node_id in template['nodes']:
|
|
662
|
+
env.add_node(node_id)
|
|
663
|
+
|
|
664
|
+
# Commit initial setup
|
|
665
|
+
env.commit(f"Initial {template['name']} environment setup")
|
|
666
|
+
|
|
667
|
+
print(f"✓ {template['name']} environment ready")
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### Use Case 4: Environment Replication Tool
|
|
671
|
+
|
|
672
|
+
```python
|
|
673
|
+
"""Clone production environment to staging."""
|
|
674
|
+
from pathlib import Path
|
|
675
|
+
import tempfile
|
|
676
|
+
|
|
677
|
+
workspace = WorkspaceFactory.find()
|
|
678
|
+
|
|
679
|
+
# Export production
|
|
680
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
681
|
+
export_path = Path(tmpdir) / "production-snapshot.tar.gz"
|
|
682
|
+
workspace.export_environment("production", export_path)
|
|
683
|
+
|
|
684
|
+
# Import as staging
|
|
685
|
+
workspace.import_environment(
|
|
686
|
+
export_path,
|
|
687
|
+
name="staging",
|
|
688
|
+
torch_backend="auto"
|
|
689
|
+
)
|
|
690
|
+
|
|
691
|
+
print("✓ Production cloned to staging")
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
## Error Handling
|
|
695
|
+
|
|
696
|
+
ComfyDock Core uses a custom exception hierarchy for precise error handling:
|
|
697
|
+
|
|
698
|
+
```python
|
|
699
|
+
from comfydock_core.models.exceptions import (
|
|
700
|
+
ComfyDockError, # Base exception
|
|
701
|
+
CDWorkspaceError, # Workspace-related errors
|
|
702
|
+
CDEnvironmentError, # Environment-related errors
|
|
703
|
+
CDNodeConflictError, # Node installation conflicts
|
|
704
|
+
CDNodeNotFoundError, # Node not found
|
|
705
|
+
UVCommandError, # UV command failures
|
|
706
|
+
)
|
|
707
|
+
|
|
708
|
+
try:
|
|
709
|
+
env = workspace.create_environment("test")
|
|
710
|
+
except CDEnvironmentError as e:
|
|
711
|
+
print(f"Environment error: {e}")
|
|
712
|
+
# Handle environment-specific error
|
|
713
|
+
except CDWorkspaceError as e:
|
|
714
|
+
print(f"Workspace error: {e}")
|
|
715
|
+
# Handle workspace-specific error
|
|
716
|
+
except ComfyDockError as e:
|
|
717
|
+
print(f"ComfyDock error: {e}")
|
|
718
|
+
# Handle any ComfyDock error
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
**Exception Hierarchy**:
|
|
722
|
+
```
|
|
723
|
+
ComfyDockError
|
|
724
|
+
├── CDWorkspaceError
|
|
725
|
+
│ ├── CDWorkspaceNotFoundError
|
|
726
|
+
│ └── CDWorkspaceExistsError
|
|
727
|
+
├── CDEnvironmentError
|
|
728
|
+
│ ├── CDEnvironmentNotFoundError
|
|
729
|
+
│ ├── CDEnvironmentExistsError
|
|
730
|
+
│ └── CDNodeConflictError
|
|
731
|
+
├── CDNodeError
|
|
732
|
+
│ ├── CDNodeNotFoundError
|
|
733
|
+
│ └── CDNodeInstallError
|
|
734
|
+
└── UVCommandError
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
**API Reference**: See `src/comfydock_core/models/exceptions.py` for all exception types.
|
|
738
|
+
|
|
739
|
+
## Data Structures
|
|
740
|
+
|
|
741
|
+
Key data structures used throughout the API:
|
|
742
|
+
|
|
743
|
+
### NodeInfo
|
|
744
|
+
```python
|
|
745
|
+
from comfydock_core.models.shared import NodeInfo
|
|
746
|
+
|
|
747
|
+
# Returned by list_nodes(), node lookup, etc.
|
|
748
|
+
node = NodeInfo(
|
|
749
|
+
name="comfyui-manager",
|
|
750
|
+
identifier="comfyui-manager",
|
|
751
|
+
source="registry", # or "git", "development"
|
|
752
|
+
version="1.0.0",
|
|
753
|
+
url="https://github.com/...",
|
|
754
|
+
installed=True
|
|
755
|
+
)
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### EnvironmentStatus
|
|
759
|
+
```python
|
|
760
|
+
from comfydock_core.models.environment import EnvironmentStatus
|
|
761
|
+
|
|
762
|
+
# Returned by env.get_status()
|
|
763
|
+
status = EnvironmentStatus(
|
|
764
|
+
has_uncommitted_changes=True,
|
|
765
|
+
python_version="3.11.5",
|
|
766
|
+
comfyui_version="abc123",
|
|
767
|
+
installed_nodes=["comfyui-manager"],
|
|
768
|
+
tracked_workflows=["workflow.json"],
|
|
769
|
+
sync_issues=[] # list of issues if any
|
|
770
|
+
)
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
### ResolutionResult
|
|
774
|
+
```python
|
|
775
|
+
from comfydock_core.models.workflow import ResolutionResult
|
|
776
|
+
|
|
777
|
+
# Returned by env.resolve_workflow()
|
|
778
|
+
result = ResolutionResult(
|
|
779
|
+
all_nodes_resolved=True,
|
|
780
|
+
all_models_found=False,
|
|
781
|
+
unresolved_nodes=[],
|
|
782
|
+
missing_models=["model.safetensors"],
|
|
783
|
+
resolved_nodes=["node1", "node2"],
|
|
784
|
+
found_models=["other-model.safetensors"]
|
|
785
|
+
)
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
**API Reference**: See `src/comfydock_core/models/` for all data structures.
|
|
789
|
+
|
|
790
|
+
## Design Principles
|
|
791
|
+
|
|
792
|
+
ComfyDock Core follows these principles for library design:
|
|
793
|
+
|
|
794
|
+
1. **No UI Coupling**: Zero `print()` or `input()` statements. All user interaction through callbacks.
|
|
795
|
+
|
|
796
|
+
2. **Stateless Services**: Services are pure functions or stateless classes. State lives in Managers and Core objects.
|
|
797
|
+
|
|
798
|
+
3. **Strategy Pattern**: Pluggable behavior via protocol interfaces. Frontends provide their own strategies.
|
|
799
|
+
|
|
800
|
+
4. **Dependency Injection**: Factories handle complex object construction. No singletons.
|
|
801
|
+
|
|
802
|
+
5. **Layered Architecture**: Clear separation between API, Management, Service, and Repository layers.
|
|
803
|
+
|
|
804
|
+
6. **Type Safety**: Full type hints. Use protocols for interfaces, dataclasses for data.
|
|
805
|
+
|
|
806
|
+
7. **Error Transparency**: Custom exception hierarchy. No silent failures.
|
|
807
|
+
|
|
808
|
+
8. **Content-Addressable**: Models identified by hash, not path. Enables flexible remapping.
|
|
809
|
+
|
|
810
|
+
## Development
|
|
811
|
+
|
|
812
|
+
### Running Tests
|
|
813
|
+
|
|
814
|
+
```bash
|
|
815
|
+
# All tests
|
|
816
|
+
uv run pytest tests/
|
|
817
|
+
|
|
818
|
+
# Integration tests only
|
|
819
|
+
uv run pytest tests/integration/
|
|
820
|
+
|
|
821
|
+
# Unit tests only
|
|
822
|
+
uv run pytest tests/unit/
|
|
823
|
+
|
|
824
|
+
# Specific test file
|
|
825
|
+
uv run pytest tests/integration/test_environment_basic.py
|
|
826
|
+
|
|
827
|
+
# With coverage
|
|
828
|
+
uv run pytest --cov=comfydock_core tests/
|
|
829
|
+
|
|
830
|
+
# Verbose output
|
|
831
|
+
uv run pytest tests/ -v
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
### Project Structure
|
|
835
|
+
|
|
836
|
+
```
|
|
837
|
+
comfydock-core/
|
|
838
|
+
├── src/comfydock_core/
|
|
839
|
+
│ ├── core/ # Workspace & Environment
|
|
840
|
+
│ ├── managers/ # Orchestration layer
|
|
841
|
+
│ ├── services/ # Business logic
|
|
842
|
+
│ ├── repositories/ # Data access
|
|
843
|
+
│ ├── analyzers/ # Parsing & extraction
|
|
844
|
+
│ ├── resolvers/ # Action determination
|
|
845
|
+
│ ├── models/ # Data structures
|
|
846
|
+
│ ├── factories/ # Object construction
|
|
847
|
+
│ ├── strategies/ # Built-in strategies
|
|
848
|
+
│ ├── clients/ # External API clients
|
|
849
|
+
│ ├── utils/ # Utilities
|
|
850
|
+
│ ├── caching/ # Caching layer
|
|
851
|
+
│ ├── configs/ # Static configuration
|
|
852
|
+
│ ├── infrastructure/ # SQLite, etc.
|
|
853
|
+
│ ├── validation/ # Testing utilities
|
|
854
|
+
│ └── logging/ # Logging setup
|
|
855
|
+
├── tests/
|
|
856
|
+
│ ├── integration/ # Integration tests
|
|
857
|
+
│ ├── unit/ # Unit tests
|
|
858
|
+
│ └── conftest.py # Pytest fixtures
|
|
859
|
+
├── docs/
|
|
860
|
+
│ ├── codebase-map.md # Architecture details
|
|
861
|
+
│ ├── prd.md # Product requirements
|
|
862
|
+
│ └── layer-hierarchy.md # Layer dependencies
|
|
863
|
+
└── pyproject.toml # Package metadata
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
### Contributing
|
|
867
|
+
|
|
868
|
+
This is an MVP project maintained by a single developer. APIs may change between versions.
|
|
869
|
+
|
|
870
|
+
- **Issues**: [GitHub Issues](https://github.com/ComfyDock/comfydock/issues)
|
|
871
|
+
- **Discussions**: [GitHub Discussions](https://github.com/ComfyDock/comfydock/discussions)
|
|
872
|
+
- **Pull Requests**: Welcome, but discuss major changes first
|
|
873
|
+
|
|
874
|
+
## API Documentation
|
|
875
|
+
|
|
876
|
+
For detailed API documentation:
|
|
877
|
+
- **Full API Docs**: [www.comfydock.com/api](https://www.comfydock.com/api) (coming soon)
|
|
878
|
+
- **Architecture Details**: See `docs/codebase-map.md` in this repository
|
|
879
|
+
- **Source Code**: All source is in `src/comfydock_core/` with inline documentation
|
|
880
|
+
|
|
881
|
+
## Comparison to CLI
|
|
882
|
+
|
|
883
|
+
The CLI (`comfydock-cli` package) is built on top of this core library:
|
|
884
|
+
|
|
885
|
+
| Core Library | CLI Package |
|
|
886
|
+
|--------------|-------------|
|
|
887
|
+
| Programmatic Python API | Command-line interface |
|
|
888
|
+
| Strategy callbacks for UI | Interactive terminal UI |
|
|
889
|
+
| No user interaction | Prompts, progress bars, formatting |
|
|
890
|
+
| `workspace.create_environment()` | `cfd create <name>` |
|
|
891
|
+
| `env.add_node()` | `cfd node add <id>` |
|
|
892
|
+
| Returns data structures | Prints formatted output |
|
|
893
|
+
|
|
894
|
+
**Use the core library when:**
|
|
895
|
+
- Building a custom GUI (Qt, Electron, web UI)
|
|
896
|
+
- CI/CD automation
|
|
897
|
+
- Scripting bulk operations
|
|
898
|
+
- Integrating into larger tools
|
|
899
|
+
|
|
900
|
+
**Use the CLI when:**
|
|
901
|
+
- Interactive terminal usage
|
|
902
|
+
- Quick manual operations
|
|
903
|
+
- You want the pre-built UX
|
|
904
|
+
|
|
905
|
+
## License
|
|
906
|
+
|
|
907
|
+
ComfyDock Core is **dual-licensed**:
|
|
908
|
+
|
|
909
|
+
- **AGPL-3.0** for open-source use (free forever)
|
|
910
|
+
- **Commercial licenses** available for businesses requiring proprietary use
|
|
911
|
+
|
|
912
|
+
**For open-source projects:** Use freely under AGPL-3.0. Modifications must be open-sourced.
|
|
913
|
+
|
|
914
|
+
**For businesses:** Contact us for commercial licensing if you need to:
|
|
915
|
+
- Build proprietary applications without open-sourcing modifications
|
|
916
|
+
- Offer SaaS without disclosing source code
|
|
917
|
+
- Integrate into closed-source products
|
|
918
|
+
|
|
919
|
+
See [LICENSE.txt](../../LICENSE.txt) for the full AGPL-3.0 license text.
|
|
920
|
+
|
|
921
|
+
## Version & Stability
|
|
922
|
+
|
|
923
|
+
**Current Version**: 1.0.0
|
|
924
|
+
|
|
925
|
+
**Stability**: MVP - APIs may change between versions. Pin your dependencies:
|
|
926
|
+
|
|
927
|
+
```toml
|
|
928
|
+
# pyproject.toml
|
|
929
|
+
dependencies = [
|
|
930
|
+
"comfydock-core>=1.0.0,<1.1.0" # Pin to minor version
|
|
931
|
+
]
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
**Semantic Versioning**:
|
|
935
|
+
- Major (X.0.0): Breaking API changes
|
|
936
|
+
- Minor (0.X.0): New features, backward compatible
|
|
937
|
+
- Patch (0.0.X): Bug fixes, backward compatible
|
|
938
|
+
|
|
939
|
+
We will stabilize APIs as we approach 2.0.0 release.
|