208 lines
8.3 KiB
Markdown
208 lines
8.3 KiB
Markdown
# 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`:**
|
|
```python
|
|
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*
|