refactor(workflow): convert all plugins to class/struct + factory pattern

- Python: class extending NodeExecutor + factory.py (80+ plugins)
- TypeScript: class implements NodeExecutor + factory.ts (7 groups, 116 classes)
- Go: struct with methods + factory.go (36 plugins)
- Rust: struct impl NodeExecutor trait + factory.rs (54 plugins)
- Mojo: struct + factory.mojo (11 plugins)

All package.json files now include:
- files array listing source files
- metadata.class/struct field
- metadata.entrypoint field

This enables a unified plugin loading system across all languages
with no import side effects (Spring-style DI pattern).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-22 14:53:04 +00:00
parent 2562c2f55b
commit 7ce8b4ae8a
653 changed files with 13243 additions and 3034 deletions

View File

@@ -0,0 +1,7 @@
"""Factory for ListConcat plugin."""
from .list_concat import ListConcat
def create():
return ListConcat()

View File

@@ -1,11 +1,20 @@
"""Workflow plugin: concatenate lists."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ListConcat(NodeExecutor):
"""Concatenate multiple lists."""
lists = inputs.get("lists", [])
result = []
for lst in lists:
if isinstance(lst, list):
result.extend(lst)
return {"result": result}
node_type = "list.concat"
category = "list"
description = "Concatenate multiple lists"
def execute(self, inputs, runtime=None):
array = inputs.get("array", inputs.get("list", []))
lists = inputs.get("lists", inputs.get("arrays", [array]))
result = []
for lst in lists:
if isinstance(lst, list):
result.extend(lst)
return {"result": result}

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/list_concat",
"version": "1.0.0",
"description": "list_concat plugin",
"description": "Concatenate multiple lists",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_concat.py",
"files": ["list_concat.py", "factory.py"],
"metadata": {
"plugin_type": "list.concat",
"category": "list"
"category": "list",
"class": "ListConcat",
"entrypoint": "execute"
}
}

View File

@@ -0,0 +1,7 @@
"""Factory for ListEvery plugin."""
from .list_every import ListEvery
def create():
return ListEvery()

View File

@@ -1,18 +1,26 @@
"""Workflow plugin: check if all items match condition."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ListEvery(NodeExecutor):
"""Check if all items match condition."""
items = inputs.get("items", [])
key = inputs.get("key")
value = inputs.get("value")
if not items:
return {"result": True}
node_type = "list.every"
category = "list"
description = "Check if all items match condition"
if key is not None and value is not None:
result = all(isinstance(item, dict) and item.get(key) == value for item in items)
else:
result = all(items)
def execute(self, inputs, runtime=None):
items = inputs.get("items", inputs.get("array", []))
key = inputs.get("key")
value = inputs.get("value")
return {"result": result}
if not items:
return {"result": True}
if key is not None and value is not None:
result = all(isinstance(item, dict) and item.get(key) == value for item in items)
else:
result = all(items)
return {"result": result}

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/list_every",
"version": "1.0.0",
"description": "list_every plugin",
"description": "Check if all items match condition",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_every.py",
"files": ["list_every.py", "factory.py"],
"metadata": {
"plugin_type": "list.every",
"category": "list"
"category": "list",
"class": "ListEvery",
"entrypoint": "execute"
}
}

View File

@@ -0,0 +1,7 @@
"""Factory for ListFind plugin."""
from .list_find import ListFind
def create():
return ListFind()

View File

@@ -1,14 +1,22 @@
"""Workflow plugin: find item in list."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ListFind(NodeExecutor):
"""Find first item matching condition."""
items = inputs.get("items", [])
key = inputs.get("key")
value = inputs.get("value")
for item in items:
if isinstance(item, dict) and item.get(key) == value:
return {"result": item, "found": True}
node_type = "list.find"
category = "list"
description = "Find first item matching condition"
return {"result": None, "found": False}
def execute(self, inputs, runtime=None):
items = inputs.get("items", inputs.get("array", []))
key = inputs.get("key")
value = inputs.get("value")
for item in items:
if isinstance(item, dict) and item.get(key) == value:
return {"result": item, "found": True}
return {"result": None, "found": False}

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/list_find",
"version": "1.0.0",
"description": "list_find plugin",
"description": "Find first item matching condition",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_find.py",
"files": ["list_find.py", "factory.py"],
"metadata": {
"plugin_type": "list.find",
"category": "list"
"category": "list",
"class": "ListFind",
"entrypoint": "execute"
}
}

View File

@@ -0,0 +1,7 @@
"""Factory for ListLength plugin."""
from .list_length import ListLength
def create():
return ListLength()

View File

@@ -1,7 +1,15 @@
"""Workflow plugin: get list length."""
from ...base import NodeExecutor
def run(_runtime, inputs):
"""Get length of a list or string."""
items = inputs.get("items", [])
return {"result": len(items) if items is not None else 0}
class ListLength(NodeExecutor):
"""Get list length."""
node_type = "list.length"
category = "list"
description = "Get list length"
def execute(self, inputs, runtime=None):
array = inputs.get("array", inputs.get("list", []))
return {"result": len(array) if array is not None else 0}

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/list_length",
"version": "1.0.0",
"description": "list_length plugin",
"description": "Get length of list",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_length.py",
"files": ["list_length.py", "factory.py"],
"metadata": {
"plugin_type": "list.length",
"category": "list"
"category": "list",
"class": "ListLength",
"entrypoint": "execute"
}
}

View File

@@ -0,0 +1,7 @@
"""Factory for ListSlice plugin."""
from .list_slice import ListSlice
def create():
return ListSlice()

View File

@@ -1,15 +1,19 @@
"""Workflow plugin: slice a list."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ListSlice(NodeExecutor):
"""Extract slice from list."""
items = inputs.get("items", [])
start = inputs.get("start", 0)
end = inputs.get("end")
if end is None:
result = items[start:]
else:
result = items[start:end]
node_type = "list.slice"
category = "list"
description = "Extract slice from list"
return {"result": result}
def execute(self, inputs, runtime=None):
array = inputs.get("array", inputs.get("items", inputs.get("list", [])))
start = inputs.get("start", 0)
end = inputs.get("end")
result = array[start:end] if end is not None else array[start:]
return {"result": result}

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/list_slice",
"version": "1.0.0",
"description": "list_slice plugin",
"description": "Extract slice from list",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_slice.py",
"files": ["list_slice.py", "factory.py"],
"metadata": {
"plugin_type": "list.slice",
"category": "list"
"category": "list",
"class": "ListSlice",
"entrypoint": "execute"
}
}

View File

@@ -0,0 +1,7 @@
"""Factory for ListSome plugin."""
from .list_some import ListSome
def create():
return ListSome()

View File

@@ -1,15 +1,23 @@
"""Workflow plugin: check if some items match condition."""
from ...base import NodeExecutor
def run(_runtime, inputs):
"""Check if at least one item matches condition."""
items = inputs.get("items", [])
key = inputs.get("key")
value = inputs.get("value")
if key is not None and value is not None:
result = any(isinstance(item, dict) and item.get(key) == value for item in items)
else:
result = any(items)
class ListSome(NodeExecutor):
"""Check if some items match condition."""
return {"result": result}
node_type = "list.some"
category = "list"
description = "Check if some items match condition"
def execute(self, inputs, runtime=None):
items = inputs.get("items", inputs.get("array", []))
key = inputs.get("key")
value = inputs.get("value")
if key is not None and value is not None:
result = any(isinstance(item, dict) and item.get(key) == value for item in items)
else:
result = any(items)
return {"result": result}

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/list_some",
"version": "1.0.0",
"description": "list_some plugin",
"description": "Check if some items match condition",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_some.py",
"files": ["list_some.py", "factory.py"],
"metadata": {
"plugin_type": "list.some",
"category": "list"
"category": "list",
"class": "ListSome",
"entrypoint": "execute"
}
}

View File

@@ -0,0 +1,7 @@
"""Factory for ListSort plugin."""
from .list_sort import ListSort
def create():
return ListSort()

View File

@@ -1,17 +1,29 @@
"""Workflow plugin: sort a list."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ListSort(NodeExecutor):
"""Sort list by key or naturally."""
items = inputs.get("items", [])
key = inputs.get("key")
reverse = inputs.get("reverse", False)
try:
if key:
result = sorted(items, key=lambda x: x.get(key) if isinstance(x, dict) else x, reverse=reverse)
else:
result = sorted(items, reverse=reverse)
return {"result": result}
except (TypeError, AttributeError):
return {"result": items, "error": "Cannot sort items"}
node_type = "list.sort"
category = "list"
description = "Sort list by key or naturally"
def execute(self, inputs, runtime=None):
items = inputs.get("items", inputs.get("array", []))
key = inputs.get("key")
reverse = inputs.get("reverse", inputs.get("order") == "desc")
try:
if key:
result = sorted(
items,
key=lambda x: x.get(key) if isinstance(x, dict) else x,
reverse=reverse,
)
else:
result = sorted(items, reverse=reverse)
return {"result": result}
except (TypeError, AttributeError):
return {"result": items, "error": "Cannot sort items"}

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/list_sort",
"version": "1.0.0",
"description": "list_sort plugin",
"description": "Sort list by key or naturally",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_sort.py",
"files": ["list_sort.py", "factory.py"],
"metadata": {
"plugin_type": "list.sort",
"category": "list"
"category": "list",
"class": "ListSort",
"entrypoint": "execute"
}
}