comfy-headless 2.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. comfy_headless-2.5.1/.gitignore +81 -0
  2. comfy_headless-2.5.1/LICENSE +21 -0
  3. comfy_headless-2.5.1/PKG-INFO +393 -0
  4. comfy_headless-2.5.1/README.md +323 -0
  5. comfy_headless-2.5.1/pyproject.toml +187 -0
  6. comfy_headless-2.5.1/tests/Dockerfile.atheris +57 -0
  7. comfy_headless-2.5.1/tests/__init__.py +1 -0
  8. comfy_headless-2.5.1/tests/atheris_runner.py +286 -0
  9. comfy_headless-2.5.1/tests/conftest.py +77 -0
  10. comfy_headless-2.5.1/tests/run_fuzz.py +212 -0
  11. comfy_headless-2.5.1/tests/test_cleanup.py +140 -0
  12. comfy_headless-2.5.1/tests/test_cleanup_extended.py +583 -0
  13. comfy_headless-2.5.1/tests/test_client.py +977 -0
  14. comfy_headless-2.5.1/tests/test_client_coverage.py +1018 -0
  15. comfy_headless-2.5.1/tests/test_client_generation.py +650 -0
  16. comfy_headless-2.5.1/tests/test_config.py +72 -0
  17. comfy_headless-2.5.1/tests/test_config_extended.py +466 -0
  18. comfy_headless-2.5.1/tests/test_error_paths.py +389 -0
  19. comfy_headless-2.5.1/tests/test_exceptions.py +195 -0
  20. comfy_headless-2.5.1/tests/test_exceptions_extended.py +642 -0
  21. comfy_headless-2.5.1/tests/test_feature_flags_extended.py +523 -0
  22. comfy_headless-2.5.1/tests/test_fuzz.py +617 -0
  23. comfy_headless-2.5.1/tests/test_health.py +152 -0
  24. comfy_headless-2.5.1/tests/test_health_extended.py +567 -0
  25. comfy_headless-2.5.1/tests/test_help_system.py +454 -0
  26. comfy_headless-2.5.1/tests/test_http_client.py +58 -0
  27. comfy_headless-2.5.1/tests/test_http_client_extended.py +436 -0
  28. comfy_headless-2.5.1/tests/test_init_extended.py +446 -0
  29. comfy_headless-2.5.1/tests/test_integration.py +403 -0
  30. comfy_headless-2.5.1/tests/test_intelligence.py +174 -0
  31. comfy_headless-2.5.1/tests/test_intelligence_coverage.py +760 -0
  32. comfy_headless-2.5.1/tests/test_logging_config_extended.py +523 -0
  33. comfy_headless-2.5.1/tests/test_main.py +164 -0
  34. comfy_headless-2.5.1/tests/test_main_extended.py +160 -0
  35. comfy_headless-2.5.1/tests/test_property_based.py +412 -0
  36. comfy_headless-2.5.1/tests/test_retry.py +149 -0
  37. comfy_headless-2.5.1/tests/test_retry_extended.py +690 -0
  38. comfy_headless-2.5.1/tests/test_secrets_extended.py +617 -0
  39. comfy_headless-2.5.1/tests/test_snapshots.py +282 -0
  40. comfy_headless-2.5.1/tests/test_test_runner_ui.py +431 -0
  41. comfy_headless-2.5.1/tests/test_theme.py +482 -0
  42. comfy_headless-2.5.1/tests/test_ui.py +646 -0
  43. comfy_headless-2.5.1/tests/test_validation.py +597 -0
  44. comfy_headless-2.5.1/tests/test_video.py +264 -0
  45. comfy_headless-2.5.1/tests/test_video_coverage.py +879 -0
  46. comfy_headless-2.5.1/tests/test_websocket_client.py +491 -0
  47. comfy_headless-2.5.1/tests/test_websocket_extended.py +533 -0
  48. comfy_headless-2.5.1/tests/test_workflows.py +157 -0
@@ -0,0 +1,81 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ venv/
25
+ ENV/
26
+ env/
27
+
28
+ # IDE
29
+ .vscode/
30
+ .idea/
31
+ *.swp
32
+ *.swo
33
+
34
+ # Testing
35
+ .pytest_cache/
36
+ .coverage
37
+ htmlcov/
38
+ .tox/
39
+ .nox/
40
+
41
+ # Type checking
42
+ .mypy_cache/
43
+ .dmypy.json
44
+ dmypy.json
45
+
46
+ # Local development
47
+ .claude/
48
+ *.local.json
49
+ settings.local.json
50
+
51
+ # OS artifacts
52
+ .DS_Store
53
+ Thumbs.db
54
+ nul
55
+
56
+ # Logs
57
+ *.log
58
+ logs/
59
+
60
+ # Temp files
61
+ tmp/
62
+ temp/
63
+ *.tmp
64
+
65
+ # Archive folder
66
+ archive/
67
+
68
+ # Coverage reports
69
+ coverage_html/
70
+ coverage.xml
71
+
72
+ # Hypothesis testing
73
+ .hypothesis/
74
+
75
+ # Environment files
76
+ .env
77
+ .env.local
78
+ .env.*.local
79
+
80
+ # Build artifacts
81
+ *.whl
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mikey Frilot
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,393 @@
1
+ Metadata-Version: 2.4
2
+ Name: comfy-headless
3
+ Version: 2.5.1
4
+ Summary: Production-ready headless client for ComfyUI with AI-powered prompt intelligence, video generation, and modular architecture
5
+ Project-URL: Homepage, https://github.com/mcp-tool-shop/comfy-headless
6
+ Project-URL: Documentation, https://github.com/mcp-tool-shop/comfy-headless#readme
7
+ Project-URL: Repository, https://github.com/mcp-tool-shop/comfy-headless
8
+ Project-URL: Issues, https://github.com/mcp-tool-shop/comfy-headless/issues
9
+ Author: Mikey Frilot
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai,api,comfyui,headless,image-generation,stable-diffusion,video-generation
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Multimedia :: Graphics
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: requests>=2.28.0
26
+ Requires-Dist: tenacity>=8.0.0
27
+ Provides-Extra: ai
28
+ Requires-Dist: httpx>=0.24.0; extra == 'ai'
29
+ Provides-Extra: dev
30
+ Requires-Dist: httpx>=0.24.0; extra == 'dev'
31
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
32
+ Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
33
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
34
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
35
+ Requires-Dist: pytest-mock>=3.10.0; extra == 'dev'
36
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
37
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
38
+ Requires-Dist: websockets>=12.0; extra == 'dev'
39
+ Provides-Extra: docs
40
+ Requires-Dist: mkdocs-material>=9.0.0; extra == 'docs'
41
+ Requires-Dist: mkdocs>=1.5.0; extra == 'docs'
42
+ Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
43
+ Provides-Extra: full
44
+ Requires-Dist: gradio>=5.6.0; extra == 'full'
45
+ Requires-Dist: httpx>=0.24.0; extra == 'full'
46
+ Requires-Dist: opentelemetry-api>=1.20.0; extra == 'full'
47
+ Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == 'full'
48
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'full'
49
+ Requires-Dist: psutil>=5.9.0; extra == 'full'
50
+ Requires-Dist: pydantic-settings>=2.0.0; extra == 'full'
51
+ Requires-Dist: pydantic>=2.0.0; extra == 'full'
52
+ Requires-Dist: websockets>=12.0; extra == 'full'
53
+ Provides-Extra: health
54
+ Requires-Dist: psutil>=5.9.0; extra == 'health'
55
+ Provides-Extra: observability
56
+ Requires-Dist: opentelemetry-api>=1.20.0; extra == 'observability'
57
+ Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == 'observability'
58
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'observability'
59
+ Provides-Extra: standard
60
+ Requires-Dist: httpx>=0.24.0; extra == 'standard'
61
+ Requires-Dist: websockets>=12.0; extra == 'standard'
62
+ Provides-Extra: ui
63
+ Requires-Dist: gradio>=5.6.0; extra == 'ui'
64
+ Provides-Extra: validation
65
+ Requires-Dist: pydantic-settings>=2.0.0; extra == 'validation'
66
+ Requires-Dist: pydantic>=2.0.0; extra == 'validation'
67
+ Provides-Extra: websocket
68
+ Requires-Dist: websockets>=12.0; extra == 'websocket'
69
+ Description-Content-Type: text/markdown
70
+
71
+ # Comfy Headless
72
+
73
+ **Making ComfyUI's power accessible without the complexity.**
74
+
75
+ A clean, headless interface for ComfyUI with AI-powered prompt enhancement, template-based workflows, and multi-model video generation.
76
+
77
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)
78
+ ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
79
+ ![Version](https://img.shields.io/badge/version-2.5.1-green.svg)
80
+
81
+ ## Philosophy
82
+
83
+ ComfyUI is incredibly powerful, but its node-based interface can be overwhelming. Comfy Headless bridges this gap:
84
+
85
+ - **For Users**: Simple presets and AI-powered prompt enhancement
86
+ - **For Developers**: Clean API with template-based workflow compilation
87
+ - **For Everyone**: Best settings for your intent, automatically
88
+
89
+ ## Installation
90
+
91
+ ### Modular Installation (v2.5.0+)
92
+
93
+ Install only what you need:
94
+
95
+ ```bash
96
+ # Core only (minimal - ~2MB)
97
+ pip install comfy-headless
98
+
99
+ # With AI prompt enhancement (Ollama)
100
+ pip install comfy-headless[ai]
101
+
102
+ # With WebSocket real-time progress
103
+ pip install comfy-headless[websocket]
104
+
105
+ # Recommended for most users
106
+ pip install comfy-headless[standard]
107
+
108
+ # Everything (UI, health monitoring, observability)
109
+ pip install comfy-headless[full]
110
+ ```
111
+
112
+ ### Available Extras
113
+
114
+ | Extra | Dependencies | Features |
115
+ |-------|--------------|----------|
116
+ | `ai` | httpx | Ollama prompt intelligence |
117
+ | `websocket` | websockets | Real-time progress updates |
118
+ | `health` | psutil | System health monitoring |
119
+ | `ui` | gradio | Web interface |
120
+ | `validation` | pydantic | Config validation |
121
+ | `observability` | opentelemetry | Distributed tracing |
122
+ | `standard` | ai + websocket | Recommended bundle |
123
+ | `full` | All of the above | Everything |
124
+
125
+ ## Requirements
126
+
127
+ - Python 3.10+
128
+ - ComfyUI running locally (default: `http://localhost:8188`)
129
+ - Optional: Ollama for AI prompt enhancement
130
+
131
+ ## Quick Start
132
+
133
+ ### Use as a Library
134
+
135
+ ```python
136
+ from comfy_headless import ComfyClient
137
+
138
+ # Simple image generation
139
+ client = ComfyClient()
140
+ result = client.generate_image("a beautiful sunset over mountains")
141
+ print(f"Generated: {result['images']}")
142
+ ```
143
+
144
+ ### With AI Enhancement (requires `[ai]` extra)
145
+
146
+ ```python
147
+ from comfy_headless import ComfyClient, analyze_prompt, enhance_prompt
148
+
149
+ # Analyze a prompt
150
+ analysis = analyze_prompt("a cyberpunk city at night with neon lights")
151
+ print(f"Intent: {analysis.intent}") # "scene"
152
+ print(f"Styles: {analysis.styles}") # ["scifi", "cinematic"]
153
+ print(f"Preset: {analysis.suggested_preset}") # "cinematic"
154
+
155
+ # Enhance a prompt
156
+ enhanced = enhance_prompt("a cat", style="detailed")
157
+ print(enhanced.enhanced) # "a cat, masterpiece, best quality, highly detailed..."
158
+ print(enhanced.negative) # Style-aware negative prompt
159
+ ```
160
+
161
+ ### Video Generation
162
+
163
+ ```python
164
+ from comfy_headless import ComfyClient, VIDEO_PRESETS, list_video_presets
165
+
166
+ # See available presets
167
+ print(list_video_presets())
168
+
169
+ # Generate video with preset
170
+ client = ComfyClient()
171
+ result = client.generate_video(
172
+ prompt="a cat walking through a garden",
173
+ preset="ltx_quality" # LTX-Video 2, 1280x720, 49 frames
174
+ )
175
+ ```
176
+
177
+ ### Launch the Web UI (requires `[ui]` extra)
178
+
179
+ ```python
180
+ from comfy_headless import launch
181
+ launch() # Opens http://localhost:7870
182
+ ```
183
+
184
+ Or via command line:
185
+ ```bash
186
+ python -m comfy_headless.ui
187
+ ```
188
+
189
+ **UI Features (v2.5.1):**
190
+ - **Image Generation** - txt2img with presets, AI prompt enhancement
191
+ - **Video Generation** - AnimateDiff, LTX, Hunyuan, Wan support
192
+ - **Queue & History** - Real-time queue management, job history
193
+ - **Workflows** - Browse, import, and create workflow templates
194
+ - **Models Browser** - View checkpoints, LoRAs, motion models
195
+ - **Settings** - Connection management, timeouts, system info
196
+
197
+ **Theme:** Ocean Mist - soft teal accents on warm neutral backgrounds (Gradio 6.0)
198
+
199
+ ## Video Models (v2.5.0)
200
+
201
+ ### Supported Models
202
+
203
+ | Model | VRAM | Quality | Speed | Best For |
204
+ |-------|------|---------|-------|----------|
205
+ | **LTX-Video 2** | 12GB+ | Excellent | Fast | General use, RTX 3080+ |
206
+ | **Hunyuan 1.5** | 14GB+ | Best | Slow | High quality, RTX 4080+ |
207
+ | **Wan 2.1/2.2** | 6-16GB | Great | Medium | Budget GPUs, efficiency |
208
+ | **Mochi** | 12GB+ | Excellent | Slow | Text adherence |
209
+ | AnimateDiff | 6GB+ | Good | Fast | Quick previews |
210
+ | SVD | 8GB+ | Good | Medium | Image-to-video |
211
+ | CogVideoX | 10GB+ | Good | Slow | Legacy support |
212
+
213
+ ### Video Presets
214
+
215
+ ```python
216
+ from comfy_headless import VIDEO_PRESETS, get_recommended_preset
217
+
218
+ # Get preset recommendation based on your VRAM
219
+ preset = get_recommended_preset(vram_gb=16) # Returns "hunyuan15_720p"
220
+
221
+ # Available presets
222
+ presets = {
223
+ # LTX-Video 2 (Fast, great quality)
224
+ "ltx_quick": "768x512, 25 frames, 20 steps",
225
+ "ltx_standard": "1280x720, 49 frames, 25 steps",
226
+ "ltx_quality": "1280x720, 97 frames, 30 steps",
227
+
228
+ # Hunyuan 1.5 (Best quality)
229
+ "hunyuan15_720p": "1280x720, 121 frames",
230
+ "hunyuan15_quality": "1280x720, 121 frames, cfg=6",
231
+ "hunyuan15_fast": "848x480, 61 frames, 6 steps",
232
+ "hunyuan15_1080p": "1920x1080 with super-resolution",
233
+
234
+ # Wan (Efficient)
235
+ "wan_1.3b": "720x480, 49 frames (6GB VRAM)",
236
+ "wan_14b": "1280x720, 81 frames (12GB VRAM)",
237
+ "wan_fast": "720x480, 25 frames, 4 steps",
238
+
239
+ # Mochi (Text adherence)
240
+ "mochi": "848x480, 84 frames",
241
+ "mochi_short": "848x480, 37 frames",
242
+
243
+ # Legacy AnimateDiff
244
+ "quick": "512x512, 16 frames, 4-step lightning",
245
+ "standard": "512x512, 16 frames",
246
+ "quality": "768x768, 24 frames with RIFE",
247
+ }
248
+ ```
249
+
250
+ ## Feature Flags
251
+
252
+ Check what features are available:
253
+
254
+ ```python
255
+ from comfy_headless import FEATURES, list_available_features, list_missing_features
256
+
257
+ print(FEATURES)
258
+ # {'ai': True, 'websocket': True, 'health': False, ...}
259
+
260
+ print(list_missing_features())
261
+ # {'health': 'pip install comfy-headless[health]', ...}
262
+ ```
263
+
264
+ ## WebSocket Progress (requires `[websocket]` extra)
265
+
266
+ ```python
267
+ import asyncio
268
+ from comfy_headless import ComfyWSClient
269
+
270
+ async def generate_with_progress():
271
+ async with ComfyWSClient() as ws:
272
+ # Queue a prompt
273
+ prompt_id = await ws.queue_prompt(workflow)
274
+
275
+ # Wait with progress callbacks
276
+ result = await ws.wait_for_completion(
277
+ prompt_id,
278
+ on_progress=lambda p: print(f"Progress: {p.progress}%")
279
+ )
280
+ return result
281
+
282
+ asyncio.run(generate_with_progress())
283
+ ```
284
+
285
+ ## API Reference
286
+
287
+ ### Core Classes
288
+
289
+ ```python
290
+ from comfy_headless import (
291
+ # Client
292
+ ComfyClient, # Main HTTP client
293
+ ComfyWSClient, # WebSocket client (requires [websocket])
294
+
295
+ # Video
296
+ VideoSettings, # Video generation settings
297
+ VideoModel, # Model enum (LTXV, HUNYUAN_15, WAN, etc.)
298
+ VIDEO_PRESETS, # Preset configurations
299
+ get_recommended_preset, # VRAM-based recommendation
300
+
301
+ # Workflows
302
+ compile_workflow, # Compile workflow from preset
303
+ WorkflowCompiler, # Low-level compiler
304
+
305
+ # Intelligence (requires [ai])
306
+ analyze_prompt, # Analyze prompt intent/style
307
+ enhance_prompt, # AI-powered enhancement
308
+ PromptAnalysis, # Analysis result type
309
+ )
310
+ ```
311
+
312
+ ### Configuration
313
+
314
+ ```python
315
+ from comfy_headless import settings, get_settings, reload_settings
316
+
317
+ # Access settings
318
+ print(settings.comfy_url) # http://localhost:8188
319
+
320
+ # Override via environment
321
+ # COMFY_HEADLESS_COMFY_URL=http://remote:8188
322
+ ```
323
+
324
+ ### Error Handling
325
+
326
+ ```python
327
+ from comfy_headless import (
328
+ ComfyHeadlessError, # Base exception
329
+ ComfyUIConnectionError, # Can't reach ComfyUI
330
+ ComfyUIOfflineError, # ComfyUI not responding
331
+ GenerationTimeoutError, # Generation took too long
332
+ GenerationFailedError, # Generation failed
333
+ ValidationError, # Invalid parameters
334
+ )
335
+
336
+ try:
337
+ result = client.generate_image("test")
338
+ except ComfyUIOfflineError:
339
+ print("Start ComfyUI first!")
340
+ except GenerationTimeoutError:
341
+ print("Generation timed out")
342
+ ```
343
+
344
+ ## Architecture
345
+
346
+ ```
347
+ comfy_headless/
348
+ ├── __init__.py # Package exports, lazy loading
349
+ ├── feature_flags.py # Optional dependency detection
350
+ ├── client.py # ComfyUI HTTP client
351
+ ├── websocket_client.py # WebSocket client
352
+ ├── intelligence.py # AI prompt analysis (requires [ai])
353
+ ├── workflows.py # Template compiler & presets
354
+ ├── video.py # Video models & presets
355
+ ├── ui.py # Gradio 6.0 interface (requires [ui])
356
+ ├── theme.py # Ocean Mist theme (soft teal, warm neutrals)
357
+ ├── config.py # Settings management
358
+ ├── exceptions.py # Error types with verbosity
359
+ ├── retry.py # Circuit breaker, rate limiting
360
+ ├── health.py # Health checks (requires [health])
361
+ ├── secrets_manager.py # Secrets management utilities
362
+ ├── help_system.py # Contextual help system
363
+ └── tests/ # Test suite
364
+ ```
365
+
366
+ ## ComfyUI Node Requirements
367
+
368
+ ### For Video Generation
369
+
370
+ Install these custom nodes:
371
+
372
+ **Core:**
373
+ - [ComfyUI-VideoHelperSuite](https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite) - Video encoding
374
+
375
+ **Model-Specific:**
376
+ - LTX-Video 2: Built-in ComfyUI support (recent versions)
377
+ - Hunyuan 1.5: [ComfyUI-HunyuanVideo](https://github.com/kijai/ComfyUI-HunyuanVideoWrapper)
378
+ - Wan: [ComfyUI-WanVideoWrapper](https://github.com/kijai/ComfyUI-WanVideoWrapper)
379
+ - AnimateDiff: [ComfyUI-AnimateDiff-Evolved](https://github.com/Kosinkadink/ComfyUI-AnimateDiff-Evolved)
380
+
381
+ ## License
382
+
383
+ MIT License - see [LICENSE](LICENSE)
384
+
385
+ ## Contributing
386
+
387
+ Contributions welcome! Please open an issue or pull request.
388
+
389
+ Areas of interest:
390
+ - Additional video model support
391
+ - Workflow templates
392
+ - Documentation
393
+ - Bug fixes