comfygit 0.3.20__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. {comfygit-0.3.20 → comfygit-0.4.0}/PKG-INFO +7 -4
  2. {comfygit-0.3.20 → comfygit-0.4.0}/README.md +3 -2
  3. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/cli.py +214 -41
  4. comfygit-0.4.0/comfygit_cli/contract_studio_static/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  5. comfygit-0.4.0/comfygit_cli/contract_studio_static/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  6. comfygit-0.4.0/comfygit_cli/contract_studio_static/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  7. comfygit-0.4.0/comfygit_cli/contract_studio_static/assets/index-BrjwrxCF.js +17 -0
  8. comfygit-0.4.0/comfygit_cli/contract_studio_static/assets/index-U1BNuI3X.css +1 -0
  9. comfygit-0.4.0/comfygit_cli/contract_studio_static/index.html +14 -0
  10. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/env_commands.py +513 -132
  11. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/global_commands.py +381 -62
  12. comfygit-0.4.0/comfygit_cli/serve_executor.py +1000 -0
  13. comfygit-0.4.0/comfygit_cli/serve_runtime.py +2934 -0
  14. comfygit-0.4.0/comfygit_cli/serve_state.py +905 -0
  15. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/utils/orchestrator.py +7 -10
  16. comfygit-0.4.0/contract-studio/AGENTS.md +52 -0
  17. comfygit-0.4.0/contract-studio/components.json +21 -0
  18. comfygit-0.4.0/contract-studio/index.html +13 -0
  19. comfygit-0.4.0/contract-studio/package-lock.json +6926 -0
  20. comfygit-0.4.0/contract-studio/package.json +36 -0
  21. comfygit-0.4.0/contract-studio/src/App.tsx +429 -0
  22. comfygit-0.4.0/contract-studio/src/app/components.tsx +371 -0
  23. comfygit-0.4.0/contract-studio/src/components/ContractInputControl.tsx +233 -0
  24. comfygit-0.4.0/contract-studio/src/components/GalleryTile.tsx +142 -0
  25. comfygit-0.4.0/contract-studio/src/components/OutputViewer.tsx +275 -0
  26. comfygit-0.4.0/contract-studio/src/components/ReadoutBlock.tsx +45 -0
  27. comfygit-0.4.0/contract-studio/src/components/ui/button.tsx +164 -0
  28. comfygit-0.4.0/contract-studio/src/components/ui/select-content.tsx +320 -0
  29. comfygit-0.4.0/contract-studio/src/components/ui/select.tsx +449 -0
  30. comfygit-0.4.0/contract-studio/src/components/ui/tooltip.tsx +123 -0
  31. comfygit-0.4.0/contract-studio/src/hooks/use-proximity-hover.ts +185 -0
  32. comfygit-0.4.0/contract-studio/src/lib/api.ts +93 -0
  33. comfygit-0.4.0/contract-studio/src/lib/clipboard.ts +23 -0
  34. comfygit-0.4.0/contract-studio/src/lib/font-weight.ts +6 -0
  35. comfygit-0.4.0/contract-studio/src/lib/format.ts +87 -0
  36. comfygit-0.4.0/contract-studio/src/lib/gallery.ts +169 -0
  37. comfygit-0.4.0/contract-studio/src/lib/icon-context.tsx +7 -0
  38. comfygit-0.4.0/contract-studio/src/lib/inputs.ts +76 -0
  39. comfygit-0.4.0/contract-studio/src/lib/shape-context.tsx +115 -0
  40. comfygit-0.4.0/contract-studio/src/lib/springs.ts +17 -0
  41. comfygit-0.4.0/contract-studio/src/lib/utils.ts +6 -0
  42. comfygit-0.4.0/contract-studio/src/main.tsx +13 -0
  43. comfygit-0.4.0/contract-studio/src/styles.css +1601 -0
  44. comfygit-0.4.0/contract-studio/src/types.ts +183 -0
  45. comfygit-0.4.0/contract-studio/src/vite-env.d.ts +3 -0
  46. comfygit-0.4.0/contract-studio/tsconfig.json +24 -0
  47. comfygit-0.4.0/contract-studio/vite.config.ts +28 -0
  48. {comfygit-0.3.20 → comfygit-0.4.0}/pyproject.toml +14 -3
  49. comfygit-0.3.20/.github/workflows/publish_pypi.yml +0 -56
  50. comfygit-0.3.20/.python-version +0 -1
  51. comfygit-0.3.20/CLAUDE.md +0 -103
  52. comfygit-0.3.20/docs/architecture.md +0 -145
  53. comfygit-0.3.20/scripts/README_REGISTRY.md +0 -130
  54. comfygit-0.3.20/scripts/augment_mappings.py +0 -381
  55. comfygit-0.3.20/scripts/build_global_mappings.py +0 -275
  56. comfygit-0.3.20/scripts/build_registry_cache.py +0 -659
  57. comfygit-0.3.20/scripts/extract_builtin_nodes.py +0 -546
  58. comfygit-0.3.20/scripts/extract_node_modules.py +0 -77
  59. comfygit-0.3.20/scripts/get_hash.py +0 -86
  60. comfygit-0.3.20/scripts/global-node-mappings.md +0 -299
  61. comfygit-0.3.20/scripts/registry.py +0 -547
  62. comfygit-0.3.20/scripts/registry_client.py +0 -184
  63. comfygit-0.3.20/scripts/test_concurrent_api.py +0 -318
  64. comfygit-0.3.20/tests/conftest.py +0 -37
  65. comfygit-0.3.20/tests/test_batch_node_add.py +0 -195
  66. comfygit-0.3.20/tests/test_batch_node_remove.py +0 -225
  67. comfygit-0.3.20/tests/test_branch_commands.py +0 -466
  68. comfygit-0.3.20/tests/test_completers.py +0 -436
  69. comfygit-0.3.20/tests/test_completion_commands.py +0 -301
  70. comfygit-0.3.20/tests/test_conflict_resolver.py +0 -218
  71. comfygit-0.3.20/tests/test_detached_head_display.py +0 -157
  72. comfygit-0.3.20/tests/test_doctor_command.py +0 -99
  73. comfygit-0.3.20/tests/test_error_formatter.py +0 -173
  74. comfygit-0.3.20/tests/test_log_command.py +0 -178
  75. comfygit-0.3.20/tests/test_logging_structure.py +0 -199
  76. comfygit-0.3.20/tests/test_manager_commands.py +0 -317
  77. comfygit-0.3.20/tests/test_manifest_command.py +0 -187
  78. comfygit-0.3.20/tests/test_pagination.py +0 -72
  79. comfygit-0.3.20/tests/test_preview_display.py +0 -276
  80. comfygit-0.3.20/tests/test_py_commands.py +0 -883
  81. comfygit-0.3.20/tests/test_py_remove_group_commands.py +0 -140
  82. comfygit-0.3.20/tests/test_status_disabled_nodes_display.py +0 -94
  83. comfygit-0.3.20/tests/test_status_displays_uninstalled_nodes.py +0 -179
  84. comfygit-0.3.20/tests/test_status_path_sync_display.py +0 -92
  85. comfygit-0.3.20/tests/test_status_real_bug_scenario.py +0 -135
  86. comfygit-0.3.20/tests/test_status_suggestions.py +0 -137
  87. comfygit-0.3.20/tests/test_status_uninstalled_reporting.py +0 -62
  88. comfygit-0.3.20/tests/test_torch_backend_cli.py +0 -300
  89. comfygit-0.3.20/tests/test_update_checker.py +0 -71
  90. comfygit-0.3.20/tests/test_update_command.py +0 -51
  91. comfygit-0.3.20/tests/test_update_notice.py +0 -84
  92. comfygit-0.3.20/tests/test_update_workflow_model_paths.py +0 -189
  93. comfygit-0.3.20/tests/test_workflow_model_importance.py +0 -210
  94. {comfygit-0.3.20 → comfygit-0.4.0}/.gitignore +0 -0
  95. {comfygit-0.3.20 → comfygit-0.4.0}/LICENSE.txt +0 -0
  96. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/__init__.py +0 -0
  97. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/__main__.py +0 -0
  98. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/cli_utils.py +0 -0
  99. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/completers.py +0 -0
  100. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/completion_commands.py +0 -0
  101. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/formatters/__init__.py +0 -0
  102. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/formatters/error_formatter.py +0 -0
  103. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/interactive/__init__.py +0 -0
  104. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/logging/compressed_handler.py +0 -0
  105. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/logging/environment_logger.py +0 -0
  106. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/logging/log_compressor.py +0 -0
  107. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/logging/logging_config.py +0 -0
  108. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/resolution_strategies.py +0 -0
  109. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/strategies/__init__.py +0 -0
  110. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/strategies/conflict_resolver.py +0 -0
  111. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/strategies/interactive.py +0 -0
  112. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/strategies/rollback.py +0 -0
  113. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/update_commands.py +0 -0
  114. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/utils/__init__.py +0 -0
  115. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/utils/civitai_errors.py +0 -0
  116. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/utils/pagination.py +0 -0
  117. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/utils/progress.py +0 -0
  118. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/utils/update_checker.py +0 -0
  119. {comfygit-0.3.20 → comfygit-0.4.0}/comfygit_cli/utils/update_notice.py +0 -0
@@ -1,14 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comfygit
3
- Version: 0.3.20
3
+ Version: 0.4.0
4
4
  Summary: ComfyGit - Git-based environment management for ComfyUI
5
5
  Project-URL: Documentation, https://docs.comfygit.org/
6
6
  Project-URL: Repository, https://github.com/comfygit-ai/comfygit
7
7
  Project-URL: Issues, https://github.com/comfygit-ai/comfygit/issues
8
8
  License-File: LICENSE.txt
9
9
  Requires-Python: >=3.10
10
+ Requires-Dist: aiohttp>=3.13.4
10
11
  Requires-Dist: argcomplete>=3.5.0
11
- Requires-Dist: comfygit-core==0.3.20
12
+ Requires-Dist: comfygit-core==0.4.0
13
+ Requires-Dist: requests>=2.33.0
12
14
  Description-Content-Type: text/markdown
13
15
 
14
16
  # ComfyGit CLI
@@ -663,9 +665,10 @@ See [packages/core/README.md](../core/README.md) for core library documentation.
663
665
 
664
666
  ## Contributing
665
667
 
666
- This is a MVP project run by a single developer. Contributions welcome!
668
+ This is a MVP project run by a single developer. Contributions welcome.
667
669
 
668
- **Note:** Contributors must sign our [Contributor License Agreement](../../CLA.md) to enable dual-licensing. See [CONTRIBUTING.md](../../CONTRIBUTING.md) for details.
670
+ Contributions are licensed under the repository's GPL-3.0 license. See
671
+ [CONTRIBUTING.md](../../CONTRIBUTING.md) for details.
669
672
 
670
673
  **Adding a new command:**
671
674
  1. Add command parser in `cli.py` (`_add_global_commands` or `_add_env_commands`)
@@ -650,9 +650,10 @@ See [packages/core/README.md](../core/README.md) for core library documentation.
650
650
 
651
651
  ## Contributing
652
652
 
653
- This is a MVP project run by a single developer. Contributions welcome!
653
+ This is a MVP project run by a single developer. Contributions welcome.
654
654
 
655
- **Note:** Contributors must sign our [Contributor License Agreement](../../CLA.md) to enable dual-licensing. See [CONTRIBUTING.md](../../CONTRIBUTING.md) for details.
655
+ Contributions are licensed under the repository's GPL-3.0 license. See
656
+ [CONTRIBUTING.md](../../CONTRIBUTING.md) for details.
656
657
 
657
658
  **Adding a new command:**
658
659
  1. Add command parser in `cli.py` (`_add_global_commands` or `_add_env_commands`)
@@ -179,6 +179,42 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
179
179
  list_parser = subparsers.add_parser("list", help="List all environments")
180
180
  list_parser.set_defaults(func=global_cmds.list_envs)
181
181
 
182
+ # analyze - Analyze a workflow file without requiring workspace/env
183
+ analyze_parser = subparsers.add_parser(
184
+ "analyze",
185
+ help="Analyze a workflow file for dependencies",
186
+ )
187
+ analyze_parser.add_argument("workflow", type=Path, help="Path to workflow JSON file")
188
+ analyze_parser.add_argument(
189
+ "--json",
190
+ action="store_true",
191
+ dest="json_output",
192
+ help="Output as JSON",
193
+ )
194
+ analyze_parser.add_argument(
195
+ "--draft-spec",
196
+ action="store_true",
197
+ help="Output draft pyproject.toml",
198
+ )
199
+ analyze_parser.add_argument(
200
+ "--online",
201
+ action="store_true",
202
+ help="Enrich model sources using online provider lookups",
203
+ )
204
+ analyze_parser.add_argument(
205
+ "--verbose",
206
+ "-v",
207
+ action="store_true",
208
+ help="Show detailed provenance",
209
+ )
210
+ analyze_parser.add_argument(
211
+ "--quiet",
212
+ "-q",
213
+ action="store_true",
214
+ help="Only show unresolved items",
215
+ )
216
+ analyze_parser.set_defaults(func=global_cmds.analyze)
217
+
182
218
  # update - Update ComfyGit CLI (self-update)
183
219
  update_parser = subparsers.add_parser("update", help="Update ComfyGit CLI")
184
220
  update_parser.add_argument("--check", action="store_true", help="Check for updates without upgrading")
@@ -206,6 +242,11 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
206
242
  "Default: auto"
207
243
  ),
208
244
  )
245
+ import_parser.add_argument(
246
+ "--no-manager",
247
+ action="store_true",
248
+ help="Skip comfygit-manager installation (headless/API-only mode)",
249
+ )
209
250
  import_parser.add_argument("--use", action="store_true", help="Set imported environment as active")
210
251
  import_parser.add_argument(
211
252
  "--models",
@@ -215,6 +256,41 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
215
256
  import_parser.add_argument("-y", "--yes", action="store_true", help="Skip confirmation prompts, use defaults for workspace initialization")
216
257
  import_parser.set_defaults(func=global_cmds.import_env)
217
258
 
259
+ # materialize - Hydrate a portable environment for headless runtime/build use
260
+ materialize_parser = subparsers.add_parser(
261
+ "materialize",
262
+ help="Materialize a ComfyGit environment from a directory, tarball, or git URL",
263
+ )
264
+ materialize_parser.add_argument("source", type=str, help="Source directory, .tar.gz bundle, or git repository URL")
265
+ materialize_parser.add_argument("--name", type=str, required=True, help="Name for the materialized environment")
266
+ materialize_parser.add_argument("--workspace", type=Path, help="Workspace path to create/use")
267
+ materialize_parser.add_argument("--models-dir", type=Path, help="Global model directory for the workspace")
268
+ materialize_parser.add_argument("--branch", "-b", type=str, help="Git branch, tag, or commit to materialize")
269
+ materialize_parser.add_argument(
270
+ "--torch-backend",
271
+ default="auto",
272
+ metavar="BACKEND",
273
+ help=(
274
+ "PyTorch backend. Examples: auto (detect GPU), cpu, "
275
+ "cu128 (CUDA 12.8), cu126, cu124, rocm6.3 (AMD), xpu (Intel). "
276
+ "Default: auto"
277
+ ),
278
+ )
279
+ materialize_parser.add_argument(
280
+ "--models",
281
+ choices=["all", "required", "skip"],
282
+ default="skip",
283
+ help="Model download strategy. Default: skip",
284
+ )
285
+ materialize_parser.add_argument(
286
+ "--with-manager",
287
+ action="store_true",
288
+ help="Install/register comfygit-manager during materialization",
289
+ )
290
+ materialize_parser.add_argument("--use", action="store_true", help="Set materialized environment as active")
291
+ materialize_parser.add_argument("--replace", action="store_true", help="Replace an existing environment with the same name")
292
+ materialize_parser.set_defaults(func=global_cmds.materialize_env)
293
+
218
294
  # export - Export ComfyGit environment
219
295
  export_parser = subparsers.add_parser("export", help="Export ComfyGit environment (include relevant files from .cec)")
220
296
  export_parser.add_argument("path", type=Path, nargs="?", help="Path to output file")
@@ -273,6 +349,12 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
273
349
  model_add_source_parser.add_argument("url", nargs="?", help="Download URL")
274
350
  model_add_source_parser.set_defaults(func=global_cmds.model_add_source)
275
351
 
352
+ # model delete
353
+ model_delete_parser = model_subparsers.add_parser("delete", help="Delete model files and clean index entries")
354
+ model_delete_parser.add_argument("identifier", help="Model hash, hash prefix, filename, or path")
355
+ model_delete_parser.add_argument("-y", "--yes", action="store_true", help="Skip confirmation prompt")
356
+ model_delete_parser.set_defaults(func=global_cmds.model_delete)
357
+
276
358
  # Registry management subcommands
277
359
  registry_parser = subparsers.add_parser("registry", help="Manage node registry cache")
278
360
  registry_subparsers = registry_parser.add_subparsers(dest="registry_command", help="Registry commands")
@@ -292,6 +374,7 @@ def _add_global_commands(subparsers: argparse._SubParsersAction) -> None:
292
374
 
293
375
  # Legacy flags - still supported at root level for backward compatibility
294
376
  config_parser.add_argument("--civitai-key", type=str, help="Set Civitai API key (use empty string to clear)")
377
+ config_parser.add_argument("--github-token", type=str, help="Set GitHub token for private git repository access (use empty string to clear)")
295
378
  config_parser.add_argument("--uv-cache", type=str, help="Set external UV cache path (use empty string to clear)")
296
379
  config_parser.add_argument("--show", action="store_true", help="Show current configuration")
297
380
  config_parser.set_defaults(func=global_cmds.config)
@@ -405,6 +488,11 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
405
488
  "Default: auto"
406
489
  ),
407
490
  )
491
+ create_parser.add_argument(
492
+ "--no-manager",
493
+ action="store_true",
494
+ help="Skip comfygit-manager installation (headless/API-only mode)",
495
+ )
408
496
  create_parser.add_argument("--use", action="store_true", help="Set active environment after creation")
409
497
  create_parser.add_argument("-y", "--yes", action="store_true", help="Skip confirmation prompts, use defaults for workspace initialization")
410
498
  create_parser.set_defaults(func=env_cmds.create)
@@ -445,47 +533,6 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
445
533
  env_config_torch_detect_parser = env_config_torch_subparsers.add_parser("detect", help="Auto-detect and show recommended backend")
446
534
  env_config_torch_detect_parser.set_defaults(func=env_cmds.env_config_torch_detect)
447
535
 
448
- # env-config local-sources - Manage local UV sources for this environment
449
- env_config_local_sources_parser = env_config_subparsers.add_parser(
450
- "local-sources",
451
- help="Manage local UV source overrides"
452
- )
453
- env_config_local_sources_subparsers = env_config_local_sources_parser.add_subparsers(
454
- dest="local_sources_command",
455
- help="Local source commands"
456
- )
457
- env_config_local_sources_parser.set_defaults(func=_make_help_func(env_config_local_sources_parser))
458
-
459
- # env-config local-sources show
460
- env_config_local_sources_show_parser = env_config_local_sources_subparsers.add_parser(
461
- "show", help="Show local UV sources"
462
- )
463
- env_config_local_sources_show_parser.set_defaults(func=env_cmds.env_config_local_sources_show)
464
-
465
- # env-config local-sources add <package> --path PATH [--editable]
466
- env_config_local_sources_add_parser = env_config_local_sources_subparsers.add_parser(
467
- "add", help="Add or update a local UV source"
468
- )
469
- env_config_local_sources_add_parser.add_argument("package", help="Package name to override")
470
- env_config_local_sources_add_parser.add_argument(
471
- "--path",
472
- required=True,
473
- help="Local path to package (absolute or relative)"
474
- )
475
- env_config_local_sources_add_parser.add_argument(
476
- "--editable",
477
- action="store_true",
478
- help="Install as editable"
479
- )
480
- env_config_local_sources_add_parser.set_defaults(func=env_cmds.env_config_local_sources_add)
481
-
482
- # env-config local-sources remove <package>
483
- env_config_local_sources_remove_parser = env_config_local_sources_subparsers.add_parser(
484
- "remove", help="Remove a local UV source"
485
- )
486
- env_config_local_sources_remove_parser.add_argument("package", help="Package name to remove")
487
- env_config_local_sources_remove_parser.set_defaults(func=env_cmds.env_config_local_sources_remove)
488
-
489
536
  # env-config extras - Manage default optional extras for sync
490
537
  env_config_extras_parser = env_config_subparsers.add_parser(
491
538
  "extras",
@@ -517,6 +564,32 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
517
564
  env_config_extras_remove_parser.add_argument("extras", nargs="+", help="Extra name(s) to remove")
518
565
  env_config_extras_remove_parser.set_defaults(func=env_cmds.env_config_extras_remove)
519
566
 
567
+ # overlay - Manage overlays for this environment
568
+ overlay_parser = subparsers.add_parser("overlay", help="Manage dependency overlays")
569
+ overlay_subparsers = overlay_parser.add_subparsers(dest="overlay_command", help="Overlay commands")
570
+ overlay_parser.set_defaults(func=_make_help_func(overlay_parser))
571
+
572
+ overlay_list_parser = overlay_subparsers.add_parser("list", help="List available overlays")
573
+ overlay_list_parser.add_argument("--active", action="store_true", help="Show only active overlays")
574
+ overlay_list_parser.set_defaults(func=env_cmds.overlay_list)
575
+
576
+ overlay_show_parser = overlay_subparsers.add_parser("show", help="Show overlay file contents")
577
+ overlay_show_parser.add_argument("name", help="Overlay name")
578
+ overlay_show_parser.set_defaults(func=env_cmds.overlay_show)
579
+
580
+ overlay_enable_parser = overlay_subparsers.add_parser("enable", help="Enable overlay for this machine")
581
+ overlay_enable_parser.add_argument("name", help="Overlay name")
582
+ overlay_enable_parser.set_defaults(func=env_cmds.overlay_enable)
583
+
584
+ overlay_disable_parser = overlay_subparsers.add_parser("disable", help="Disable overlay for this machine")
585
+ overlay_disable_parser.add_argument("name", help="Overlay name")
586
+ overlay_disable_parser.set_defaults(func=env_cmds.overlay_disable)
587
+
588
+ overlay_create_parser = overlay_subparsers.add_parser("create", help="Create overlay template")
589
+ overlay_create_parser.add_argument("name", nargs="?", default=None, help="Overlay name")
590
+ overlay_create_parser.add_argument("--local", action="store_true", help="Create a local (gitignored) overlay")
591
+ overlay_create_parser.set_defaults(func=env_cmds.overlay_create)
592
+
520
593
  # run - Run ComfyUI (special handling for ComfyUI args)
521
594
  run_parser = subparsers.add_parser("run", help="Run ComfyUI")
522
595
  run_parser.add_argument("--no-sync", action="store_true", help="Skip environment sync before running")
@@ -540,8 +613,98 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
540
613
  action="store_true",
541
614
  help="Install all optional dependency extras"
542
615
  )
616
+ run_parser.add_argument(
617
+ "--overlay",
618
+ action="append",
619
+ help="Apply overlay for this run sync (can be repeated)",
620
+ )
543
621
  run_parser.set_defaults(func=env_cmds.run, args=[])
544
622
 
623
+ # serve - Front a running ComfyUI instance with contract-shaped endpoints
624
+ serve_parser = subparsers.add_parser(
625
+ "serve",
626
+ help="Serve workflow contracts for this environment",
627
+ )
628
+ serve_parser.add_argument(
629
+ "--host",
630
+ default="127.0.0.1",
631
+ help="Host/interface to bind (default: 127.0.0.1)",
632
+ )
633
+ serve_parser.add_argument(
634
+ "--port",
635
+ type=int,
636
+ default=8190,
637
+ help="Port to bind (default: 8190)",
638
+ )
639
+ serve_parser.add_argument(
640
+ "--comfy-url",
641
+ default="http://127.0.0.1:8188",
642
+ help="Running ComfyUI API URL (default: http://127.0.0.1:8188)",
643
+ )
644
+ serve_parser.add_argument(
645
+ "--role",
646
+ choices=["studio", "proxy"],
647
+ default="studio",
648
+ help="Serve role: studio front door or compute-only proxy runtime (default: studio)",
649
+ )
650
+ serve_parser.add_argument(
651
+ "--executor",
652
+ choices=["local", "proxy"],
653
+ default="local",
654
+ help="Execution adapter for studio role (default: local)",
655
+ )
656
+ serve_parser.add_argument(
657
+ "--proxy-url",
658
+ help="Proxy runtime base URL when --executor proxy is used",
659
+ )
660
+ serve_parser.add_argument(
661
+ "--proxy-token",
662
+ help="Bearer token shared by proxy front door and proxy runtime",
663
+ )
664
+ serve_parser.add_argument(
665
+ "--callback-url",
666
+ help="Browser/coordinator-reachable base URL that proxy workers call back after async runs",
667
+ )
668
+ serve_parser.add_argument(
669
+ "--callback-token",
670
+ help="Bearer token accepted by the front door worker-callback endpoint (defaults to --proxy-token)",
671
+ )
672
+ serve_parser.add_argument(
673
+ "--artifact-dir",
674
+ type=Path,
675
+ help="Directory for localized proxy artifacts (default: <workspace>/.metadata/serve/artifacts)",
676
+ )
677
+ serve_parser.add_argument(
678
+ "--max-request-mb",
679
+ type=int,
680
+ default=256,
681
+ help="Maximum contract request body size in MiB (default: 256)",
682
+ )
683
+ serve_parser.add_argument(
684
+ "--run-timeout-seconds",
685
+ type=float,
686
+ default=12 * 60 * 60,
687
+ help="Maximum background run wait time in seconds (default: 43200)",
688
+ )
689
+ serve_parser.add_argument(
690
+ "--state",
691
+ choices=["ephemeral", "local"],
692
+ default="ephemeral",
693
+ help="Serve runtime state adapter (default: ephemeral)",
694
+ )
695
+ serve_parser.add_argument(
696
+ "--gallery",
697
+ choices=["private", "shared"],
698
+ default="private",
699
+ help="Gallery visibility policy for serve state (default: private)",
700
+ )
701
+ serve_parser.add_argument(
702
+ "--state-db",
703
+ type=Path,
704
+ help="SQLite database path for --state local (default: <workspace>/.metadata/serve/serve.sqlite)",
705
+ )
706
+ serve_parser.set_defaults(func=env_cmds.serve)
707
+
545
708
  # status - Show environment status
546
709
  status_parser = subparsers.add_parser("status", help="Show status (both sync and git status)")
547
710
  status_parser.add_argument("-v", "--verbose", action="store_true", help="Show full details")
@@ -599,6 +762,11 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
599
762
  action="store_true",
600
763
  help="Install all optional dependency extras"
601
764
  )
765
+ sync_parser.add_argument(
766
+ "--overlay",
767
+ action="append",
768
+ help="Apply overlay for this sync only (can be repeated)",
769
+ )
602
770
  sync_parser.add_argument(
603
771
  "-v", "--verbose",
604
772
  action="store_true",
@@ -793,6 +961,11 @@ def _add_env_commands(subparsers: argparse._SubParsersAction) -> None:
793
961
  node_add_parser.add_argument("--force", action="store_true", help="Force overwrite existing directory")
794
962
  node_add_parser.add_argument("--verbose", "-v", action="store_true", help="Show full UV error output for dependency conflicts")
795
963
  node_add_parser.add_argument("--strict", action="store_true", help="Fail on dependency conflicts instead of auto-resolving")
964
+ node_add_parser.add_argument(
965
+ "--resolve-with-overlays",
966
+ action="store_true",
967
+ help="Resolve node install with all active overlays (default is pytorch-only)",
968
+ )
796
969
  node_add_parser.add_argument(
797
970
  "--extra",
798
971
  action="append",