Files
bradsec-ComfyUI_StringEssen…/.planning/codebase/STRUCTURE.md
T
2026-03-03 20:13:36 +10:00

8.3 KiB

Codebase Structure

Analysis Date: 2026-03-03

Directory Layout

ComfyUI_StringEssentials/
├── __init__.py                        # Node registry and exports
├── pyproject.toml                     # Project metadata and configuration
├── README.md                          # Documentation
├── LICENSE                            # License file
├── string_textbox_node.py             # String Textbox node
├── string_strip_node.py               # String Strip node
├── string_multi_replace_node.py       # String Multi Replace node
├── string_preview_node.py             # String Preview node
├── string_conditional_append_node.py  # String Conditional Append node
├── string_contains_any_node.py        # String Contains Any node
├── test_string_nodes.py               # Unit tests
├── .planning/                         # Planning and analysis docs (not committed)
│   └── codebase/                      # Architecture documentation
├── .pytest_cache/                     # Pytest cache (gitignored)
├── js/                                # Client-side assets (currently empty)
└── images/                            # Documentation images

Directory Purposes

Root Directory:

  • Purpose: Contains all Python node implementations and project config
  • Contains: Node classes, tests, project metadata
  • Key files: All *_node.py files, __init__.py, pyproject.toml, test_string_nodes.py

js/ Directory:

  • Purpose: Placeholder for client-side JavaScript/web assets
  • Contains: Currently empty, referenced in __init__.py WEB_DIRECTORY
  • Committed: Yes (directory exists, may have assets)

images/ Directory:

  • Purpose: Documentation images for README
  • Contains: PNG screenshots of node interfaces and example workflows
  • Committed: Yes

.planning/codebase/ Directory:

  • Purpose: Architecture and analysis documentation generated by GSD tools
  • Contains: ARCHITECTURE.md, STRUCTURE.md, CONVENTIONS.md, TESTING.md, etc.
  • Committed: No (git ignored)

.pytest_cache/ Directory:

  • Purpose: Pytest runtime cache
  • Contains: Test execution metadata
  • Committed: No (git ignored)

Key File Locations

Entry Points:

  • __init__.py: Module initialization - imports nodes and exports NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS, WEB_DIRECTORY

Node Implementations:

  • string_textbox_node.py: StringTextboxNode - simple text input passthrough (5 lines of logic)
  • string_strip_node.py: StringStripNode - removes specified strings with regex patterns
  • string_multi_replace_node.py: StringMultiReplaceNode - replaces text using delimiter-separated pairs
  • string_preview_node.py: StringPreviewNode - displays string output in ComfyUI UI
  • string_conditional_append_node.py: StringConditionalAppendNode - appends text only if not present
  • string_contains_any_node.py: StringContainsAnyNode - checks if any of multiple substrings exist

Configuration:

  • pyproject.toml: Project metadata including name, version (2.0.7), description, repository URL

Testing:

  • test_string_nodes.py: 62 unit tests covering all node functionalities

Documentation:

  • README.md: User-facing documentation with node descriptions and usage examples

Naming Conventions

Files:

  • Node files: string_<operation>_node.py format
    • Examples: string_strip_node.py, string_multi_replace_node.py
    • Pattern: snake_case with _node.py suffix

Classes:

  • Node classes: PascalCase with "Node" suffix
    • Examples: StringTextboxNode, StringStripNode, StringMultiReplaceNode
    • Pattern: Convert filename from snake_case to PascalCase, append "Node"

Methods:

  • Execution methods: verb_noun_v1 format (snake_case)
    • Examples: string_strip(), string_replace(), conditional_append(), contains_any(), pass_string(), preview_string()
    • Pattern: Descriptive snake_case names indicating operation

Variables:

  • Instance variables: snake_case with descriptive names
    • Examples: input_string, strings_to_remove, match_case, preserve_punctuation
    • Pattern: Clear names indicating type and purpose

Constants:

  • Node metadata: UPPERCASE
    • Examples: RETURN_TYPES, RETURN_NAMES, FUNCTION, CATEGORY, INPUT_TYPES, OUTPUT_NODE
    • Pattern: ComfyUI convention for node interface

Where to Add New Code

New String Operation Node:

  1. Create file: string_<operation>_node.py in root directory
  2. Class structure (follow pattern from existing nodes):
    • Define INPUT_TYPES() classmethod with parameter definitions
    • Define RETURN_TYPES tuple with output types
    • Define RETURN_NAMES tuple with output names
    • Set FUNCTION = "<method_name>"
    • Set CATEGORY = "utils/StringEssentials"
    • Implement execution method with logic
  3. Add to __init__.py:
    • Import the new class at top
    • Add entry to NODE_CLASS_MAPPINGS dict (key = class name as string)
    • Add entry to NODE_DISPLAY_NAME_MAPPINGS dict (key = class name, value = display name)
  4. Add tests to test_string_nodes.py:
    • Create test class or add methods to TestStringNodes
    • Test basic functionality, edge cases, parameter variations

Example node implementation pattern from string_strip_node.py:

import re

class StringStripNode:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "input_string": ("STRING", {...}),
                "strings_to_remove": ("STRING", {...}),
                "match_case": ("BOOLEAN", {...}),
                # ... more parameters
            }
        }

    RETURN_TYPES = ("STRING",)
    RETURN_NAMES = ("modified_string",)
    FUNCTION = "string_strip"
    CATEGORY = "utils/StringEssentials"

    def cleanup_text(self, text):
        # Helper method for text normalization
        pass

    def string_strip(self, input_string, strings_to_remove, ...):
        # Parse input (splitlines, strip, filter empty)
        # Compile regex patterns
        # Apply patterns
        # Cleanup if needed
        return (result,)

Utilities/Helpers:

  • Shared helper methods: Add to individual node class if only used there
  • Common patterns: Currently duplicated in cleanup_text() across nodes (consider extraction if adding more nodes)
  • Location: Keep at root level - no separate utils directory used

Tests:

  • Add test methods to TestStringNodes class in test_string_nodes.py
  • Follow naming: test_<node>_<scenario> (e.g., test_strip_basic_functionality)
  • Setup: Use self.setUp() to instantiate node classes
  • Pattern: Call node method directly with test parameters, assert expected results

Special Directories

js/ Directory:

  • Purpose: ComfyUI web assets (referenced in WEB_DIRECTORY in __init__.py)
  • Generated: No
  • Committed: Yes (directory exists, may be empty or contain future web assets)
  • Note: Currently unused but available for client-side node customization

images/ Directory:

  • Purpose: Screenshots and diagrams for documentation
  • Generated: No (manually created/updated)
  • Committed: Yes
  • Files: PNG images referenced in README.md

.planning/codebase/ Directory:

  • Purpose: GSD (Get Shit Done) architecture analysis documents
  • Generated: Yes (by GSD tools)
  • Committed: No (git ignored)
  • Contains: ARCHITECTURE.md, STRUCTURE.md, CONVENTIONS.md, TESTING.md, CONCERNS.md

.pytest_cache/ Directory:

  • Purpose: Pytest internal cache for test discovery and execution
  • Generated: Yes (auto-created by pytest)
  • Committed: No (git ignored)

File Organization Rationale

Flat root structure for nodes: Each node is a separate file at root level

  • Rationale: Simple discovery by ComfyUI, clear 1:1 mapping between file and node class
  • Alternative avoided: Subdirectory organization (would complicate imports in __init__.py)

Single test file: All tests in test_string_nodes.py

  • Rationale: Small codebase, all nodes similar in nature, easy to run all tests together
  • Scalability: If adding more nodes, consider splitting tests by node when >100 test methods

Shared patterns duplicated: cleanup_text() method exists in both string_strip_node.py and string_multi_replace_node.py

  • Current state: Intentionally duplicated to keep each node self-contained
  • Future improvement: Extract to shared module if >3 nodes need it

Structure analysis: 2026-03-03