Commit Graph
171 Commits
Author SHA1 Message Date
AEmotionStudio 73b2bfe5b1 Fix CI: Add numpy to requirements-nodes.txt 2026-01-21 00:41:04 -08:00
AEmotionStudio b3d8f9d16f Fix CI: Add Pillow to requirements-nodes.txt 2026-01-21 00:19:23 -08:00
AEmotionStudio b63dac6cad Refactor Image and Video nodes to inherit from BaseDiscordNode 2026-01-20 23:41:39 -08:00
AEmotionStudio 3ee819d042 refactor: make DiscordSendSaveImage inherit from BaseDiscordNode 2026-01-20 22:27:59 -08:00
AEmotionStudio 1ba7122694 docs: add GitHub Actions test badge to README 2026-01-20 19:02:00 -08:00
AEmotionStudio e00194e0e7 ci: add GitHub Actions test workflow 2026-01-20 19:01:07 -08:00
AEmotionStudio c74b572c38 chore: split requirements into nodes-only and bot versions 2026-01-20 19:00:23 -08:00
Æmotion Studio 5d23e30dbc Merge pull request #37 from AEmotionStudio/palette-tooltip-clarification-16066511053936262454
UX: Clarify resize_method dependency in image node tooltips
2026-01-20 18:18:21 -08:00
Æmotion Studio 7382295a76 Merge pull request #38 from AEmotionStudio/bolt-video-batch-processing-2145519241141552514
⚡ Bolt: Optimize video processing with batched tensor conversion
2026-01-20 18:17:56 -08:00
Æmotion Studio c4ef38cff3 Merge pull request #39 from AEmotionStudio/sentinel-webhook-token-leak-fix-6649537465366460291
🛡️ Sentinel: Fix webhook token leakage in error logs
2026-01-20 18:17:10 -08:00
google-labs-jules[bot] c1b1e2497c Fix: Sanitize webhook tokens from error messages
- Added `sanitize_token_from_text` helper to `shared/discord/webhook_client.py`.
- Updated `DiscordWebhookClient._send_with_retry` to sanitize `response.text` before returning it in error details.
- Updated `nodes/image_node.py` and `nodes/video_node.py` to sanitize `response.text` before printing error messages.
- Added regression test `tests/test_webhook_security.py`.

This prevents sensitive Discord webhook tokens from being leaked in ComfyUI console logs when the Discord API returns an error (e.g. 400 Bad Request) that echoes the request URL.
2026-01-21 01:26:33 +00:00
google-labs-jules[bot] 7cf1b45545 ⚡ Optimize video processing with batched tensor conversion
- Implements `process_batched_images` generator in `nodes/video_node.py` to process video frames in batches (default 20), significantly reducing GPU-CPU synchronization overhead.
- Optimizes `tensor_to_numpy_uint8` in `shared/media/image_processing.py` to use in-place operations (`.clamp_()`), saving memory allocations for large tensors.
- Reduces performance bottlenecks in video encoding pipelines.
2026-01-21 01:23:18 +00:00
google-labs-jules[bot] 0c7c1d83be UX: Clarify resize_method dependency in image node tooltips
- Updated `resize_to_power_of_2` tooltip to mention it uses the selected `resize_method`.
- Updated `resize_method` tooltip to explicitly state it is only used when `resize_to_power_of_2` is enabled.
- Added UX learning to `.Jules/palette.md`.

This prevents user confusion regarding why the resize method selection might not seem to affect standard outputs.
2026-01-21 01:22:34 +00:00
Æmotion Studio f53010ceef Merge pull request #36 from AEmotionStudio/refactor/separation-of-concerns
Refactor/separation of concerns
2026-01-20 16:25:54 -08:00
AEmotionStudio 8206c475e5 fix: make connect() return bool to verify connection success in reconnect loop 2026-01-20 16:10:23 -08:00
AEmotionStudio f2e1779450 fix: use absolute imports for shared module in cogs 2026-01-20 15:49:04 -08:00
AEmotionStudio 8ffb72bb4d fix: capture reconnect attempts before connect() to fix log message 2026-01-20 15:32:43 -08:00
AEmotionStudio 6af9e26255 chore: add sensitive file patterns to .gitignore 2026-01-20 15:15:02 -08:00
AEmotionStudio e7fde9951a fix: resolve race condition between connect() and disconnect() 2026-01-20 15:09:59 -08:00
AEmotionStudioandClaude Opus 4.5 def123c242 chore: remove REFACTOR_PRD.md from version control
File is already in .gitignore but was being tracked.
Keep locally as project reference only.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 10:22:21 -08:00
AEmotionStudioandClaude Opus 4.5 436b773bd8 chore: implement phase 6 - final cleanup
- Remove unused imports from nodes (time, torch, requests, itertools)
- Move uuid import to top-level in bot/bot.py
- Add 4 new test files with 86 tests for shared utilities
- Update CHANGELOG.md with version 2.0.0 refactoring summary
- Update REFACTOR_PRD.md to mark Phase 5 complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 10:20:51 -08:00
AEmotionStudioandClaude Opus 4.5 b083702eb9 feat(bot): implement phase 5 - complete bot features
- Add WebSocket reconnection with exponential backoff (1s-60s, ±10% jitter)
- Add error delivery to notify users when jobs fail
- Create templates cog with /template save/load/list/delete commands
- Create history cog with /history (paginated) and /rerun commands
- Fix BotConfig import in bot.py
- Enable templates and history cogs in bot loader

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 10:11:53 -08:00
AEmotionStudioandClaude Opus 4.5 618b9ae4bb docs(prd): update PRD to reflect phases 1-4 completion
- Mark phases 1-4 as complete with commit references
- Add phase 4.1 for PR review bug fixes (5 issues)
- Update success metrics with actual line counts:
  - Image node: 986 → 836 (-15%)
  - Video node: 1562 → 1092 (-30%)
  - Total: 2548 → 1928 (-24%)
  - Utility modules: 6 → 17
- Update change log with all phase completions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 03:22:18 -08:00
Æmotion Studio 569f76f484 Merge pull request #35 from AEmotionStudio/refactor/separation-of-concerns
refactor(phase2): extract shared utilities and reduce node duplication
2026-01-20 03:20:29 -08:00
AEmotionStudioandClaude Opus 4.5 0d6ed9d9c5 fix(message_builder): add trailing newline to metadata section
The build_metadata_section function used "\n".join(metadata_lines)
which lacks a trailing newline. When dimensions were appended later,
they concatenated directly without proper spacing, producing malformed
output like "**Format:** PNG**Original Dimensions:** 1024x1024".

Added trailing newline so subsequent content appears on a new line.

Fixes issue identified in PR #35 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 03:07:13 -08:00
AEmotionStudioandClaude Opus 4.5 cc07d20f86 fix(image_node): prevent redundant CDN URL sends on 204 responses
The refactored code checked only `if save_cdn_urls:` instead of the
original `if save_cdn_urls and response.status_code == 200:`. While
extract_cdn_urls_from_response correctly returns empty for 204 responses,
accumulated URLs from prior iterations could still trigger the
`if batch_cdn_urls:` condition, causing duplicate sends.

Fixed in both individual image send and batch send sections.

Fixes issue identified in PR #35 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 02:54:58 -08:00
AEmotionStudioandClaude Opus 4.5 36c5d06cf8 fix(prompt_extractor): restore SDXL workflow prompt extraction support
The refactored prompt extractor only detected CLIPTextEncode nodes,
losing support for SDXL-specific nodes that was present in the original
code. This caused SDXL workflows using SDXLPromptEncoder or SDXLTextEncode
nodes to not have their prompts included in Discord messages.

Changes:
- Add PROMPT_NODE_TYPES list with CLIPTextEncode, SDXLPromptEncoder,
  and SDXLTextEncode
- Rename functions from clip-specific to generic prompt node naming
- Add fallback detection for custom text/encode/prompt nodes
- Update docstrings to reflect broader node type support

Fixes regression identified in PR #35 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 02:42:25 -08:00
AEmotionStudioandClaude Opus 4.5 b8aadd7faa fix(image_node): add section header when only dimensions are displayed
When add_dimensions or resize_to_power_of_2 was enabled but add_date,
add_time, and include_format_in_message were all disabled, dimensions
would be appended to the Discord message without the "Image Information:"
section header.

Now checks if dimensions will be added but no other metadata exists,
and adds the section header in that case.

Fixes issue identified in PR #35 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 02:27:42 -08:00
AEmotionStudioandClaude Opus 4.5 1e94a69e5f fix(image_node): correct else block indentation in batch Discord send
The else block for error handling was incorrectly associated with the
`if save_cdn_urls:` condition instead of the `if response.status_code
in [200, 204]:` check. This caused discord_send_success to always be
set to False after a successful batch send, regardless of the actual
outcome.

Fixes control flow bug identified in PR #35 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 02:13:16 -08:00
AEmotionStudioandClaude Opus 4.5 87c97e04a3 refactor(phase4): create BaseDiscordNode with shared utilities
- Create nodes/base_node.py with BaseDiscordNode class
- Provide common INPUT_TYPES generators (discord, cdn, filename)
- Extract shared methods:
  - sanitize_workflow_data()
  - build_filename_prefix()
  - get_dest_folder()
  - extract_workflow_from_metadata()
  - build_prompt_message()
  - send_discord_files()
  - send_cdn_urls_to_discord()
  - update_github_cdn()

The base class is ready for nodes to inherit from, enabling
gradual adoption of shared functionality without disrupting
existing node implementations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 23:41:05 -08:00
AEmotionStudioandClaude Opus 4.5 76da850b3d refactor(phase3): extract video encoding utilities to shared modules
- Create shared/media/format_utils.py with format detection and validation
- Create shared/media/video_encoder.py with FFmpegEncoder and PILEncoder classes
- Extract validate_video_for_discord to shared utility
- Extract ffmpeg detection to shared detect_ffmpeg() function
- Extract Discord video optimization to shared optimize_video_for_discord()
- Remove duplicate code from video_node.py (-109 lines)

Phase 3 summary:
- video_node.py: 1201 -> 1092 lines (9% reduction this phase)
- Total reduction from original: 1562 -> 1092 lines (30% reduction)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 23:38:58 -08:00
AEmotionStudioandClaude Opus 4.5 a208cd482b refactor(phase2): extract shared utilities and reduce node duplication
- Create shared/filename_utils.py for date/time/dimension filename building
- Create shared/path_utils.py for output directory handling
- Create shared/discord/message_builder.py for Discord message construction
- Create shared/discord/cdn_extractor.py for CDN URL extraction
- Refactor image_node.py to use shared utilities (-161 lines, 16.3%)
- Refactor video_node.py to use shared utilities (-361 lines, 23.1%)
- Fix setup_logging missing from logging_config.py
- Fix test imports to use new module paths (nodes.* instead of discord_*_node)
- Total reduction: 522 lines (20.5%), exceeding PRD target of ~200 lines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 23:33:10 -08:00
Æmotion Studio 9295546c17 Merge pull request #34 from AEmotionStudio/refactor/separation-of-concerns
Refactor/separation of concerns
2026-01-19 23:04:57 -08:00
AEmotionStudio 852840dcae refactor(core): restructure project into shared/ and nodes/ modules 2026-01-19 22:02:47 -08:00
AEmotionStudio 06d7b955f5 Merge branch 'main' of https://github.com/AEmotionStudio/ComfyUI-DiscordSend into refactor/separation-of-concerns 2026-01-19 21:26:44 -08:00
Æmotion Studio 64179a3170 Merge pull request #32 from AEmotionStudio/bolt-remove-redundant-sanitization-5640104545261640127
⚡ Bolt: Remove redundant sanitization in save_images
2026-01-19 19:57:10 -08:00
google-labs-jules[bot] 1a84f62ec1 ⚡ Bolt: Fix test input to include github_token
- Updated `tests/test_image_node_sanitization.py` to include `github_token` in test inputs.
- Verified test now correctly covers github token sanitization.
2026-01-20 03:05:28 +00:00
google-labs-jules[bot] d7b20fc717 ⚡ Bolt: Fix test to not swallow assertions
- Updated `tests/test_image_node_sanitization.py` to avoid bare `try...except` that swallowed `AssertionError`.
- Verified the test fails correctly when sanitization is broken.
2026-01-20 02:34:53 +00:00
Æmotion Studio 95e00c65bf Merge pull request #33 from AEmotionStudio/fix-discord-video-node-imports-11402248337429151758
Fix incorrect imports and dead code in discord_video_node.py
2026-01-19 18:33:32 -08:00
google-labs-jules[bot] 4d34e27463 I have fixed incorrect imports in discord_video_node.py.
I removed a try-except block that attempted to import non-existent variables (`ffmpeg_path`, `get_audio`, etc.) from `discordsend_utils`. These variables were not used in the codebase and were causing import errors or false positives in static analysis.

- Replaced the failing import block with explicit definitions for `ffmpeg_path`, `ENCODE_ARGS`, and `has_vhs_formats`.
- Imported `ProgressBar` from `comfy.utils` with a fallback for standalone usage.
- Removed unused variables `floatOrInt`, `imageOrLatent`, and `BIGMAX`.
- Verified that the removed variables and functions are dead code.
2026-01-20 02:00:56 +00:00
google-labs-jules[bot] 5c6f15469d ⚡ Bolt: Remove redundant metadata sanitization in save_images
- Removed redundant calls to `sanitize_json_for_export` in `discord_image_node.py` loop.
- Verified ~33ms performance gain per batch via benchmark.
- Added regression test `tests/test_image_node_sanitization.py`.
2026-01-20 01:45:03 +00:00
Æmotion Studio 9acae29f27 Merge pull request #30 from AEmotionStudio/fix/temp-file-leak-video-node-7583297146289477645
🛡️ Sentinel: [MEDIUM] Fix Resource Exhaustion via Unbounded Temporary Files
2026-01-19 17:33:53 -08:00
google-labs-jules[bot] 83f0059720 Fix temporary file leak in discord_video_node.py 2026-01-20 01:23:20 +00:00
Æmotion Studio 81010bbb4e Merge pull request #29 from AEmotionStudio/palette-tooltip-improvements-547592080699549748
🎨 Palette: Enhance configuration tooltips for better UX
2026-01-19 17:22:13 -08:00
google-labs-jules[bot] c4dcfd586d Improve tooltips for GitHub and Discord settings
- Update `filename_prefix` tooltip to clarify `%batch_num%` usage.
- Update `github_repo` tooltip with an example format.
- Update `github_token` tooltip with navigation instructions to find the token.
- Standardize `webhook_url` tooltip across image and video nodes.
- Add `.jules/palette.md` for UX learnings.
2026-01-20 01:14:51 +00:00
AEmotionStudioandClaude Opus 4.5 e3e95ab197 fix(bot): resolve 4 critical bugs preventing bot startup
Phase 0 of separation-of-concerns refactor:

- Fix BotConfig class name mismatch in bot/__main__.py
  (was importing 'Config' but class is 'BotConfig')
- Add missing 'import json' to bot/services/delivery.py
  (json.loads was called without import)
- Remove unused PermissionLevel import from bot/cogs/admin.py
- Fix config attribute path: config.comfyui.url (was config.comfyui_url)

Also adds REFACTOR_PRD.md to .gitignore for project planning docs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 17:07:29 -08:00
Æmotion Studio 7cc72606a5 Merge pull request #28 from AEmotionStudio/bolt-video-memory-optimization-3922534104789050158
⚡ Bolt: Zero-copy video frame writing
2026-01-18 19:16:33 -08:00
google-labs-jules[bot] 8be6270aef fix(video): ensure contiguous arrays for both audio and video paths
- Fix potential BufferError in video frame writing path by enforcing C-contiguity with np.ascontiguousarray
- Add regression tests for non-contiguous array writing to Popen.stdin
- Rename variables for clarity (images_bytes -> image_chunks)
- Ensure cross-platform compatibility in tests
2026-01-19 03:06:07 +00:00
google-labs-jules[bot] b944db244e fix(video): ensure contiguous array for audio subprocess and rename var
- Fix BufferError when passing non-contiguous transposed audio array to memoryview/subprocess by using np.ascontiguousarray
- Rename 'images_bytes' to 'image_chunks' to better reflect that it contains numpy arrays, not bytes objects
- Improve test portability by using sys.executable instead of 'cat'
2026-01-19 02:39:37 +00:00
google-labs-jules[bot] d99aa60623 ⚡ Optimize video frame writing to ffmpeg
Avoids unnecessary memory copying by passing numpy arrays/memoryviews directly to subprocess stdin instead of creating intermediate bytes objects. This reduces memory pressure and allocation overhead when processing high-resolution video frames.
2026-01-19 02:15:43 +00:00